diff --git a/h/form/fdouble.h b/h/form/fdouble.h new file mode 100644 index 0000000..e69de29 diff --git a/h/form/fsingle.h b/h/form/fsingle.h new file mode 100644 index 0000000..98268ca --- /dev/null +++ b/h/form/fsingle.h @@ -0,0 +1,5 @@ +#pragma once +#include "form/instructions.h" + +extern const struct formation rv32f[]; +extern const struct formation rv64f[]; diff --git a/h/form/generic.h b/h/form/generic.h index dfb3aca..8292f68 100644 --- a/h/form/generic.h +++ b/h/form/generic.h @@ -18,6 +18,8 @@ #define OP_LUI 0x37 #define OP_AUIPC 0x17 #define OP_AMO 0x2F +#define OP_LOADF 0x13 +#define OP_STOREF 0x33 #define END_FORMATION \ { \ diff --git a/h/parse.h b/h/parse.h index 748f716..2566c22 100644 --- a/h/parse.h +++ b/h/parse.h @@ -28,5 +28,6 @@ arg_parser parse_al; arg_parser parse_as; arg_parser parse_csr; arg_parser parse_csri; +arg_parser parse_fltype; int parse_asm(const char *, struct sectionpos); diff --git a/src/form/fdouble.c b/src/form/fdouble.c new file mode 100644 index 0000000..e69de29 diff --git a/src/form/fsingle.c b/src/form/fsingle.c new file mode 100644 index 0000000..b96c0a0 --- /dev/null +++ b/src/form/fsingle.c @@ -0,0 +1,10 @@ + +#include "form/fsingle.h" + +#include "form/generic.h" +#include "parse.h" + +const struct formation rv32f[] = { + { "FLW", &form_itype, &parse_fltype, { 4, OP_LOADF, 0x2, 0 } }, + END_FORMATION +}; diff --git a/src/form/generic.c b/src/form/generic.c index e397c05..0235f0f 100644 --- a/src/form/generic.c +++ b/src/form/generic.c @@ -108,7 +108,6 @@ struct bytecode form_stype(const char *name, struct idata instruction, struct bytecode form_btype(const char *name, struct idata instruction, struct args args, size_t position) { - (void)position; logger(DEBUG, no_error, "Generating B type instruction %s", name); if (args.sym->type != SYMBOL_LABEL) @@ -166,7 +165,6 @@ struct bytecode form_utype(const char *name, struct idata instruction, struct bytecode form_jtype(const char *name, struct idata instruction, struct args args, size_t position) { - (void)position; logger(DEBUG, no_error, "Generating J type instruction %s", name); int32_t offset = calc_symbol_offset(args.sym, position); diff --git a/src/generation.c b/src/generation.c index f42f0af..30e8ab2 100644 --- a/src/generation.c +++ b/src/generation.c @@ -61,7 +61,7 @@ size_t getl(char **lineptr, size_t *n, FILE *stream) return (size_t)(p - bufptr - 1); } -void parse_file(FILE *ifp, FILE *ofp) +void parse_file(FILE *input, FILE *output) { char *line = NULL; size_t linesize = 0; @@ -69,9 +69,9 @@ void parse_file(FILE *ifp, FILE *ofp) linenumber = 0; - fseek(ifp, 0L, SEEK_SET); + fseek(input, 0L, SEEK_SET); - while ((nread = getl(&line, &linesize, ifp)) != (size_t)-1) { + while ((nread = getl(&line, &linesize, input)) != (size_t)-1) { linenumber++; logger(DEBUG, no_error, "Parsing line \"%s\"", line); if (parse_line(line, get_outputpos())) @@ -94,7 +94,7 @@ void parse_file(FILE *ifp, FILE *ofp) fill_strtab(); fill_symtab(); - flush_output(ofp); + flush_output(output); free_output(); free_instructions(); diff --git a/src/registers.c b/src/registers.c index 0c9c03b..34a74a1 100644 --- a/src/registers.c +++ b/src/registers.c @@ -386,24 +386,23 @@ const struct { { "dscratch1", 0x7B3 }, }; -/* TODO: implement w/ float extension */ -const char *float_reg_abi_map[] = { 0 }; - size_t get_register_id(const char *reg) { - logger(DEBUG, no_error, "Searching for register (%s)", reg); - - /* limit the number of possible characters in the register */ - int l = 0; - while (reg[l] && reg[l] != ' ') - l++; - if (l > 4) - return (size_t)-1; + logger(DEBUG, no_error, "Searching for register %s", reg); if (*reg == 'x') { - size_t r = (size_t)atol(reg + 1); - if (r >= 32) + char *endptr; + size_t r = strtol(reg + 1, &endptr, 10); + if (*endptr) { + logger(ERROR, error_instruction_other, + "Expected end of register but got %s", endptr); return (size_t)-1; + } + if (r >= 32) { + logger(ERROR, error_instruction_other, + "Maximum register is x31 but got %s", reg); + return (size_t)-1; + } return r; } @@ -415,24 +414,31 @@ size_t get_register_id(const char *reg) if (!strcmp(reg, "fp")) return 8; - logger(INFO, no_error, "unknown register (%s)", reg); + logger(ERROR, no_error, "unknown register %s", reg); return (size_t)-1; } size_t get_float_register_id(const char *reg) { - if (*reg != 'f') + if (*reg != 'f') { + logger(ERROR, error_instruction_other, + "Expected floating point register but got %s", reg); return (size_t)-1; - - if (reg[1] >= '0' && reg[1] <= '9') - return (size_t)atoi(reg + 1); - - for (size_t i = 0; i < ARRAY_LENGTH(float_reg_abi_map); i++) - if (!strcmp(reg, float_reg_abi_map[i])) - return i; - - return (size_t)-1; + } + char *endptr; + size_t r = strtol(reg + 1, &endptr, 10); + if (*endptr) { + logger(ERROR, error_instruction_other, + "Expected end of register but got %s", endptr); + return (size_t)-1; + } + if (r >= 32) { + logger(ERROR, error_instruction_other, + "Maximum register is f31 but got %s", reg); + return (size_t)-1; + } + return r; } int get_immediate(const char *imm, size_t *res)