Gabe Black has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/27242 )
Change subject: util: Add support for multiple call types in the m5 utility.
......................................................................
util: Add support for multiple call types in the m5 utility.
Using mechanisms added in previous CLs, this change modifies the m5
utility so that it can use any of the back ends enabled and implemented
by each variant, defaulting to one particular implementation if not is
selected explicitly.
On x86, the default mechanism is the magic address. All other variants
default to the magic instruction since they don't have a well
established address to use or even in most cases an implementation to
use.
The ability to override the particular magic address the utility wants
to use (necessary on variants such as aarch64) will be added in a future
CL.
Change-Id: I5fc414740e30759e7dde719cddcc8d5d41f8cc74
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27242
Reviewed-by: Jason Lowe-Power <[email protected]>
Reviewed-by: Pouya Fotouhi <[email protected]>
Maintainer: Gabe Black <[email protected]>
Tested-by: kokoro <[email protected]>
---
M util/m5/SConstruct
M util/m5/src/SConscript
M util/m5/src/aarch64/SConsopts
M util/m5/src/aarch64/m5op.S
A util/m5/src/aarch64/m5op_addr.S
M util/m5/src/addr_call_type.c
M util/m5/src/arm/SConsopts
M util/m5/src/m5.c
M util/m5/src/semi_call_type.c
M util/m5/src/sparc/SConsopts
M util/m5/src/thumb/SConsopts
M util/m5/src/x86/SConsopts
M util/m5/src/x86/m5op.S
A util/m5/src/x86/m5op_addr.S
14 files changed, 251 insertions(+), 98 deletions(-)
Approvals:
Jason Lowe-Power: Looks good to me, approved
Pouya Fotouhi: Looks good to me, but someone else must approve
Gabe Black: Looks good to me, approved
kokoro: Regressions pass
diff --git a/util/m5/SConstruct b/util/m5/SConstruct
index 83d46aa..48073d2 100644
--- a/util/m5/SConstruct
+++ b/util/m5/SConstruct
@@ -23,6 +23,7 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+import copy
import os
main = Environment()
@@ -59,11 +60,34 @@
# Use soft links instead of hard links when setting up a build directory.
main.SetOption('duplicate', 'soft-copy')
+class CallType(object):
+ def __init__(self, name):
+ self.name = name
+ self.impl_file = None
+ self.enabled = False
+ self.default = False
+
+ def impl(self, impl, default=False):
+ self.impl_file = impl
+ self.enabled = True
+ self.default = default
+
+call_types = {
+ # Magic instruction.
+ 'inst': CallType('inst'),
+ # Magic address.
+ 'addr': CallType('addr'),
+ # Semihosting extension.
+ 'semi': CallType('semi'),
+}
+
for root, dirs, files in os.walk(abspath(src_dir)):
# Each SConsopts file describes a variant of the m5 utility.
if 'SConsopts' in files:
env = main.Clone()
+ env['CALL_TYPE'] = copy.deepcopy(call_types)
+
# The user may override variant settings by setting environment
# variables of the form ${VARIANT}.${OPTION}. For instance, to set
the
# CROSS_COMPILE prefix for variant foo to bar-, the user would set
an
diff --git a/util/m5/src/SConscript b/util/m5/src/SConscript
index 392ac9e..c2a3ede 100644
--- a/util/m5/src/SConscript
+++ b/util/m5/src/SConscript
@@ -29,30 +29,47 @@
# Raw source files.
m5_mmap = 'm5_mmap.c'
-m5op = '${VARIANT}/m5op.S'
m5 = 'm5.c'
jni = 'jni_gem5Op.c'
lua = 'lua_gem5Op.c'
+all_call_types = list(env['CALL_TYPE'].values())
+call_types = list([ ct for ct in all_call_types if ct.enabled ])
+m5ops = list([ '${VARIANT}/%s' % ct.impl_file for ct in call_types ])
+
+default_call_type = list([ ct for ct in call_types if ct.default ])
+assert len(default_call_type) == 1, \
+ 'There should be exactly one default call type for %s, found %d' %
\
+ (env['VARIANT'], len(default_call_type))
+default_call_type = default_call_type[0]
+
static_env = env.Clone()
static_env.Append(LINKFLAGS=[ '-no-pie', '-static' ])
+for ct in all_call_types:
+ static_env.Append(CFLAGS='-DENABLE_CT_%s=%d' %
+ (ct.name, 1 if ct.enabled else 0))
+ static_env.Append(CFLAGS='-DDEFAULT_CT_%s=%d' %
+ (ct.name, 1 if ct.default else 0))
+static_env.Append(CFLAGS='-DDEFAULT_CALL_TYPE=%s' % default_call_type.name)
+
#
# The m5 library for use in other C/C++ programs.
#
-libm5 = static_env.StaticLibrary('out/m5', [ m5op, m5_mmap ])
+libm5 = static_env.StaticLibrary('out/m5', [ m5_mmap ] + m5ops)
#
# The m5 stand alone command line utility.
#
-m5_bin = static_env.Program('out/m5', [ m5, m5_mmap, libm5 ])
+ct_support = list([ File('%s_call_type.c' % ct.name) for ct in call_types
])
+m5_bin = static_env.Program('out/m5', ct_support + [ m5, m5_mmap, libm5 ])
# The shared version of the m5 op call sights, used by mutliple targets
below.
shared_env = env.Clone()
shared_env.Append(ASFLAGS='-DM5OP_PIC')
-m5op_shared = shared_env.SharedObject(m5op)
+m5op_shared = shared_env.SharedObject(m5ops)
if env['HAVE_JAVA']:
#
@@ -71,7 +88,7 @@
OUT=Dir('out'), CWD=Dir('.'))
# Set include paths to the C headers from the JDK which scons found
for us.
java_env.Append(CPPPATH='${JAVAINCLUDES}')
- java_env.SharedLibrary('out/gem5OpJni', [ jni, m5op_shared ])
+ java_env.SharedLibrary('out/gem5OpJni', [ jni ] + m5op_shared)
if env['HAVE_LUA51']:
@@ -81,4 +98,5 @@
lua_env = shared_env.Clone()
# Extract the include paths needed for lua51 using pkg-config.
lua_env.ParseConfig('pkg-config --cflags lua51')
- lib = lua_env.SharedLibrary('out/gem5OpLua', [ lua, m5op_shared,
m5_mmap ])
+ lib = lua_env.SharedLibrary('out/gem5OpLua',
+ [ lua, m5_mmap ] + m5op_shared)
diff --git a/util/m5/src/aarch64/SConsopts b/util/m5/src/aarch64/SConsopts
index 12059f8..343247c 100644
--- a/util/m5/src/aarch64/SConsopts
+++ b/util/m5/src/aarch64/SConsopts
@@ -27,3 +27,6 @@
env['VARIANT'] = 'aarch64'
get_variant_opt('CROSS_COMPILE', 'aarch64-linux-gnu-')
+
+env['CALL_TYPE']['inst'].impl('m5op.S', default=True)
+env['CALL_TYPE']['addr'].impl('m5op_addr.S')
diff --git a/util/m5/src/aarch64/m5op.S b/util/m5/src/aarch64/m5op.S
index 1cc222a..6529dcf 100644
--- a/util/m5/src/aarch64/m5op.S
+++ b/util/m5/src/aarch64/m5op.S
@@ -40,33 +40,12 @@
#include <gem5/asm/generic/m5ops.h>
-#ifdef M5OP_ADDR
-.macro m5op_func, name, func
- .globl \name
- \name:
- // Load the value of m5_mem into x9...
-#if defined(M5OP_PIC)
- // using the global offset table.
- adrp x9, :got:m5_mem
- ldr x9, [ x9, #:got_lo12:m5_mem ]
- ldr x9, [ x9 ]
-#else
- // normally.
- adrp x9, m5_mem
- ldr x9, [ x9, #:lo12:m5_mem ]
-#endif
- movz x10, #(\func << 8)
- ldr x0, [ x9, x10 ]
- ret
-.endm
-#else
.macro m5op_func, name, func
.globl \name
\name:
.long 0xff000110 | (\func << 16)
ret
.endm
-#endif
.text
#define M5OP(name, func) m5op_func name, func;
diff --git a/util/m5/src/aarch64/m5op_addr.S
b/util/m5/src/aarch64/m5op_addr.S
new file mode 100644
index 0000000..0368754
--- /dev/null
+++ b/util/m5/src/aarch64/m5op_addr.S
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2010-2013, 2016-2017 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Copyright (c) 2003-2006 The Regents of The University of Michigan
+ * 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.
+ */
+
+#include <gem5/asm/generic/m5ops.h>
+
+.macro m5op_func, name, func
+ .globl \name
+ \name:
+ // Load the value of m5_mem into x9...
+#if defined(M5OP_PIC)
+ // using the global offset table.
+ adrp x9, :got:m5_mem
+ ldr x9, [ x9, #:got_lo12:m5_mem ]
+ ldr x9, [ x9 ]
+#else
+ // normally.
+ adrp x9, m5_mem
+ ldr x9, [ x9, #:lo12:m5_mem ]
+#endif
+ movz x10, #(\func << 8)
+ ldr x0, [ x9, x10 ]
+ ret
+.endm
+
+.text
+#define M5OP(name, func) m5op_func M5OP_MERGE_TOKENS(name, _addr), func;
+ M5OP_FOREACH
+#undef M5OP
diff --git a/util/m5/src/addr_call_type.c b/util/m5/src/addr_call_type.c
index d91d2ec..cb269dc 100644
--- a/util/m5/src/addr_call_type.c
+++ b/util/m5/src/addr_call_type.c
@@ -53,5 +53,6 @@
DispatchTable *
addr_call_type_init()
{
+ map_m5_mem();
return &addr_dispatch;
}
diff --git a/util/m5/src/arm/SConsopts b/util/m5/src/arm/SConsopts
index fb46668..e251758 100644
--- a/util/m5/src/arm/SConsopts
+++ b/util/m5/src/arm/SConsopts
@@ -28,3 +28,5 @@
env['VARIANT'] = 'arm'
get_variant_opt('CROSS_COMPILE', 'arm-linux-gnueabihf-')
env.Append(CFLAGS='-march=armv7-a')
+
+env['CALL_TYPE']['inst'].impl('m5op.S', default=True)
diff --git a/util/m5/src/m5.c b/util/m5/src/m5.c
index 9fe8221..cda6bf6 100644
--- a/util/m5/src/m5.c
+++ b/util/m5/src/m5.c
@@ -51,6 +51,7 @@
#include <gem5/asm/generic/m5ops.h>
#include <gem5/m5ops.h>
+#include "call_type.h"
#include "dispatch_table.h"
#include "m5_mmap.h"
@@ -58,12 +59,6 @@
char *command = "unspecified";
void usage();
-DispatchTable default_dispatch = {
-#define M5OP(name, func) .name = &name,
-M5OP_FOREACH
-#undef M5OP
-};
-
void
parse_int_args(int argc, char *argv[], uint64_t ints[], int len)
{
@@ -323,13 +318,29 @@
void
usage()
{
- int i;
-
- for (i = 0; i < numfuncs; ++i) {
- char *header = i ? "" : "usage:";
- fprintf(stderr, "%-6s %s %s %s\n",
- header, progname, mainfuncs[i].name, mainfuncs[i].usage);
- }
+ fprintf(stderr, "Usage: %s [call type] <command> [arguments]\n",
progname);
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Call types:\n");
+# if ENABLE_CT_addr
+ fprintf(stderr, " --addr%s\n", DEFAULT_CT_addr ? " (default)" : "");
+ fprintf(stderr, " Use the address based invocation method.\n");
+# if defined(M5OP_ADDR)
+ fprintf(stderr, " The address is %#"PRIx64".\n",
+ (uint64_t)M5OP_ADDR);
+# endif
+# endif
+# if ENABLE_CT_inst
+ fprintf(stderr, " --inst%s\n", DEFAULT_CT_inst ? " (default)" : "");
+ fprintf(stderr, " Use the instruction based invocation
method.\n");
+# endif
+# if ENABLE_CT_semi
+ fprintf(stderr, " --semi%s\n", DEFAULT_CT_semi ? " (default)" : "");
+ fprintf(stderr, " Use the semi-hosting based invocation
method.\n");
+# endif
+ fprintf(stderr, "\n");
+ fprintf(stderr, "Commands:\n");
+ for (int i = 0; i < numfuncs; ++i)
+ fprintf(stderr, " %s %s\n", mainfuncs[i].name,
mainfuncs[i].usage);
fprintf(stderr, "\n");
fprintf(stderr, "All times in nanoseconds!\n");
@@ -340,22 +351,44 @@
main(int argc, char *argv[])
{
progname = argv[0];
- if (argc < 2)
+
+ argv++;
+ argc--;
+
+ DispatchTable *dt = NULL;
+
+# if ENABLE_CT_inst
+ if (!dt && inst_call_type_detect(&argc, &argv)) {
+ dt = inst_call_type_init();
+ }
+# endif
+# if ENABLE_CT_addr
+ if (!dt && addr_call_type_detect(&argc, &argv)) {
+ dt = addr_call_type_init();
+ }
+# endif
+# if ENABLE_CT_semi
+ if (!dt && semi_call_type_detect(&argc, &argv)) {
+ dt = semi_call_type_init();
+ }
+# endif
+ if (!dt)
+ dt = default_call_type_init();
+
+ if (!argc)
usage(1);
- map_m5_mem();
+ command = argv[0];
- command = argv[1];
-
- argv += 2;
- argc -= 2;
+ argv++;
+ argc--;
int i;
for (i = 0; i < numfuncs; ++i) {
if (strcmp(command, mainfuncs[i].name) != 0)
continue;
- mainfuncs[i].func(&default_dispatch, argc, argv);
+ mainfuncs[i].func(dt, argc, argv);
exit(0);
}
diff --git a/util/m5/src/semi_call_type.c b/util/m5/src/semi_call_type.c
index 012d637..f3d5630 100644
--- a/util/m5/src/semi_call_type.c
+++ b/util/m5/src/semi_call_type.c
@@ -29,6 +29,10 @@
#include "semi_call_type.h"
+#define M5OP(name, func) __typeof__(name) M5OP_MERGE_TOKENS(name, _semi);
+M5OP_FOREACH
+#undef M5OP
+
static DispatchTable semi_dispatch = {
#define M5OP(name, func) .name = &M5OP_MERGE_TOKENS(name, _semi),
M5OP_FOREACH
diff --git a/util/m5/src/sparc/SConsopts b/util/m5/src/sparc/SConsopts
index 89b2db9..aa6f4be 100644
--- a/util/m5/src/sparc/SConsopts
+++ b/util/m5/src/sparc/SConsopts
@@ -28,3 +28,5 @@
env['VARIANT'] = 'sparc'
get_variant_opt('CROSS_COMPILE', 'sparc64-linux-gnu-')
env.Append(CFLAGS='-m64')
+
+env['CALL_TYPE']['inst'].impl('m5op.S', default=True)
diff --git a/util/m5/src/thumb/SConsopts b/util/m5/src/thumb/SConsopts
index ffa6c37..e0b0245 100644
--- a/util/m5/src/thumb/SConsopts
+++ b/util/m5/src/thumb/SConsopts
@@ -28,3 +28,5 @@
env['VARIANT'] = 'thumb'
get_variant_opt('CROSS_COMPILE', 'arm-linux-gnueabihf-')
env.Append(CFLAGS=[ '-mthumb', '-march=armv7' ])
+
+env['CALL_TYPE']['inst'].impl('m5op.S', default=True)
diff --git a/util/m5/src/x86/SConsopts b/util/m5/src/x86/SConsopts
index 8bfbe0a..8763f29 100644
--- a/util/m5/src/x86/SConsopts
+++ b/util/m5/src/x86/SConsopts
@@ -28,4 +28,6 @@
env['VARIANT'] = 'x86'
get_variant_opt('CROSS_COMPILE', '')
env.Append(CFLAGS='-DM5OP_ADDR=0xFFFF0000')
-env.Append(ASFLAGS='-DM5OP_ADDR=0xFFFF0000')
+
+env['CALL_TYPE']['inst'].impl('m5op.S')
+env['CALL_TYPE']['addr'].impl('m5op_addr.S', default=True)
diff --git a/util/m5/src/x86/m5op.S b/util/m5/src/x86/m5op.S
index cd83a94..9a425b6 100644
--- a/util/m5/src/x86/m5op.S
+++ b/util/m5/src/x86/m5op.S
@@ -28,57 +28,18 @@
#include <gem5/asm/generic/m5ops.h>
-/*
- Note: The ABI for pseudo ops using the M5OP_ADDR is defined in
- src/arch/x86/pseudo_inst_abi.hh. If the ABI is changed below, it's likely
- that the ABI in the arch directory will also need to be updated.
+.macro m5op_func, name, func
+ .globl \name
+ .func \name
+\name:
+ .byte 0x0F, 0x04
+ .word \func
+ ret
+ .endfunc
+.endm
- The ABI for the magic instruction-based pseudo ops is not affected by
this.
-*/
+.text
-#if defined(M5OP_ADDR) && defined(M5OP_PIC)
-/* Use the memory mapped m5op interface */
-#define TWO_BYTE_OP(name, number) \
- .globl name; \
- .func name; \
-name: \
- mov m5_mem@gotpcrel(%rip), %r11; \
- mov (%r11), %r11; \
- mov $number, %rax; \
- shl $8, %rax; \
- mov 0(%r11, %rax, 1), %rax; \
- ret; \
- .endfunc;
-
-#elif defined(M5OP_ADDR) && !defined(M5OP_PIC)
-/* Use the memory mapped m5op interface */
-#define TWO_BYTE_OP(name, number) \
- .globl name; \
- .func name; \
-name: \
- mov m5_mem, %r11; \
- mov $number, %rax; \
- shl $8, %rax; \
- mov 0(%r11, %rax, 1), %rax; \
- ret; \
- .endfunc;
-
-#else
-/* Use the magic instruction based m5op interface. This does not work
- * in virtualized environments.
- */
-
-#define TWO_BYTE_OP(name, number) \
- .globl name; \
- .func name; \
-name: \
- .byte 0x0F, 0x04; \
- .word number; \
- ret; \
- .endfunc;
-
-#endif
-
-#define M5OP(name, number) TWO_BYTE_OP(name, number)
+#define M5OP(name, func) m5op_func name, func;
M5OP_FOREACH
#undef M5OP
diff --git a/util/m5/src/x86/m5op_addr.S b/util/m5/src/x86/m5op_addr.S
new file mode 100644
index 0000000..d6e6cf5
--- /dev/null
+++ b/util/m5/src/x86/m5op_addr.S
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2003-2006 The Regents of The University of Michigan
+ * 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.
+ */
+
+#include <gem5/asm/generic/m5ops.h>
+
+/*
+ * Note: The ABI for pseudo ops using the M5OP_ADDR is defined in
+ * src/arch/x86/pseudo_inst_abi.hh. If the ABI is changed below, it's
likely
+ * that the ABI in the arch directory will also need to be updated.
+ */
+
+.macro m5op_func, name, func
+ .globl \name
+ .func \name
+\name:
+#if defined(M5OP_PIC)
+ mov m5_mem@gotpcrel(%rip), %r11
+ mov (%r11), %r11
+#else
+ mov m5_mem, %r11
+#endif
+ mov $\func, %rax
+ shl $8, %rax
+ mov 0(%r11, %rax, 1), %rax
+ ret
+ .endfunc
+.endm
+
+.text
+#define M5OP(name, func) m5op_func M5OP_MERGE_TOKENS(name, _addr), func;
+ M5OP_FOREACH
+#undef M5OP
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/27242
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I5fc414740e30759e7dde719cddcc8d5d41f8cc74
Gerrit-Change-Number: 27242
Gerrit-PatchSet: 15
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-Reviewer: Bobby R. Bruce <[email protected]>
Gerrit-Reviewer: Earl Ou <[email protected]>
Gerrit-Reviewer: Gabe Black <[email protected]>
Gerrit-Reviewer: Giacomo Travaglini <[email protected]>
Gerrit-Reviewer: Jason Lowe-Power <[email protected]>
Gerrit-Reviewer: Pouya Fotouhi <[email protected]>
Gerrit-Reviewer: Yu-hsin Wang <[email protected]>
Gerrit-Reviewer: kokoro <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s