util: c++-ify the call type in the m5 utility.
authorGabe Black <gabeblack@google.com>
Sat, 4 Apr 2020 12:39:50 +0000 (05:39 -0700)
committerGabe Black <gabeblack@google.com>
Fri, 26 Jun 2020 02:36:48 +0000 (02:36 +0000)
Use a class to track call type information, and mostly avoid having to
use ifdefs to include or not include support for individual call types.

Change-Id: I731c99e67ea1c511d53431df3f77b4a959919a59
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27549
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Gabe Black <gabeblack@google.com>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Maintainer: Gabe Black <gabeblack@google.com>

13 files changed:
util/m5/src/SConscript
util/m5/src/addr_call_type.cc
util/m5/src/addr_call_type.hh [deleted file]
util/m5/src/call_type.cc
util/m5/src/call_type.hh
util/m5/src/commands.cc
util/m5/src/commands.hh
util/m5/src/inst_call_type.cc
util/m5/src/inst_call_type.hh [deleted file]
util/m5/src/m5.cc
util/m5/src/semi_call_type.cc
util/m5/src/semi_call_type.hh [deleted file]
util/m5/src/usage.cc

index 0961f2f5d2520f6d690da1713fa6c640e1f98b57..176f4c262f3530b97a9d95650dc159a06390dc66 100644 (file)
@@ -51,13 +51,6 @@ 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(CXXFLAGS='-DENABLE_CT_%s=%d' %
-                (ct.name, 1 if ct.enabled else 0))
-    static_env.Append(CXXFLAGS='-DDEFAULT_CT_%s=%d' %
-                (ct.name, 1 if ct.default else 0))
-static_env.Append(CXXFLAGS='-DDEFAULT_CALL_TYPE=%s' % default_call_type.name)
-
 #
 # The m5 library for use in other C/C++ programs.
 #
@@ -67,7 +60,12 @@ libm5 = static_env.StaticLibrary('out/m5', [ m5_mmap ] + m5ops)
 #
 # The m5 stand alone command line utility.
 #
-ct_support = list([ File('%s_call_type.cc' % ct.name) for ct in call_types ])
+ct_support = []
+for ct in call_types:
+    ct_env = static_env.Clone()
+    is_default = 'true' if ct.default else 'false'
+    ct_env.Append(CXXFLAGS=[ '-DCALL_TYPE_IS_DEFAULT=%s' % is_default ])
+    ct_support.extend(ct_env.StaticObject('%s_call_type.cc' % ct.name))
 m5_bin = static_env.Program('out/m5',
         ct_support + [ args, call_type, commands, m5, m5_mmap, libm5, usage ])
 
index cdf5e5d7f67d03f87cad194483147491ef2f76b1..3a10ffab5830657c904acd4d0e2f47142fc7d8c7 100644 (file)
 
 #include <cstring>
 
-#include "addr_call_type.hh"
-#include "args.hh"
 #include "m5_mmap.h"
 
+#include "call_type.hh"
+#include "usage.hh"
+
 extern "C"
 {
 #define M5OP(name, func) __typeof__(name) M5OP_MERGE_TOKENS(name, _addr);
@@ -38,54 +39,88 @@ M5OP_FOREACH
 #undef M5OP
 }
 
