diff options
Diffstat (limited to 'src/arch/x86/memhelpers.hh')
-rw-r--r-- | src/arch/x86/memhelpers.hh | 104 |
1 files changed, 100 insertions, 4 deletions
diff --git a/src/arch/x86/memhelpers.hh b/src/arch/x86/memhelpers.hh index 705457d67..b13207ec4 100644 --- a/src/arch/x86/memhelpers.hh +++ b/src/arch/x86/memhelpers.hh @@ -1,5 +1,6 @@ /* * Copyright (c) 2011 Google + * Copyright (c) 2015 Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,6 +32,8 @@ #ifndef __ARCH_X86_MEMHELPERS_HH__ #define __ARCH_X86_MEMHELPERS_HH__ +#include <array> + #include "base/types.hh" #include "sim/byteswap.hh" #include "sim/insttracer.hh" @@ -47,10 +50,10 @@ initiateMemRead(XC *xc, Trace::InstRecord *traceData, Addr addr, return xc->initiateMemRead(addr, dataSize, flags); } -static inline uint64_t -getMem(PacketPtr pkt, unsigned dataSize, Trace::InstRecord *traceData) +static void +getMem(PacketPtr pkt, uint64_t &mem, unsigned dataSize, + Trace::InstRecord *traceData) { - uint64_t mem; switch (dataSize) { case 1: mem = pkt->get<uint8_t>(); @@ -69,9 +72,31 @@ getMem(PacketPtr pkt, unsigned dataSize, Trace::InstRecord *traceData) } if (traceData) traceData->setData(mem); - return mem; } + +template <size_t N> +void +getMem(PacketPtr pkt, std::array<uint64_t, N> &mem, unsigned dataSize, + Trace::InstRecord *traceData) +{ + assert(dataSize >= 8); + assert((dataSize % 8) == 0); + + int num_words = dataSize / 8; + assert(num_words <= N); + + auto pkt_data = pkt->getConstPtr<const uint64_t>(); + for (int i = 0; i < num_words; ++i) + mem[i] = gtoh(pkt_data[i]); + + // traceData record only has space for 64 bits, so we just record + // the first qword + if (traceData) + traceData->setData(mem[0]); +} + + template <class XC> Fault readMemAtomic(XC *xc, Trace::InstRecord *traceData, Addr addr, uint64_t &mem, @@ -90,6 +115,30 @@ readMemAtomic(XC *xc, Trace::InstRecord *traceData, Addr addr, uint64_t &mem, return fault; } +template <class XC, size_t N> +Fault +readMemAtomic(XC *xc, Trace::InstRecord *traceData, Addr addr, + std::array<uint64_t, N> &mem, unsigned dataSize, + unsigned flags) +{ + assert(dataSize >= 8); + assert((dataSize % 8) == 0); + + Fault fault = xc->readMem(addr, (uint8_t *)&mem, dataSize, flags); + + if (fault == NoFault) { + int num_words = dataSize / 8; + assert(num_words <= N); + + for (int i = 0; i < num_words; ++i) + mem[i] = gtoh(mem[i]); + + if (traceData) + traceData->setData(mem[0]); + } + return fault; +} + template <class XC> Fault writeMemTiming(XC *xc, Trace::InstRecord *traceData, uint64_t mem, @@ -102,6 +151,28 @@ writeMemTiming(XC *xc, Trace::InstRecord *traceData, uint64_t mem, return xc->writeMem((uint8_t *)&mem, dataSize, addr, flags, res); } +template <class XC, size_t N> +Fault +writeMemTiming(XC *xc, Trace::InstRecord *traceData, + std::array<uint64_t, N> &mem, unsigned dataSize, + Addr addr, unsigned flags, uint64_t *res) +{ + assert(dataSize >= 8); + assert((dataSize % 8) == 0); + + if (traceData) { + traceData->setData(mem[0]); + } + + int num_words = dataSize / 8; + assert(num_words <= N); + + for (int i = 0; i < num_words; ++i) + mem[i] = htog(mem[i]); + + return xc->writeMem((uint8_t *)&mem, dataSize, addr, flags, res); +} + template <class XC> Fault writeMemAtomic(XC *xc, Trace::InstRecord *traceData, uint64_t mem, @@ -119,6 +190,31 @@ writeMemAtomic(XC *xc, Trace::InstRecord *traceData, uint64_t mem, return fault; } +template <class XC, size_t N> +Fault +writeMemAtomic(XC *xc, Trace::InstRecord *traceData, + std::array<uint64_t, N> &mem, unsigned dataSize, + Addr addr, unsigned flags, uint64_t *res) +{ + if (traceData) { + traceData->setData(mem[0]); + } + + int num_words = dataSize / 8; + assert(num_words <= N); + + for (int i = 0; i < num_words; ++i) + mem[i] = htog(mem[i]); + + Fault fault = xc->writeMem((uint8_t *)&mem, dataSize, addr, flags, res); + + if (fault == NoFault && res != NULL) { + *res = gtoh(*res); + } + + return fault; +} + } #endif |