summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/arch/isa_parser.py11
-rw-r--r--src/arch/x86/isa/includes.isa1
-rw-r--r--src/arch/x86/isa/microops/ldstop.isa2
-rw-r--r--src/arch/x86/isa/operands.isa2
-rw-r--r--src/arch/x86/memhelpers.hh104
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