Gabe Black has uploaded this change for review. ( 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
---
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, 221 insertions(+), 96 deletions(-)



diff --git a/util/m5/SConstruct b/util/m5/SConstruct
index 822ba7a..d007925 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()
@@ -60,11 +61,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 viarant foo to bar-, the user would set an
diff --git a/util/m5/src/SConscript b/util/m5/src/SConscript
index e5ead1a..4ae2f6d 100644
--- a/util/m5/src/SConscript
+++ b/util/m5/src/SConscript
@@ -29,30 +29,45 @@

 # 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')

+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_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 +86,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 +96,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 af68e79..6529dcf 100644
--- a/util/m5/src/aarch64/m5op.S
+++ b/util/m5/src/aarch64/m5op.S
@@ -40,30 +40,12 @@

 #include <gem5/asm/generic/m5ops.h>

-#ifdef M5OP_ADDR
-.macro m5op_func, name, func
-        .globl \name
-        \name:
-#if defined(M5OP_PIC)
-        /* Load the address of m5_mem from the global offset table. */
-        ldr x9, :got:m5_mem
-        /* Load the value of m5_mem into x9. */
-        ldr x9, [ x9 ]
-#else
-        ldr x9, 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..79bdaf1
--- /dev/null
+++ b/util/m5/src/aarch64/m5op_addr.S
@@ -0,0 +1,58 @@
+/*
+ * 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 address of m5_mem from the global offset table. */
+        ldr x9, :got:m5_mem
+        /* Load the value of m5_mem into x9. */
+        ldr x9, [ x9 ]
+        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 11818c5..6ff15d2 100644
--- a/util/m5/src/m5.c
+++ b/util/m5/src/m5.c
@@ -51,25 +51,14 @@

 #include <gem5/asm/generic/m5ops.h>
 #include <gem5/m5ops.h>
-#include "m5_mmap.h"
+
+#include "call_type.h"
+#include "dispatch_table.h"

 char *progname;
 char *command = "unspecified";
 void usage();

-typedef struct DispatchTable
-{
-#define M5OP(name, func) __typeof__(&name) name;
-M5OP_FOREACH
-#undef M5OP
-} DispatchTable;
-
-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)
 {
@@ -346,22 +335,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: 1
Gerrit-Owner: Gabe Black <gabebl...@google.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to