-static DispatchTable addr_dispatch = {
+namespace
+{
+
+DispatchTable addr_dispatch = {
 #define M5OP(name, func) .name = &::M5OP_MERGE_TOKENS(name, _addr),
 M5OP_FOREACH
 #undef M5OP
 };
 
-int
-addr_call_type_detect(Args *args)
+#if defined(M5OP_ADDR)
+const bool DefaultAddrDefined = true;
+constexpr uint64_t DefaultAddress = M5OP_ADDR;
+#else
+const bool DefaultAddrDefined = false;
+constexpr uint64_t DefaultAddress = 0;
+#endif
+
+class AddrCallType : public CallType
 {
-    static const char *prefix = "--addr";
-    const size_t prefix_len = strlen(prefix);
-    uint64_t addr_override;
+  private:
+  public:
+    bool isDefault() const override { return CALL_TYPE_IS_DEFAULT; }
+    const DispatchTable &getDispatch() const override { return addr_dispatch; }
+
+    void
+    printBrief(std::ostream &os) const override
+    {
+        os << "--addr " << (DefaultAddrDefined ? "[address override]" :
+                                                 "<address override>");
+    }
+
+    void
+    printDesc(std::ostream &os) const override
+    {
+        os << "Use the address based invocation method.";
+        if (DefaultAddrDefined) {
+            os << " The default address is 0x" <<
+                std::hex << DefaultAddress << std::dec << ".";
+        }
+    }
+
+    bool
+    checkArgs(Args &args) override
+    {
+        static const char *prefix = "--addr";
+        const size_t prefix_len = strlen(prefix);
+        uint64_t addr_override;
 
-    // If the first argument starts with --addr...
-    if (args->argc && memcmp(args->argv[0], prefix, prefix_len) == 0) {
-        const char *argv0 = pop_arg(args);
+        // If the first argument doesn't start with --addr...
+        if (!args.argc || memcmp(args.argv[0], prefix, prefix_len) != 0)
+            return false;
+
+        const char *argv0 = pop_arg(&args);
 
         // If there's more text in this argument...
         if (strlen(argv0) != prefix_len) {
             // If it doesn't start with '=', it's malformed.
             if (argv0[prefix_len] != '=')
-                return -1;
+                usage();
             // Attempt to extract an address after the '='.
             const char *temp_argv[] = { &argv0[prefix_len + 1] };
             Args temp_args = { 1, temp_argv };
             if (!parse_int_args(&temp_args, &addr_override, 1))
-                return -1;
+                usage();
             // If we found an address, use it to override m5op_addr.
             m5op_addr = addr_override;
-            return 1;
+            return true;
         }
         // If an address override wasn't part of the first argument, check if
         // it's the second argument. If not, then there's no override.
-        if (args->argc && parse_int_args(args, &addr_override, 1)) {
+        if (args.argc && parse_int_args(&args, &addr_override, 1)) {
             m5op_addr = addr_override;
-            return 1;
+            return true;
         }
-        // If the default address was zero, an override is required.
-        if (!m5op_addr)
-            return -1;
-        return 1;
+        // If the default address was not defined, an override is required.
+        if (!DefaultAddrDefined)
+            usage();
+
+        return true;
     }
-    return 0;
-}
 
-DispatchTable *
-addr_call_type_init()
-{
-    map_m5_mem();
-    return &addr_dispatch;
-}
+    void init() override { map_m5_mem(); }
+} addr_call_type;
+
+} // anonymous namespace
diff --git a/util/m5/src/addr_call_type.hh b/util/m5/src/addr_call_type.hh
deleted file mode 100644 (file)
index a327fd6..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2020 Google Inc.
- *
- * 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.
- */
-
-#ifndef __ADDR_CALL_TYPE_HH__
-#define __ADDR_CALL_TYPE_HH__
-
-#include "args.hh"
-#include "dispatch_table.hh"
-
-// Returns 0 if not detected, 1 if detected successfully, and -1 on error.
-int addr_call_type_detect(Args *args);
-DispatchTable *addr_call_type_init();
-
-#endif // __ADDR_CALL_TYPE_HH__
index 96b886933769a8cd75048b75415ad3846a491073..5deaae1c54438aa9b7e01c14a6d10559235bae70 100644 (file)
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "args.hh"
+#include <cassert>
+#include <sstream>
+
 #include "call_type.hh"
-#include "usage.hh"
 
-#if ENABLE_CT_addr
-#include "addr_call_type.hh"
-#endif
-#if ENABLE_CT_inst
-#include "inst_call_type.hh"
-#endif
-#if ENABLE_CT_semi
-#include "semi_call_type.hh"
-#endif
+std::vector<CallType *> &
+CallType::allTypes()
+{
+    static std::vector<CallType *> all;
+    return all;
+}
+
+CallType &
+CallType::detect(Args &args)
+{
+    CallType *def = nullptr;
 
-#define default_call_type_init() \
-    M5OP_MERGE_TOKENS(DEFAULT_CALL_TYPE, _call_type_init())
+    for (auto *ct: allTypes()) {
+        if (ct->checkArgs(args)) {
+            ct->init();
+            return *ct;
+        }
+        if (ct->isDefault())
+            def = ct;
+    }
 
-DispatchTable *
-init_call_type(Args *args)
+    assert(def);
+    def->init();
+    return *def;
+}
+
+std::string
+CallType::usageSummary()
 {
-#   if ENABLE_CT_inst
-    if (inst_call_type_detect(args))
-        return inst_call_type_init();
-#   endif
-#   if ENABLE_CT_addr
-    int detect = addr_call_type_detect(args);
-    if (detect < 0)
-        usage();
-    if (detect > 0)
-        return addr_call_type_init();
-#   endif
-#   if ENABLE_CT_semi
-    if (semi_call_type_detect(args))
-        return semi_call_type_init();
-#   endif
-    return default_call_type_init();
+    std::string summary = "";
+    for (auto *ct: allTypes())
+        summary += ct->formattedUsage();
+    return summary;
+}
+
+std::string
+CallType::formattedUsage() const
+{
+    std::ostringstream os;
+    os << "    ";
+    printBrief(os);
+    if (isDefault())
+        os << " (default)";
+    os << std::endl;
+
+    os << "        ";
+    printDesc(os);
+    os << std::endl;
+    return os.str();
 }
index 92cd9c9608dc5563583e08a257e64d09538b944b..6ee536d2d19a6de742a522b8baa3ec0fb4897cc5 100644 (file)
 #ifndef __CALL_TYPE_HH__
 #define __CALL_TYPE_HH__
 
+#include <iostream>
+#include <string>
+#include <vector>
+
 #include "args.hh"
 #include "dispatch_table.hh"
 
-DispatchTable *init_call_type(Args *args);
+class CallType
+{
+  protected:
+    virtual bool isDefault() const = 0;
+    virtual bool checkArgs(Args &args) = 0;
+    virtual void init() {}
+
+    static std::vector<CallType *> &allTypes();
+
+    virtual void printBrief(std::ostream &os) const = 0;
+    virtual void printDesc(std::ostream &os) const = 0;
+    std::string formattedUsage() const;
+
+  public:
+    CallType() { allTypes().push_back(this); }
+
+    static CallType &detect(Args &args);
+    static std::string usageSummary();
+
+    virtual const DispatchTable &getDispatch() const = 0;
+};
+
 
 #endif // __CALL_TYPE_HH__
index 9cd43c0cefc609a133af4be67d36a77bd66206bb..2690f0fe251905166dc663d0499479944a1b4e55 100644 (file)
@@ -40,7 +40,7 @@
 #include "usage.hh"
 
 static int
-read_file(DispatchTable *dt, int dest_fid)
+read_file(const DispatchTable &dt, int dest_fid)
 {
     uint8_t buf[256*1024];
     int offset = 0;
@@ -51,7 +51,7 @@ read_file(DispatchTable *dt, int dest_fid)
     // Linux does demand paging.
     memset(buf, 0, sizeof(buf));
 
-    while ((len = (*dt->m5_read_file)(buf, sizeof(buf), offset)) > 0) {
+    while ((len = (*dt.m5_read_file)(buf, sizeof(buf), offset)) > 0) {
         uint8_t *base = buf;
         offset += len;
         do {
@@ -74,7 +74,8 @@ read_file(DispatchTable *dt, int dest_fid)
 }
 
 static void
-write_file(DispatchTable *dt, const char *filename, const char *host_filename)
+write_file(const DispatchTable &dt, const char *filename,
+           const char *host_filename)
 {
     fprintf(stderr, "opening %s\n", filename);
     int src_fid = open(filename, O_RDONLY);
@@ -92,7 +93,7 @@ write_file(DispatchTable *dt, const char *filename, const char *host_filename)
     memset(buf, 0, sizeof(buf));
 
     while ((len = read(src_fid, buf, sizeof(buf))) > 0) {
-        bytes += (*dt->m5_write_file)(buf, len, offset, host_filename);
+        bytes += (*dt.m5_write_file)(buf, len, offset, host_filename);
         offset += len;
     }
     fprintf(stderr, "written %d bytes\n", bytes);
@@ -101,7 +102,7 @@ write_file(DispatchTable *dt, const char *filename, const char *host_filename)
 }
 
 static void
-do_exit(DispatchTable *dt, Args *args)
+do_exit(const DispatchTable &dt, Args *args)
 {
     if (args->argc > 1)
         usage();
@@ -109,11 +110,11 @@ do_exit(DispatchTable *dt, Args *args)
     uint64_t ints[1];
     if (!parse_int_args(args, ints, 1))
         usage();
-    (*dt->m5_exit)(ints[0]);
+    (*dt.m5_exit)(ints[0]);
 }
 
 static void
-do_fail(DispatchTable *dt, Args *args)
+do_fail(const DispatchTable &dt, Args *args)
 {
     if (args->argc < 1 || args->argc > 2)
         usage();
@@ -121,38 +122,38 @@ do_fail(DispatchTable *dt, Args *args)
     uint64_t ints[2] = { 0, 0 };
     if (!parse_int_args(args, ints, args->argc))
         usage();
-    (*dt->m5_fail)(ints[1], ints[0]);
+    (*dt.m5_fail)(ints[1], ints[0]);
 }
 
 static void
-do_reset_stats(DispatchTable *dt, Args *args)
+do_reset_stats(const DispatchTable &dt, Args *args)
 {
     uint64_t ints[2];
     if (!parse_int_args(args, ints, 2))
         usage();
-    (*dt->m5_reset_stats)(ints[0], ints[1]);
+    (*dt.m5_reset_stats)(ints[0], ints[1]);
 }
 
 static void
-do_dump_stats(DispatchTable *dt, Args *args)
+do_dump_stats(const DispatchTable &dt, Args *args)
 {
     uint64_t ints[2];
     if (!parse_int_args(args, ints, 2))
         usage();
-    (*dt->m5_dump_stats)(ints[0], ints[1]);
+    (*dt.m5_dump_stats)(ints[0], ints[1]);
 }
 
 static void
-do_dump_reset_stats(DispatchTable *dt, Args *args)
+do_dump_reset_stats(const DispatchTable &dt, Args *args)
 {
     uint64_t ints[2];
     if (!parse_int_args(args, ints, 2))
         usage();
-    (*dt->m5_dump_reset_stats)(ints[0], ints[1]);
+    (*dt.m5_dump_reset_stats)(ints[0], ints[1]);
 }
 
 static void
-do_read_file(DispatchTable *dt, Args *args)
+do_read_file(const DispatchTable &dt, Args *args)
 {
     if (args->argc > 0)
         usage();
@@ -161,7 +162,7 @@ do_read_file(DispatchTable *dt, Args *args)
 }
 
 static void
-do_write_file(DispatchTable *dt, Args *args)
+do_write_file(const DispatchTable &dt, Args *args)
 {
     if (args->argc != 1 && args->argc != 2)
         usage();
@@ -175,37 +176,37 @@ do_write_file(DispatchTable *dt, Args *args)
 }
 
 static void
-do_checkpoint(DispatchTable *dt, Args *args)
+do_checkpoint(const DispatchTable &dt, Args *args)
 {
     uint64_t ints[2];
     if (!parse_int_args(args, ints, 2))
         usage();
-    (*dt->m5_checkpoint)(ints[0], ints[1]);
+    (*dt.m5_checkpoint)(ints[0], ints[1]);
 }
 
 static void
-do_addsymbol(DispatchTable *dt, Args *args)
+do_addsymbol(const DispatchTable &dt, Args *args)
 {
     if (args->argc != 2)
         usage();
 
     uint64_t addr = strtoul(pop_arg(args), NULL, 0);
     const char *symbol = pop_arg(args);
-    (*dt->m5_add_symbol)(addr, symbol);
+    (*dt.m5_add_symbol)(addr, symbol);
 }
 
 
 static void
-do_loadsymbol(DispatchTable *dt, Args *args)
+do_loadsymbol(const DispatchTable &dt, Args *args)
 {
     if (args->argc > 0)
         usage();
 
-    (*dt->m5_load_symbol)();
+    (*dt.m5_load_symbol)();
 }
 
 static void
-do_initparam(DispatchTable *dt, Args *args)
+do_initparam(const DispatchTable &dt, Args *args)
 {
     if (args->argc > 1)
         usage();
@@ -213,7 +214,7 @@ do_initparam(DispatchTable *dt, Args *args)
     uint64_t key_str[2];
     if (!pack_arg_into_regs(args, key_str, 2))
         usage();
-    uint64_t val = (*dt->m5_init_param)(key_str[0], key_str[1]);
+    uint64_t val = (*dt.m5_init_param)(key_str[0], key_str[1]);
     std::cout << val;
 }
 
index 05b54f64271af41be1a13aabc99c48b71eac5653..83a3335c7ed502bd4e1cefb07ac594f573726ac8 100644 (file)
@@ -38,7 +38,7 @@ struct CommandInfo
     const char *name;
     // A function which processes command line arguments and passes them to
     // the underlying function through the dispatch table.
-    void (*func)(DispatchTable *dt, Args *args);
+    void (*func)(const DispatchTable &dt, Args *args);
     // Help text for this command.
     const char *usage;
 };
index 5fbd756d90d1558ed66db19ffc546ab26232c285..49f87abcc20e65f8e64ad32a9d3a4f3842565d3a 100644 (file)
 
 #include <cstring>
 
-#include "inst_call_type.hh"
+#include "call_type.hh"
 
-static DispatchTable inst_dispatch = {
+namespace
+{
+
+DispatchTable inst_dispatch = {
 #define M5OP(name, func) .name = &::name,
 M5OP_FOREACH
 #undef M5OP
 };
 
-int
-inst_call_type_detect(Args *args)
+class InstCallType : public CallType
 {
-    if (args->argc && strcmp(args->argv[0], "--inst") == 0) {
-        pop_arg(args);
-        return 1;
+  public:
+    bool isDefault() const override { return CALL_TYPE_IS_DEFAULT; }
+    const DispatchTable &getDispatch() const override { return inst_dispatch; }
+
+    bool
+    checkArgs(Args &args) override
+    {
+        if (args.argc && strcmp(args.argv[0], "--inst") == 0) {
+            pop_arg(&args);
+            return true;
+        }
+        return false;
     }
-    return 0;
-}
 
-DispatchTable *
-inst_call_type_init()
-{
-    return &inst_dispatch;
-}
+    void printBrief(std::ostream &os) const override { os << "--inst"; }
+    void
+    printDesc(std::ostream &os) const override
+    {
+        os << "Use the instruction based invocation method.";
+    }
+} inst_call_type;
+
+} // anonymous namespace
diff --git a/util/m5/src/inst_call_type.hh b/util/m5/src/inst_call_type.hh
deleted file mode 100644 (file)
index a0d76fe..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2020 Google Inc.
- *
- * 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.
- */
-
-#ifndef __INST_CALL_TYPE_HH__
-#define __INST_CALL_TYPE_HH__
-
-#include "args.hh"
-#include "dispatch_table.hh"
-
-int inst_call_type_detect(Args *args);
-DispatchTable *inst_call_type_init();
-
-#endif // __INST_CALL_TYPE_HH__
index 8a48337484dd4fcaa691e9998ca2be304353e582..283dada3f9579f9572e3a11e7dcafd9b93d50e6c 100644 (file)
@@ -56,7 +56,7 @@ main(int argc, const char *argv[])
 
     progname = pop_arg(&args);
 
-    DispatchTable *dt = init_call_type(&args);
+    const DispatchTable &dt = CallType::detect(args).getDispatch();
 
     const char *command = pop_arg(&args);
 
index 85057c241c343cf679f56d09e63649f8c951032b..5c9787ff593a2ef4119994cbd3f38f1f485314ca 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <cstring>
 
-#include "semi_call_type.hh"
+#include "call_type.hh"
 
 extern "C"
 {
@@ -36,24 +36,37 @@ M5OP_FOREACH
 #undef M5OP
 }
 
-static DispatchTable semi_dispatch = {
+namespace
+{
+
+DispatchTable semi_dispatch = {
 #define M5OP(name, func) .name = &::M5OP_MERGE_TOKENS(name, _semi),
 M5OP_FOREACH
 #undef M5OP
 };
 
-int
-semi_call_type_detect(Args *args)
+class SemiCallType : public CallType
 {
-    if (args->argc && strcmp(args->argv[0], "--semi") == 0) {
-        pop_arg(args);
-        return 1;
+  public:
+    bool isDefault() const override { return CALL_TYPE_IS_DEFAULT; }
+    const DispatchTable &getDispatch() const override { return semi_dispatch; }
+
+    bool
+    checkArgs(Args &args) override
+    {
+        if (args.argc && strcmp(args.argv[0], "--semi") == 0) {
+            pop_arg(&args);
+            return true;
+        }
+        return false;
     }
-    return 0;
-}
 
-DispatchTable *
-semi_call_type_init()
-{
-    return &semi_dispatch;
-}
+    void printBrief(std::ostream &os) const override { os << "--semi"; }
+    void
+    printDesc(std::ostream &os) const override
+    {
+        os << "Use the semi-hosting based invocation method.";
+    }
+} semi_call_type;
+
+} // anonymous namespace
diff --git a/util/m5/src/semi_call_type.hh b/util/m5/src/semi_call_type.hh
deleted file mode 100644 (file)
index 73081dd..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2020 Google Inc.
- *
- * 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.
- */
-
-#ifndef __SEMI_CALL_TYPE_HH__
-#define __SEMI_CALL_TYPE_HH__
-
-#include "args.hh"
-#include "dispatch_table.hh"
-
-int semi_call_type_detect(Args *args);
-DispatchTable *semi_call_type_init();
-
-#endif // __SEMI_CALL_TYPE_HH__
index 620d8cd2ec466856654386a83d074d0eddd8c4b9..a472b1e7cc109abb03eca430978aa842087d0fbf 100644 (file)
@@ -42,6 +42,7 @@
 #include <cstdio>
 #include <cstdlib>
 
+#include "call_type.hh"
 #include "commands.hh"
 #include "usage.hh"
 
@@ -53,28 +54,7 @@ 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%s\n",
-#   if defined(M5OP_ADDR)
-            "[address override]",
-#   else
-            "<address override>",
-#   endif
-            DEFAULT_CT_addr ? " (default)" : "");
-    fprintf(stderr, "        Use the address based invocation method.\n");
-#   if defined(M5OP_ADDR)
-    fprintf(stderr, "        The default 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, CallType::usageSummary().c_str());
     fprintf(stderr, "\n");
     fprintf(stderr, "Commands:\n");
     for (int i = 0; i < num_commands; ++i) {