mirror of
https://github.com/danog/ir.git
synced 2025-01-21 13:11:16 +01:00
Allow code generation for functions with unesolved symbols
This commit is contained in:
parent
2c67a3ac86
commit
6898d26e80
@ -1172,8 +1172,16 @@ static void ir_emit_load(ir_ctx *ctx, ir_type type, ir_reg reg, ir_ref src)
|
||||
if (IR_IS_TYPE_INT(type)) {
|
||||
ir_insn *insn = &ctx->ir_base[src];
|
||||
|
||||
IR_ASSERT(insn->op != IR_STR && insn->op != IR_SYM && insn->op != IR_FUNC);
|
||||
ir_emit_load_imm_int(ctx, type, reg, insn->val.i64);
|
||||
if (insn->op == IR_SYM || insn->op == IR_FUNC) {
|
||||
void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
|
||||
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, insn->val.name)) :
|
||||
ir_resolve_sym_name(ir_get_str(ctx, insn->val.name));
|
||||
IR_ASSERT(addr);
|
||||
ir_emit_load_imm_int(ctx, type, reg, (intptr_t)addr);
|
||||
} else {
|
||||
IR_ASSERT(insn->op != IR_STR);
|
||||
ir_emit_load_imm_int(ctx, type, reg, insn->val.i64);
|
||||
}
|
||||
} else {
|
||||
ir_emit_load_imm_fp(ctx, type, reg, src);
|
||||
}
|
||||
@ -4306,6 +4314,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
|
||||
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, val_insn->val.name)) :
|
||||
ir_resolve_sym_name(ir_get_str(ctx, val_insn->val.name));
|
||||
IR_ASSERT(addr);
|
||||
ir_emit_load_imm_int(ctx, IR_ADDR, dst_reg, (intptr_t)addr);
|
||||
continue;
|
||||
}
|
||||
@ -4335,6 +4344,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
|
||||
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, val_insn->val.name)) :
|
||||
ir_resolve_sym_name(ir_get_str(ctx, val_insn->val.name));
|
||||
IR_ASSERT(addr);
|
||||
ir_emit_load_imm_int(ctx, IR_ADDR, tmp_reg, (intptr_t)addr);
|
||||
| str Rx(tmp_reg), [sp, #stack_offset]
|
||||
} else {
|
||||
@ -4387,6 +4397,7 @@ static void ir_emit_call_ex(ir_ctx *ctx, ir_ref def, ir_insn *insn, int32_t used
|
||||
addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
|
||||
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, addr_insn->val.name)) :
|
||||
ir_resolve_sym_name(ir_get_str(ctx, addr_insn->val.name));
|
||||
IR_ASSERT(addr);
|
||||
} else {
|
||||
IR_ASSERT(addr_insn->op == IR_ADDR || addr_insn->op == IR_FUNC_ADDR);
|
||||
addr = (void*)addr_insn->val.addr;
|
||||
@ -4472,6 +4483,7 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
|
||||
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, addr_insn->val.name)) :
|
||||
ir_resolve_sym_name(ir_get_str(ctx, addr_insn->val.name));
|
||||
IR_ASSERT(addr);
|
||||
} else {
|
||||
IR_ASSERT(addr_insn->op == IR_ADDR || addr_insn->op == IR_FUNC_ADDR);
|
||||
addr = (void*)addr_insn->val.addr;
|
||||
@ -4855,6 +4867,7 @@ static void ir_emit_exitcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
|
||||
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, addr_insn->val.name)) :
|
||||
ir_resolve_sym_name(ir_get_str(ctx, addr_insn->val.name));
|
||||
IR_ASSERT(addr);
|
||||
} else {
|
||||
IR_ASSERT(addr_insn->op == IR_ADDR || addr_insn->op == IR_FUNC_ADDR);
|
||||
addr = (void*)addr_insn->val.addr;
|
||||
|
@ -337,6 +337,7 @@ static void *ir_jmp_addr(ir_ctx *ctx, ir_insn *insn, ir_insn *addr_insn)
|
||||
addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
|
||||
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, addr_insn->val.name)) :
|
||||
ir_resolve_sym_name(ir_get_str(ctx, addr_insn->val.name));
|
||||
IR_ASSERT(addr);
|
||||
} else {
|
||||
IR_ASSERT(addr_insn->op == IR_ADDR || addr_insn->op == IR_FUNC_ADDR);
|
||||
addr = (void*)addr_insn->val.addr;
|
||||
|
19
ir_main.c
19
ir_main.c
@ -231,6 +231,7 @@ int ir_compile_func(ir_ctx *ctx, int opt_level, uint32_t dump, FILE *dump_file,
|
||||
|
||||
typedef struct _ir_sym {
|
||||
void *addr;
|
||||
void *thunk_addr;
|
||||
} ir_sym;
|
||||
|
||||
typedef struct _ir_main_loader {
|
||||
@ -265,6 +266,9 @@ static bool ir_loader_add_sym(ir_loader *loader, const char *name, void *addr)
|
||||
if (addr && !l->sym[old_val].addr) {
|
||||
/* Update forward declaration */
|
||||
l->sym[old_val].addr = addr;
|
||||
if (l->sym[old_val].thunk_addr) {
|
||||
// TODO: Fix thunk or relocation ???
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -274,6 +278,7 @@ static bool ir_loader_add_sym(ir_loader *loader, const char *name, void *addr)
|
||||
l->sym = ir_mem_realloc(l->sym, sizeof(ir_sym) * l->sym_count);
|
||||
}
|
||||
l->sym[val].addr = addr;
|
||||
l->sym[val].thunk_addr = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -293,7 +298,15 @@ static void* ir_loader_resolve_sym_name(ir_loader *loader, const char *name)
|
||||
void *addr;
|
||||
|
||||
if (val) {
|
||||
return l->sym[val].addr;
|
||||
if (l->sym[val].addr) {
|
||||
return l->sym[val].addr;
|
||||
}
|
||||
if (!l->sym[val].thunk_addr) {
|
||||
/* Undefined declaration */
|
||||
// TODO: Add thunk or relocation ???
|
||||
l->sym[val].thunk_addr = (void*)(intptr_t)sizeof(void*);
|
||||
}
|
||||
return l->sym[val].thunk_addr;
|
||||
}
|
||||
addr = ir_resolve_sym_name(name);
|
||||
ir_loader_add_sym(loader, name, addr); /* cache */
|
||||
@ -312,11 +325,9 @@ static bool ir_loader_external_sym_dcl(ir_loader *loader, const char *name, uint
|
||||
fprintf(l->dump_file, "extern %s %s;\n", (flags & IR_CONST) ? "const" : "var", name);
|
||||
}
|
||||
if (l->c_file) {
|
||||
// TODO:
|
||||
ir_emit_c_sym_decl(name, flags | IR_EXTERN, 0, l->c_file);
|
||||
}
|
||||
if (l->llvm_file) {
|
||||
// TODO:
|
||||
ir_emit_llvm_sym_decl(name, flags | IR_EXTERN, 0, l->llvm_file);
|
||||
}
|
||||
if (l->dump_asm || l->dump_size || l->run) {
|
||||
@ -430,11 +441,9 @@ static bool ir_loader_sym_dcl(ir_loader *loader, const char *name, uint32_t flag
|
||||
fprintf(l->dump_file, "%s %s [%ld]%s\n", (flags & IR_CONST) ? "const" : "var", name, size, has_data ? " = {" : ";");
|
||||
}
|
||||
if (l->c_file) {
|
||||
// TODO:
|
||||
ir_emit_c_sym_decl(name, flags, has_data, l->c_file);
|
||||
}
|
||||
if (l->llvm_file) {
|
||||
// TODO:
|
||||
ir_emit_llvm_sym_decl(name, flags, has_data, l->llvm_file);
|
||||
}
|
||||
if (l->dump_asm || l->dump_size || l->run) {
|
||||
|
16
ir_x86.dasc
16
ir_x86.dasc
@ -2145,8 +2145,16 @@ static void ir_emit_load(ir_ctx *ctx, ir_type type, ir_reg reg, ir_ref src)
|
||||
if (IR_IS_TYPE_INT(type)) {
|
||||
ir_insn *insn = &ctx->ir_base[src];
|
||||
|
||||
IR_ASSERT(insn->op != IR_STR && insn->op != IR_SYM && insn->op != IR_FUNC);
|
||||
ir_emit_load_imm_int(ctx, type, reg, insn->val.i64);
|
||||
if (insn->op == IR_SYM || insn->op == IR_FUNC) {
|
||||
void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
|
||||
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, insn->val.name)) :
|
||||
ir_resolve_sym_name(ir_get_str(ctx, insn->val.name));
|
||||
IR_ASSERT(addr);
|
||||
ir_emit_load_imm_int(ctx, type, reg, (intptr_t)addr);
|
||||
} else {
|
||||
IR_ASSERT(insn->op != IR_STR);
|
||||
ir_emit_load_imm_int(ctx, type, reg, insn->val.i64);
|
||||
}
|
||||
} else {
|
||||
ir_emit_load_imm_fp(ctx, type, reg, src);
|
||||
}
|
||||
@ -7154,6 +7162,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
|
||||
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, val_insn->val.name)) :
|
||||
ir_resolve_sym_name(ir_get_str(ctx, val_insn->val.name));
|
||||
IR_ASSERT(addr);
|
||||
if (sizeof(void*) == 4 || IR_IS_SIGNED_32BIT(addr)) {
|
||||
| mov Ra(dst_reg), ((ptrdiff_t)addr)
|
||||
} else {
|
||||
@ -7232,6 +7241,7 @@ static int32_t ir_emit_arguments(ir_ctx *ctx, ir_ref def, ir_insn *insn, ir_reg
|
||||
void *addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
|
||||
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, val_insn->val.name)) :
|
||||
ir_resolve_sym_name(ir_get_str(ctx, val_insn->val.name));
|
||||
IR_ASSERT(addr);
|
||||
if (sizeof(void*) == 4) {
|
||||
| mov aword [Ra(IR_REG_RSP)+stack_offset], ((ptrdiff_t)addr)
|
||||
|.if X64
|
||||
@ -7351,6 +7361,7 @@ static void ir_emit_call_ex(ir_ctx *ctx, ir_ref def, ir_insn *insn, int32_t used
|
||||
addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
|
||||
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, addr_insn->val.name)) :
|
||||
ir_resolve_sym_name(ir_get_str(ctx, addr_insn->val.name));
|
||||
IR_ASSERT(addr);
|
||||
} else {
|
||||
IR_ASSERT(addr_insn->op == IR_ADDR || addr_insn->op == IR_FUNC_ADDR);
|
||||
addr = (void*)addr_insn->val.addr;
|
||||
@ -7505,6 +7516,7 @@ static void ir_emit_tailcall(ir_ctx *ctx, ir_ref def, ir_insn *insn)
|
||||
addr = (ctx->loader && ctx->loader->resolve_sym_name) ?
|
||||
ctx->loader->resolve_sym_name(ctx->loader, ir_get_str(ctx, addr_insn->val.name)) :
|
||||
ir_resolve_sym_name(ir_get_str(ctx, addr_insn->val.name));
|
||||
IR_ASSERT(addr);
|
||||
} else {
|
||||
IR_ASSERT(addr_insn->op == IR_ADDR || addr_insn->op == IR_FUNC_ADDR);
|
||||
addr = (void*)addr_insn->val.addr;
|
||||
|
Loading…
x
Reference in New Issue
Block a user