Initial commit
Added base code, can run ELF files and simulate RV32I instructions
This commit is contained in:
+178
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Command-line option parsing
|
||||
*/
|
||||
#include "vriscv.h"
|
||||
|
||||
#define OPTION_SEPARATOR "-"
|
||||
|
||||
uint64_t memory_size = 512 * 1024 * 1024;
|
||||
char* file_path;
|
||||
|
||||
static void print_usage();
|
||||
static void print_help();
|
||||
static void print_version();
|
||||
|
||||
static int parse_long_option(char* str, char* argq);
|
||||
|
||||
void parse_options(int argc, char** argv)
|
||||
{
|
||||
for(int i = 1; i < argc; i++)
|
||||
{
|
||||
// Start option parsing for argument 'i'
|
||||
if(argv[i][0] != *OPTION_SEPARATOR) continue;
|
||||
|
||||
// Check for long options
|
||||
if(argv[i][1] == *OPTION_SEPARATOR)
|
||||
{
|
||||
i += parse_long_option(argv[i] + 2, argv[i + 1]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Parse short options
|
||||
int k = 1;
|
||||
while(argv[i][k])
|
||||
{
|
||||
switch(argv[i][k])
|
||||
{
|
||||
case 'h':
|
||||
case '?':
|
||||
{
|
||||
print_help();
|
||||
exit(0);
|
||||
}
|
||||
case 'v':
|
||||
{
|
||||
print_version();
|
||||
exit(0);
|
||||
}
|
||||
case 'm':
|
||||
{
|
||||
// First try to convert next chars into int (ex. -m512)
|
||||
char* end;
|
||||
memory_size = strtol(&argv[i][k + 1], &end, 10);
|
||||
if(*end != '\0' || end == &argv[i][k + 1])
|
||||
{
|
||||
if(argv[i][k + 1])
|
||||
{
|
||||
fprintf(stderr, "Error: Option -m needs an argument, but you used -m in a group of options without an integer next to it\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Try to parse next arg as integer
|
||||
if(argc <= i + 1)
|
||||
{
|
||||
fprintf(stderr, "Error: Option " OPTION_SEPARATOR "m needs an argument\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
memory_size = strtol(argv[i + 1], &end, 10);
|
||||
if(*end != '\0')
|
||||
{
|
||||
fprintf(stderr, "Error: Invalid argument '%s' for option " OPTION_SEPARATOR "m\n", argv[i + 1]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
k = strlen(argv[i]) - 1;
|
||||
}
|
||||
}
|
||||
else k += (end - &argv[i][k + 1]);
|
||||
|
||||
if(memory_size <= 0)
|
||||
{
|
||||
fprintf(stderr, "Error: Memory size needs to be > 0\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(memory_size > 4096)
|
||||
{
|
||||
fprintf(stderr, "Error: Cannot address more than 4 GiB of memory on 32-bits !\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memory_size *= 1024 * 1024;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
fprintf(stderr, "Error: Unknown short option -%c\n", argv[i][k]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
if(argc <= 1)
|
||||
{
|
||||
print_usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
else file_path = argv[argc - 1];
|
||||
}
|
||||
|
||||
static int parse_long_option(char* str, char* argq)
|
||||
{
|
||||
if(strcmp(str, "help") == 0)
|
||||
{
|
||||
print_help();
|
||||
exit(0);
|
||||
}
|
||||
else if(strcmp(str, "version") == 0)
|
||||
{
|
||||
print_version();
|
||||
exit(0);
|
||||
}
|
||||
else if(strcmp(str, "memory") == 0)
|
||||
{
|
||||
if(argq == NULL)
|
||||
{
|
||||
fprintf(stderr, "Error: No argument given for option " OPTION_SEPARATOR "-memory\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Convert argument to integer
|
||||
char* end;
|
||||
memory_size = strtol(argq, &end, 10);
|
||||
if(*end != '\0')
|
||||
{
|
||||
fprintf(stderr, "Error: Invalid argument '%s' for option " OPTION_SEPARATOR "-memory\n", argq);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(memory_size > 4096)
|
||||
{
|
||||
fprintf(stderr, "Error: Cannot address more than 4 GiB of memory on 32-bits !\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memory_size *= 1024 * 1024;
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Error: Unknown long option " OPTION_SEPARATOR OPTION_SEPARATOR "%s\n", str);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_usage()
|
||||
{
|
||||
printf("Usage: %s [options] <elf-file>\n", CURRENT_NAME);
|
||||
}
|
||||
|
||||
static void print_help()
|
||||
{
|
||||
print_usage();
|
||||
|
||||
printf("Options:\n");
|
||||
printf(" " OPTION_SEPARATOR "h, " OPTION_SEPARATOR "?, --help\t\tPrint this help message\n");
|
||||
printf(" " OPTION_SEPARATOR "v, --version\t\t\tPrint version information\n");
|
||||
printf(" " OPTION_SEPARATOR "m, --memory\t\t\tSet the simulated memory size, in MiB\n");
|
||||
}
|
||||
|
||||
static void print_version()
|
||||
{
|
||||
printf("%s (%s) version %s\n", CURRENT_NAME, NAME, VERSION);
|
||||
}
|
||||
Reference in New Issue
Block a user