Added instruction set selector to CLI

float_support
Anton Lydike 4 years ago
parent 8b1cbd97ec
commit cd17c65ce7

@ -35,7 +35,9 @@ Basic IO should work, as open, read, write and close are supported for stdin/std
This is how the interface is used: This is how the interface is used:
``` ```
riscemu [--options OPTIONS] [--syscall-option SYSCALL_OPTIONS] [--default_stack_size] file.asm [file.asm ...] usage: riscemu [-h] [--options OPTIONS] [--syscall-opts SYSCALL_OPTS] [--instruction-sets INSTRUCTION_SETS] [--default_stack_size [default-stack-size]] file.asm [file.asm ...]
OPTIONS and SYSCALL_OPTIONS is a list of comma-separated flags that will be enabled OPTIONS and SYSCALL_OPTIONS is a list of comma-separated flags that will be enabled
@ -44,9 +46,14 @@ disable_debug Disable the ebreak and sbreak instructions
no_syscall_symbols Don't make syscall symbols globally available no_syscall_symbols Don't make syscall symbols globally available
fail_on_ex Do not launch an interactive debugger when the CPU loop catches an exception fail_on_ex Do not launch an interactive debugger when the CPU loop catches an exception
SYSCALL_OPTIONS: SYSCALL_OPTS: Options to control syscall behaviour
fs_access Allow access to the filesystem fs_access Allow access to the filesystem
disable_io Disallow reading/writing from stdin/stdout/stderr disable_io Disallow reading/writing from stdin/stdout/stderr
INSTRUCTION_SETS: A list of comma separated instruction sets you want to load:
Currently implemented: RV32I, RV32M
``` ```
If multiple files are specified, all are loaded into memeory, but only the last one is executed. This might be improved If multiple files are specified, all are loaded into memeory, but only the last one is executed. This might be improved

@ -1,13 +1,14 @@
if __name__ == '__main__': if __name__ == '__main__':
from . import * from . import *
from .helpers import * from .helpers import *
from .instructions import RV32I, RV32M from .instructions import InstructionSetDict
import argparse import argparse
import sys import sys
all_ins_names = list(InstructionSetDict.keys())
class OptionStringAction(argparse.Action): class OptionStringAction(argparse.Action):
def __init__(self, option_strings, dest, keys=None, **kwargs): def __init__(self, option_strings, dest, keys=None, omit_empty=False, **kwargs):
if keys is None: if keys is None:
raise ValueError('must define "keys" argument') raise ValueError('must define "keys" argument')
if isinstance(keys, dict): if isinstance(keys, dict):
@ -24,13 +25,17 @@ if __name__ == '__main__':
keys_d = dict() keys_d = dict()
super().__init__(option_strings, dest, default=keys_d, **kwargs) super().__init__(option_strings, dest, default=keys_d, **kwargs)
self.keys = keys_d self.keys = keys_d
self.omit_empty = omit_empty
def __call__(self, parser, namespace, values, option_string=None): def __call__(self, parser, namespace, values, option_string=None):
d = {} d = {}
d.update(self.keys) if not self.omit_empty:
d.update(self.keys)
for x in values.split(','): for x in values.split(','):
if x in self.keys: if x in self.keys:
d[x] = True d[x] = True
else:
raise ValueError('Invalid parameter supplied: ' + x)
setattr(namespace, self.dest, d) setattr(namespace, self.dest, d)
@ -44,6 +49,10 @@ if __name__ == '__main__':
parser.add_argument('--syscall-opts', '-so', action=OptionStringAction, parser.add_argument('--syscall-opts', '-so', action=OptionStringAction,
keys=('fs_access', 'disable_input')) keys=('fs_access', 'disable_input'))
parser.add_argument('--instruction-sets', '-is', action=OptionStringAction, help="Instruction sets to load, available are: {}. "
"All are enabled by default"
.format(", ".join(all_ins_names)), keys={k: True for k in all_ins_names}, omit_empty=True)
parser.add_argument('--default_stack_size', type=int, help='Default stack size of loaded programs', default=None, parser.add_argument('--default_stack_size', type=int, help='Default stack size of loaded programs', default=None,
metavar='default-stack-size', nargs='?') metavar='default-stack-size', nargs='?')
@ -60,8 +69,13 @@ if __name__ == '__main__':
FMT_PRINT = FMT_BOLD + FMT_MAGENTA FMT_PRINT = FMT_BOLD + FMT_MAGENTA
# parse required instruction sets
ins_to_load = [
InstructionSetDict[name] for name, b in args.ins.items() if b
]
try: try:
cpu = CPU(cfg, [RV32I, RV32M]) cpu = CPU(cfg, ins_to_load)
loaded_exe = None loaded_exe = None
for file in args.files: for file in args.files:
tk = cpu.get_tokenizer(RiscVInput.from_file(file)) tk = cpu.get_tokenizer(RiscVInput.from_file(file))

@ -1,3 +1,7 @@
from .InstructionSet import InstructionSet from .InstructionSet import InstructionSet
from .RV32M import RV32M from .RV32M import RV32M
from .RV32I import RV32I from .RV32I import RV32I
InstructionSetDict = {
v.__name__: v for v in [RV32I, RV32M]
}

Loading…
Cancel
Save