util: c++-ify the call type in the m5 utility.
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>
This commit is contained in:
@@ -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 ])
|
||||
|
||||
|
||||
@@ -27,10 +27,11 @@
|
||||
|
||||
#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)
|
||||
{
|
||||
static const char *prefix = "--addr";
|
||||
const size_t prefix_len = strlen(prefix);
|
||||
uint64_t addr_override;
|
||||
#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
|
||||
|
||||
// If the first argument starts with --addr...
|
||||
if (args->argc && memcmp(args->argv[0], prefix, prefix_len) == 0) {
|
||||
const char *argv0 = pop_arg(args);
|
||||
class AddrCallType : public CallType
|
||||
{
|
||||
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 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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// If the default address was not defined, an override is required.
|
||||
if (!DefaultAddrDefined)
|
||||
usage();
|
||||
|
||||
DispatchTable *
|
||||
addr_call_type_init()
|
||||
{
|
||||
map_m5_mem();
|
||||
return &addr_dispatch;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void init() override { map_m5_mem(); }
|
||||
} addr_call_type;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
@@ -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__
|
||||
@@ -25,40 +25,58 @@
|
||||
* 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
|
||||
|
||||
#define default_call_type_init() \
|
||||
M5OP_MERGE_TOKENS(DEFAULT_CALL_TYPE, _call_type_init())
|
||||
|
||||
DispatchTable *
|
||||
init_call_type(Args *args)
|
||||
std::vector<CallType *> &
|
||||
CallType::allTypes()
|
||||
{
|
||||
# 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();
|
||||
static std::vector<CallType *> all;
|
||||
return all;
|
||||
}
|
||||
|
||||
CallType &
|
||||
CallType::detect(Args &args)
|
||||
{
|
||||
CallType *def = nullptr;
|
||||
|
||||
for (auto *ct: allTypes()) {
|
||||
if (ct->checkArgs(args)) {
|
||||
ct->init();
|
||||
return *ct;
|
||||
}
|
||||
if (ct->isDefault())
|
||||
def = ct;
|
||||
}
|
||||
|
||||
assert(def);
|
||||
def->init();
|
||||
return *def;
|
||||
}
|
||||
|
||||
std::string
|
||||
CallType::usageSummary()
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -28,9 +28,34 @@
|
||||
#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__
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -27,26 +27,39 @@
|
||||
|
||||
#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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public:
|
||||
bool isDefault() const override { return CALL_TYPE_IS_DEFAULT; }
|
||||
const DispatchTable &getDispatch() const override { return inst_dispatch; }
|
||||
|
||||
DispatchTable *
|
||||
inst_call_type_init()
|
||||
{
|
||||
return &inst_dispatch;
|
||||
}
|
||||
bool
|
||||
checkArgs(Args &args) override
|
||||
{
|
||||
if (args.argc && strcmp(args.argv[0], "--inst") == 0) {
|
||||
pop_arg(&args);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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__
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
public:
|
||||
bool isDefault() const override { return CALL_TYPE_IS_DEFAULT; }
|
||||
const DispatchTable &getDispatch() const override { return semi_dispatch; }
|
||||
|
||||
DispatchTable *
|
||||
semi_call_type_init()
|
||||
{
|
||||
return &semi_dispatch;
|
||||
}
|
||||
bool
|
||||
checkArgs(Args &args) override
|
||||
{
|
||||
if (args.argc && strcmp(args.argv[0], "--semi") == 0) {
|
||||
pop_arg(&args);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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__
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user