diff options
Diffstat (limited to 'src/arch')
-rwxr-xr-x | src/arch/isa_parser.py | 11 | ||||
-rw-r--r-- | src/arch/x86/isa/includes.isa | 1 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/ldstop.isa | 2 | ||||
-rw-r--r-- | src/arch/x86/isa/operands.isa | 2 | ||||
-rw-r--r-- | src/arch/x86/memhelpers.hh | 104 |
5 files changed, 112 insertions, 8 deletions
diff --git a/src/arch/isa_parser.py b/src/arch/isa_parser.py index cbc8651d1..749eaf88d 100755 --- a/src/arch/isa_parser.py +++ b/src/arch/isa_parser.py @@ -1053,9 +1053,14 @@ stringRE = re.compile(r'"([^"\\]|\\.)*"') commentRE = re.compile(r'(^)?[^\S\n]*/(?:\*(.*?)\*/[^\S\n]*|/[^\n]*)($)?', re.DOTALL | re.MULTILINE) -# Regular expression object to match assignment statements -# (used in findOperands()) -assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE) +# Regular expression object to match assignment statements (used in +# findOperands()). If the code immediately following the first +# appearance of the operand matches this regex, then the operand +# appears to be on the LHS of an assignment, and is thus a +# destination. basically we're looking for an '=' that's not '=='. +# The heinous tangle before that handles the case where the operand +# has an array subscript. +assignRE = re.compile(r'(\[[^\]]+\])?\s*=(?!=)', re.MULTILINE) def makeFlagConstructor(flag_list): if len(flag_list) == 0: diff --git a/src/arch/x86/isa/includes.isa b/src/arch/x86/isa/includes.isa index 43565fda5..0d0c0de3e 100644 --- a/src/arch/x86/isa/includes.isa +++ b/src/arch/x86/isa/includes.isa @@ -49,6 +49,7 @@ let {{ }}; output header {{ +#include <array> #include <cstring> #include <iostream> #include <sstream> diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index fa8bc6f2b..b35954439 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -143,7 +143,7 @@ def template MicroLoadCompleteAcc {{ %(op_decl)s; %(op_rd)s; - Mem = getMem(pkt, dataSize, traceData); + getMem(pkt, Mem, dataSize, traceData); %(code)s; diff --git a/src/arch/x86/isa/operands.isa b/src/arch/x86/isa/operands.isa index 59adada13..baa8552e0 100644 --- a/src/arch/x86/isa/operands.isa +++ b/src/arch/x86/isa/operands.isa @@ -1,4 +1,5 @@ // Copyright (c) 2007-2008 The Hewlett-Packard Development Company +// Copyright (c) 2015 Advanced Micro Devices, Inc. // All rights reserved. // // The license below extends only to copyright in the software and shall @@ -49,6 +50,7 @@ def operand_types {{ 'udw' : 'uint32_t', 'sqw' : 'int64_t', 'uqw' : 'uint64_t', + 'u2qw' : 'std::array<uint64_t, 2>', 'sf' : 'float', 'df' : 'double', }}; 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 |