ISA: Use readBytes/writeBytes for all instruction level memory operations.
This commit is contained in:
parent
d42e471baa
commit
aade13769f
16 changed files with 297 additions and 135 deletions
|
@ -73,6 +73,7 @@ output exec {{
|
|||
|
||||
#include "arch/alpha/registers.hh"
|
||||
#include "arch/alpha/regredir.hh"
|
||||
#include "arch/generic/memhelpers.hh"
|
||||
#include "base/cp_annotate.hh"
|
||||
#include "base/fenv.hh"
|
||||
#include "config/ss_compatible_fp.hh"
|
||||
|
|
|
@ -197,7 +197,7 @@ def template LoadExecute {{
|
|||
%(ea_code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
||||
fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
|
||||
%(memacc_code)s;
|
||||
}
|
||||
|
||||
|
@ -223,7 +223,7 @@ def template LoadInitiateAcc {{
|
|||
%(ea_code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
|
||||
fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
|
||||
}
|
||||
|
||||
return fault;
|
||||
|
@ -241,7 +241,7 @@ def template LoadCompleteAcc {{
|
|||
%(fp_enable_check)s;
|
||||
%(op_decl)s;
|
||||
|
||||
Mem = pkt->get<typeof(Mem)>();
|
||||
getMem(pkt, Mem, traceData);
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(memacc_code)s;
|
||||
|
@ -273,8 +273,8 @@ def template StoreExecute {{
|
|||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
fault = writeMemAtomic(xc, traceData, Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
|
@ -307,8 +307,8 @@ def template StoreCondExecute {{
|
|||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, &write_result);
|
||||
fault = writeMemAtomic(xc, traceData, Mem, EA,
|
||||
memAccessFlags, &write_result);
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
|
@ -340,8 +340,8 @@ def template StoreInitiateAcc {{
|
|||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
fault = writeMemTiming(xc, traceData, Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
}
|
||||
|
||||
return fault;
|
||||
|
|
|
@ -80,6 +80,7 @@ output exec {{
|
|||
#include "arch/arm/faults.hh"
|
||||
#include "arch/arm/isa_traits.hh"
|
||||
#include "arch/arm/utility.hh"
|
||||
#include "arch/generic/memhelpers.hh"
|
||||
#include "base/condcodes.hh"
|
||||
#include "sim/pseudo_inst.hh"
|
||||
#if defined(linux)
|
||||
|
|
|
@ -87,8 +87,8 @@ def template SwapExecute {{
|
|||
%(preacc_code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem,
|
||||
EA, memAccessFlags, &memData);
|
||||
fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
|
||||
&memData);
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
|
@ -123,8 +123,8 @@ def template SwapInitiateAcc {{
|
|||
%(preacc_code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, &memData);
|
||||
fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
|
||||
&memData);
|
||||
}
|
||||
} else {
|
||||
xc->setPredicate(false);
|
||||
|
@ -147,7 +147,8 @@ def template SwapCompleteAcc {{
|
|||
if (%(predicate_test)s)
|
||||
{
|
||||
// ARM instructions will not have a pkt if the predicate is false
|
||||
uint64_t memData = pkt->get<typeof(Mem)>();
|
||||
getMem(pkt, Mem, traceData);
|
||||
uint64_t memData = Mem;
|
||||
|
||||
%(postacc_code)s;
|
||||
|
||||
|
@ -174,7 +175,7 @@ def template LoadExecute {{
|
|||
if (%(predicate_test)s)
|
||||
{
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
||||
fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
|
||||
%(memacc_code)s;
|
||||
}
|
||||
|
||||
|
@ -241,8 +242,8 @@ def template StoreExecute {{
|
|||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
fault = writeMemAtomic(xc, traceData, Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
|
@ -314,8 +315,8 @@ def template StoreExExecute {{
|
|||
uint64_t writeResult;
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, &writeResult);
|
||||
fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
|
||||
&writeResult);
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
|
@ -351,8 +352,8 @@ def template StoreExInitiateAcc {{
|
|||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
|
||||
NULL);
|
||||
}
|
||||
} else {
|
||||
xc->setPredicate(false);
|
||||
|
@ -380,8 +381,8 @@ def template StoreInitiateAcc {{
|
|||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
|
||||
NULL);
|
||||
}
|
||||
} else {
|
||||
xc->setPredicate(false);
|
||||
|
@ -437,7 +438,7 @@ def template LoadInitiateAcc {{
|
|||
if (%(predicate_test)s)
|
||||
{
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
|
||||
fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
|
||||
}
|
||||
} else {
|
||||
xc->setPredicate(false);
|
||||
|
@ -489,7 +490,7 @@ def template LoadCompleteAcc {{
|
|||
if (%(predicate_test)s)
|
||||
{
|
||||
// ARM instructions will not have a pkt if the predicate is false
|
||||
Mem = pkt->get<typeof(Mem)>();
|
||||
getMem(pkt, Mem, traceData);
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(memacc_code)s;
|
||||
|
|
100
src/arch/generic/memhelpers.hh
Normal file
100
src/arch/generic/memhelpers.hh
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Google
|
||||
* 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.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_GENERIC_MEMHELPERS_HH__
|
||||
#define __ARCH_GENERIC_MEMHELPERS_HH__
|
||||
|
||||
#include "base/types.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
#include "sim/fault_fwd.hh"
|
||||
#include "sim/insttracer.hh"
|
||||
|
||||
/// Read from memory in timing mode.
|
||||
template <class XC, class MemT>
|
||||
Fault
|
||||
readMemTiming(XC *xc, Trace::InstRecord *traceData, Addr addr,
|
||||
MemT &mem, unsigned flags)
|
||||
{
|
||||
return xc->readBytes(addr, (uint8_t *)&mem, sizeof(MemT), flags);
|
||||
}
|
||||
|
||||
/// Extract the data returned from a timing mode read.
|
||||
template <class MemT>
|
||||
void
|
||||
getMem(PacketPtr pkt, MemT &mem, Trace::InstRecord *traceData)
|
||||
{
|
||||
mem = pkt->get<MemT>();
|
||||
if (traceData)
|
||||
traceData->setData(mem);
|
||||
}
|
||||
|
||||
/// Read from memory in atomic mode.
|
||||
template <class XC, class MemT>
|
||||
Fault
|
||||
readMemAtomic(XC *xc, Trace::InstRecord *traceData, Addr addr, MemT &mem,
|
||||
unsigned flags)
|
||||
{
|
||||
memset(&mem, 0, sizeof(mem));
|
||||
Fault fault = readMemTiming(xc, traceData, addr, mem, flags);
|
||||
if (fault == NoFault) {
|
||||
mem = gtoh(mem);
|
||||
if (traceData)
|
||||
traceData->setData(mem);
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
|
||||
/// Write to memory in timing mode.
|
||||
template <class XC, class MemT>
|
||||
Fault
|
||||
writeMemTiming(XC *xc, Trace::InstRecord *traceData, MemT mem, Addr addr,
|
||||
unsigned flags, uint64_t *res)
|
||||
{
|
||||
if (traceData) {
|
||||
traceData->setData(mem);
|
||||
}
|
||||
mem = TheISA::htog(mem);
|
||||
return xc->writeBytes((uint8_t *)&mem, sizeof(MemT), addr, flags, res);
|
||||
}
|
||||
|
||||
/// Write to memory in atomic mode.
|
||||
template <class XC, class MemT>
|
||||
Fault
|
||||
writeMemAtomic(XC *xc, Trace::InstRecord *traceData, const MemT &mem,
|
||||
Addr addr, unsigned flags, uint64_t *res)
|
||||
{
|
||||
Fault fault = writeMemTiming(xc, traceData, mem, addr, flags, res);
|
||||
if (fault == NoFault && res != NULL) {
|
||||
*res = gtoh((MemT)*res);
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -216,7 +216,7 @@ def template LoadExecute {{
|
|||
%(ea_code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
||||
fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
|
||||
%(memacc_code)s;
|
||||
}
|
||||
|
||||
|
@ -248,7 +248,7 @@ def template LoadInitiateAcc {{
|
|||
%(ea_code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
|
||||
fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
|
||||
}
|
||||
|
||||
return fault;
|
||||
|
@ -272,7 +272,7 @@ def template LoadCompleteAcc {{
|
|||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
|
||||
Mem = pkt->get<typeof(Mem)>();
|
||||
getMem(pkt, Mem, traceData);
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(memacc_code)s;
|
||||
|
@ -303,8 +303,8 @@ def template StoreExecute {{
|
|||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
|
@ -339,8 +339,8 @@ def template StoreFPExecute {{
|
|||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
|
@ -373,8 +373,8 @@ def template StoreCondExecute {{
|
|||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, &write_result);
|
||||
fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
|
||||
&write_result);
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
|
@ -406,8 +406,8 @@ def template StoreInitiateAcc {{
|
|||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return fault;
|
||||
|
@ -559,14 +559,15 @@ def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3;
|
|||
|
||||
def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
decl_code = 'uint32_t mem_word = 0;\n'
|
||||
decl_code += 'uint32_t unaligned_addr = Rs + disp;\n'
|
||||
decl_code += 'uint32_t byte_offset = unaligned_addr & 3;\n'
|
||||
decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
|
||||
decl_code += '\tbyte_offset ^= 3;\n'
|
||||
decl_code += '#endif\n'
|
||||
decl_code += 'fault = xc->read(EA, (uint32_t&)mem_word, memAccessFlags);\n'
|
||||
#decl_code += 'xc->readFunctional(EA,(uint32_t&)mem_word);'
|
||||
decl_code = '''
|
||||
uint32_t mem_word = 0;
|
||||
uint32_t unaligned_addr = Rs + disp;
|
||||
uint32_t byte_offset = unaligned_addr & 3;
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
byte_offset ^= 3;
|
||||
#endif
|
||||
fault = readMemAtomic(xc, traceData, EA, mem_word, memAccessFlags);
|
||||
'''
|
||||
memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
|
||||
|
||||
(header_output, decoder_output, decode_block, exec_output) = \
|
||||
|
|
|
@ -68,6 +68,7 @@ using namespace MipsISA;
|
|||
output exec {{
|
||||
#include <math.h>
|
||||
|
||||
#include "arch/generic/memhelpers.hh"
|
||||
#include "arch/mips/dsp.hh"
|
||||
#include "arch/mips/dt_constants.hh"
|
||||
#include "arch/mips/faults.hh"
|
||||
|
|
|
@ -84,7 +84,7 @@ def template LoadExecute {{
|
|||
%(ea_code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t&)Mem, memAccessFlags);
|
||||
fault = readMemAtomic(xc, traceData, EA, Mem, memAccessFlags);
|
||||
%(memacc_code)s;
|
||||
}
|
||||
|
||||
|
@ -109,7 +109,7 @@ def template LoadInitiateAcc {{
|
|||
%(ea_code)s;
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->read(EA, (uint%(mem_acc_size)d_t &)Mem, memAccessFlags);
|
||||
fault = readMemTiming(xc, traceData, EA, Mem, memAccessFlags);
|
||||
xc->setEA(EA);
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ def template LoadCompleteAcc {{
|
|||
|
||||
EA = xc->getEA();
|
||||
|
||||
val = pkt->get<uint%(mem_acc_size)d_t>();
|
||||
getMem(pkt, val, traceData);
|
||||
*((uint%(mem_acc_size)d_t*)&Mem) = val;
|
||||
|
||||
if (fault == NoFault) {
|
||||
|
@ -164,8 +164,8 @@ def template StoreExecute {{
|
|||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
fault = writeMemAtomic(xc, traceData, Mem, EA, memAccessFlags,
|
||||
NULL);
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
|
@ -193,8 +193,8 @@ def template StoreInitiateAcc {{
|
|||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
fault = xc->write((uint%(mem_acc_size)d_t&)Mem, EA,
|
||||
memAccessFlags, NULL);
|
||||
fault = writeMemTiming(xc, traceData, Mem, EA, memAccessFlags,
|
||||
NULL);
|
||||
}
|
||||
|
||||
// Need to write back any potential address register update
|
||||
|
|
|
@ -75,6 +75,7 @@ output exec {{
|
|||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
#include "arch/generic/memhelpers.hh"
|
||||
#include "arch/power/faults.hh"
|
||||
#include "arch/power/isa_traits.hh"
|
||||
#include "arch/power/utility.hh"
|
||||
|
|
|
@ -50,8 +50,8 @@ def template SwapExecute {{
|
|||
}
|
||||
if (storeCond && fault == NoFault) {
|
||||
%(EA_trunc)s
|
||||
fault = xc->write((uint%(mem_acc_size)s_t)Mem,
|
||||
EA, %(asi_val)s, &mem_data);
|
||||
fault = writeMemAtomic(xc, traceData, Mem, EA,
|
||||
%(asi_val)s, &mem_data);
|
||||
}
|
||||
if (fault == NoFault) {
|
||||
// Handle the swapping
|
||||
|
@ -87,8 +87,8 @@ def template SwapInitiateAcc {{
|
|||
}
|
||||
if (fault == NoFault) {
|
||||
%(EA_trunc)s
|
||||
fault = xc->write((uint%(mem_acc_size)s_t)Mem,
|
||||
EA, %(asi_val)s, &mem_data);
|
||||
fault = writeMemTiming(xc, traceData, Mem, EA, %(asi_val)s,
|
||||
&mem_data);
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
|
@ -103,7 +103,8 @@ def template SwapCompleteAcc {{
|
|||
Fault fault = NoFault;
|
||||
%(op_decl)s;
|
||||
|
||||
uint64_t mem_data = pkt->get<uint%(mem_acc_size)s_t>();
|
||||
getMem(pkt, Mem, traceData);
|
||||
uint64_t mem_data = Mem;
|
||||
|
||||
if (fault == NoFault) {
|
||||
// Handle the swapping
|
||||
|
|
|
@ -143,7 +143,7 @@ def template LoadExecute {{
|
|||
%(fault_check)s;
|
||||
if (fault == NoFault) {
|
||||
%(EA_trunc)s
|
||||
fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s);
|
||||
fault = readMemAtomic(xc, traceData, EA, Mem, %(asi_val)s);
|
||||
}
|
||||
if (fault == NoFault) {
|
||||
%(code)s;
|
||||
|
@ -171,7 +171,7 @@ def template LoadInitiateAcc {{
|
|||
%(fault_check)s;
|
||||
if (fault == NoFault) {
|
||||
%(EA_trunc)s
|
||||
fault = xc->read(EA, (%(mem_acc_type)s%(mem_acc_size)s_t&)Mem, %(asi_val)s);
|
||||
fault = readMemTiming(xc, traceData, EA, Mem, %(asi_val)s);
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ def template LoadCompleteAcc {{
|
|||
Fault fault = NoFault;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
Mem = pkt->get<typeof(Mem)>();
|
||||
getMem(pkt, Mem, traceData);
|
||||
%(code)s;
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
|
@ -214,8 +214,7 @@ def template StoreExecute {{
|
|||
}
|
||||
if (storeCond && fault == NoFault) {
|
||||
%(EA_trunc)s
|
||||
fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
|
||||
EA, %(asi_val)s, 0);
|
||||
fault = writeMemAtomic(xc, traceData, Mem, EA, %(asi_val)s, 0);
|
||||
}
|
||||
if (fault == NoFault) {
|
||||
// Write the resulting state to the execution context
|
||||
|
@ -245,8 +244,7 @@ def template StoreInitiateAcc {{
|
|||
}
|
||||
if (storeCond && fault == NoFault) {
|
||||
%(EA_trunc)s
|
||||
fault = xc->write((%(mem_acc_type)s%(mem_acc_size)s_t)Mem,
|
||||
EA, %(asi_val)s, 0);
|
||||
fault = writeMemTiming(xc, traceData, Mem, EA, %(asi_val)s, 0);
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ output exec {{
|
|||
#include <cmath>
|
||||
#include <limits>
|
||||
|
||||
#include "arch/generic/memhelpers.hh"
|
||||
#include "arch/sparc/asi.hh"
|
||||
#include "base/bigint.hh"
|
||||
#include "cpu/base.hh"
|
||||
|
|
|
@ -97,73 +97,6 @@ namespace X86ISA
|
|||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
|
||||
template<class Context, class MemType>
|
||||
Fault read(Context *xc, Addr EA, MemType & Mem, unsigned flags) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
switch(dataSize)
|
||||
{
|
||||
case 1:
|
||||
fault = xc->read(EA, (uint8_t&)Mem, flags);
|
||||
break;
|
||||
case 2:
|
||||
fault = xc->read(EA, (uint16_t&)Mem, flags);
|
||||
break;
|
||||
case 4:
|
||||
fault = xc->read(EA, (uint32_t&)Mem, flags);
|
||||
break;
|
||||
case 8:
|
||||
fault = xc->read(EA, (uint64_t&)Mem, flags);
|
||||
break;
|
||||
default:
|
||||
panic("Bad operand size %d for read at %#x.\n", dataSize, EA);
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
|
||||
template<class Context, class MemType>
|
||||
Fault write(Context *xc, MemType & Mem, Addr EA, unsigned flags) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
switch(dataSize)
|
||||
{
|
||||
case 1:
|
||||
fault = xc->write((uint8_t&)Mem, EA, flags, 0);
|
||||
break;
|
||||
case 2:
|
||||
fault = xc->write((uint16_t&)Mem, EA, flags, 0);
|
||||
break;
|
||||
case 4:
|
||||
fault = xc->write((uint32_t&)Mem, EA, flags, 0);
|
||||
break;
|
||||
case 8:
|
||||
fault = xc->write((uint64_t&)Mem, EA, flags, 0);
|
||||
break;
|
||||
default:
|
||||
panic("Bad operand size %d for write at %#x.\n", dataSize, EA);
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
get(PacketPtr pkt) const
|
||||
{
|
||||
switch(dataSize)
|
||||
{
|
||||
case 1:
|
||||
return pkt->get<uint8_t>();
|
||||
case 2:
|
||||
return pkt->get<uint16_t>();
|
||||
case 4:
|
||||
return pkt->get<uint32_t>();
|
||||
case 8:
|
||||
return pkt->get<uint64_t>();
|
||||
default:
|
||||
panic("Bad operand size %d for read at %#x.\n",
|
||||
dataSize, pkt->getAddr());
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ output exec {{
|
|||
#include "arch/x86/regs/misc.hh"
|
||||
#include "arch/x86/cpuid.hh"
|
||||
#include "arch/x86/faults.hh"
|
||||
#include "arch/x86/memhelpers.hh"
|
||||
#include "arch/x86/tlb.hh"
|
||||
#include "base/bigint.hh"
|
||||
#include "base/compiler.hh"
|
||||
|
|
|
@ -98,7 +98,7 @@ def template MicroLoadExecute {{
|
|||
%(ea_code)s;
|
||||
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||
|
||||
fault = read(xc, EA, Mem, memFlags);
|
||||
fault = readMemAtomic(xc, traceData, EA, Mem, dataSize, memFlags);
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(code)s;
|
||||
|
@ -127,7 +127,7 @@ def template MicroLoadInitiateAcc {{
|
|||
%(ea_code)s;
|
||||
DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
|
||||
|
||||
fault = read(xc, EA, Mem, memFlags);
|
||||
fault = readMemTiming(xc, traceData, EA, Mem, dataSize, memFlags);
|
||||
|
||||
return fault;
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ def template MicroLoadCompleteAcc {{
|
|||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
|
||||
Mem = get(pkt);
|
||||
Mem = getMem(pkt, dataSize, traceData);
|
||||
|
||||
%(code)s;
|
||||
|
||||
|
@ -174,7 +174,8 @@ def template MicroStoreExecute {{
|
|||
|
||||
if(fault == NoFault)
|
||||
{
|
||||
fault = write(xc, Mem, EA, memFlags);
|
||||
fault = writeMemAtomic(xc, traceData, Mem, dataSize, EA,
|
||||
memFlags, NULL);
|
||||
if(fault == NoFault)
|
||||
{
|
||||
%(op_wb)s;
|
||||
|
@ -201,7 +202,8 @@ def template MicroStoreInitiateAcc {{
|
|||
|
||||
if(fault == NoFault)
|
||||
{
|
||||
fault = write(xc, Mem, EA, memFlags);
|
||||
fault = writeMemTiming(xc, traceData, Mem, dataSize, EA,
|
||||
memFlags, NULL);
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
|
|
120
src/arch/x86/memhelpers.hh
Normal file
120
src/arch/x86/memhelpers.hh
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Google
|
||||
* 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.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_X86_MEMHELPERS_HH__
|
||||
#define __ARCH_X86_MEMHELPERS_HH__
|
||||
|
||||
#include "base/types.hh"
|
||||
#include "sim/byteswap.hh"
|
||||
#include "sim/fault_fwd.hh"
|
||||
#include "sim/insttracer.hh"
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
|
||||
template <class XC>
|
||||
Fault
|
||||
readMemTiming(XC *xc, Trace::InstRecord *traceData, Addr addr,
|
||||
uint64_t &mem, unsigned dataSize, unsigned flags)
|
||||
{
|
||||
return xc->readBytes(addr, (uint8_t *)&mem, dataSize, flags);
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
getMem(PacketPtr pkt, unsigned dataSize, Trace::InstRecord *traceData)
|
||||
{
|
||||
uint64_t mem;
|
||||
switch (dataSize) {
|
||||
case 1:
|
||||
mem = pkt->get<uint8_t>();
|
||||
break;
|
||||
case 2:
|
||||
mem = pkt->get<uint16_t>();
|
||||
break;
|
||||
case 4:
|
||||
mem = pkt->get<uint32_t>();
|
||||
break;
|
||||
case 8:
|
||||
mem = pkt->get<uint64_t>();
|
||||
break;
|
||||
default:
|
||||
panic("Unhandled size in getMem.\n");
|
||||
}
|
||||
if (traceData)
|
||||
traceData->setData(mem);
|
||||
return mem;
|
||||
}
|
||||
|
||||
template <class XC>
|
||||
Fault
|
||||
readMemAtomic(XC *xc, Trace::InstRecord *traceData, Addr addr, uint64_t &mem,
|
||||
unsigned dataSize, unsigned flags)
|
||||
{
|
||||
memset(&mem, 0, sizeof(mem));
|
||||
Fault fault = readMemTiming(xc, traceData, addr, mem, dataSize, flags);
|
||||
if (fault == NoFault) {
|
||||
// If LE to LE, this is a nop, if LE to BE, the actual data ends up
|
||||
// in the right place because the LSBs where at the low addresses on
|
||||
// access. This doesn't work for BE guests.
|
||||
mem = gtoh(mem);
|
||||
if (traceData)
|
||||
traceData->setData(mem);
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
|
||||
template <class XC>
|
||||
Fault
|
||||
writeMemTiming(XC *xc, Trace::InstRecord *traceData, uint64_t mem,
|
||||
unsigned dataSize, Addr addr, unsigned flags, uint64_t *res)
|
||||
{
|
||||
if (traceData) {
|
||||
traceData->setData(mem);
|
||||
}
|
||||
mem = TheISA::htog(mem);
|
||||
return xc->writeBytes((uint8_t *)&mem, dataSize, addr, flags, res);
|
||||
}
|
||||
|
||||
template <class XC>
|
||||
Fault
|
||||
writeMemAtomic(XC *xc, Trace::InstRecord *traceData, uint64_t mem,
|
||||
unsigned dataSize, Addr addr, unsigned flags, uint64_t *res)
|
||||
{
|
||||
Fault fault = writeMemTiming(xc, traceData, mem, dataSize, addr, flags,
|
||||
res);
|
||||
if (fault == NoFault && res != NULL) {
|
||||
*res = gtoh(*res);
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue