asm: assembler: implement label creation and resolution

This commit is contained in:
2025-05-14 16:27:22 +01:00
parent 6399022cb3
commit a35ae51b2f
4 changed files with 252 additions and 30 deletions

View File

@@ -63,6 +63,7 @@ enum ivy_status ivy_assembler_create(FILE *fp, struct ivy_assembler **as)
static void pad(struct ivy_assembler *as, unsigned int boundary)
{
fseek(as->as_data, as->as_data_offset, SEEK_SET);
while ((as->as_data_offset % boundary) != 0) {
fputc(0, as->as_data);
as->as_data_offset++;
@@ -75,6 +76,7 @@ enum ivy_status ivy_assembler_finish(struct ivy_assembler *as)
size_t xdat_len = as->as_next_xdata_key;
fseek(as->as_xdat, 0, SEEK_SET);
fseek(as->as_data, as->as_data_offset, SEEK_SET);
unsigned char *buf = malloc(buf_len);
if (!buf) {
@@ -143,16 +145,40 @@ enum ivy_status ivy_assembler_finish(struct ivy_assembler *as)
return IVY_OK;
}
size_t ivy_assembler_get_ptr(const struct ivy_assembler *as)
{
return as->as_data_offset;
}
size_t assembler_write_data(struct ivy_assembler *as, const void *p, size_t len)
{
size_t offset = as->as_data_offset;
fwrite(p, 1, len, as->as_data);
fseek(as->as_data, offset, SEEK_SET);
size_t w = fwrite(p, 1, len, as->as_data);
as->as_data_offset += len;
return offset;
}
enum ivy_status assembler_read_data_at(
struct ivy_assembler *as, void *p, size_t offset, size_t len, size_t *nr_read)
{
fseek(as->as_data, offset, SEEK_SET);
*nr_read = fread(p, 1, len, as->as_data);
return ferror(as->as_data) ? IVY_ERR_IO_FAILURE : IVY_OK;
}
size_t assembler_write_data_at(
struct ivy_assembler *as, const void *p, size_t offset, size_t len)
{
fseek(as->as_data, offset, SEEK_SET);
fwrite(p, 1, len, as->as_data);
return ferror(as->as_data) ? IVY_ERR_IO_FAILURE : IVY_OK;
}
ivy_extended_data_key assembler_write_extended_data(
struct ivy_assembler *as, const void *p, size_t len)
{
@@ -193,10 +219,7 @@ enum ivy_status ivy_assembler_begin_scope(
memset(scope, 0x0, type_info->s_scope_size);
while ((as->as_data_offset % 16) != 0) {
fputc(0, as->as_data);
as->as_data_offset++;
}
pad(as, 16);
scope->s_ops = type_info;
scope->s_type = type;
@@ -314,3 +337,39 @@ enum ivy_status ivy_assembler_put_instr(
return type_info->s_put_instr(as, scope, i);
}
enum ivy_status ivy_assembler_put_label(
struct ivy_assembler *as, const struct ivy_asm_token *label_name,
size_t label_offset)
{
struct assembler_scope *scope = as->as_scope;
if (!scope) {
return IVY_ERR_NOT_SUPPORTED;
}
const struct assembler_scope_type *type_info = scope->s_ops;
if (!type_info || !type_info->s_put_label) {
return IVY_ERR_NOT_SUPPORTED;
}
return type_info->s_put_label(as, scope, label_name, label_offset);
}
enum ivy_status ivy_assembler_put_label_ref(
struct ivy_assembler *as, const struct ivy_asm_token *label_name,
size_t ref_offset)
{
struct assembler_scope *scope = as->as_scope;
if (!scope) {
return IVY_ERR_NOT_SUPPORTED;
}
const struct assembler_scope_type *type_info = scope->s_ops;
if (!type_info || !type_info->s_put_label_ref) {
return IVY_ERR_NOT_SUPPORTED;
}
return type_info->s_put_label_ref(as, scope, label_name, ref_offset);
}