diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2024-11-25 14:26:36 +0100 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2024-11-25 14:26:36 +0100 |
commit | 81cddda1e3975491298aff94015da538e152b869 (patch) | |
tree | 9f77bd33061a79316fe114a54848d58f744dc9b5 | |
parent | 5e6dddee0b116e50654ab5d6c87c5908da1b7b20 (diff) | |
download | bxgen-81cddda1e3975491298aff94015da538e152b869.zip |
Phi node
-rwxr-xr-x | bxgen.c | 151 | ||||
-rw-r--r-- | test_cond_1 | 0 |
2 files changed, 80 insertions, 71 deletions
@@ -209,10 +209,11 @@ enum { OP_OR, OP_XOR, OP_NOT, - OP_IF, OP_ADDRESS, OP_CALL, + OP_IF, OP_RET, + OP_PHI, // Calling conventions @@ -297,6 +298,11 @@ typedef struct { } Ret; typedef struct { + i64 branch; + Chunk_Handle vals; +} Phi; + +typedef struct { // NOTE // We may call a local procedure by it's id, // or a global procedure by name. @@ -315,17 +321,12 @@ typedef struct { i64 index_in_proc; union { Chunk_Handle lit; + Var bin_op[2]; Var ref; - struct { - i64 ctrl_previous; - i64 ctrl_index; - union { - If if_; - Ret ret; - Call call; - Var bin_op[2]; - }; - }; + Call call; + If if_; + Ret ret; + Phi phi; }; } Node; @@ -483,12 +484,13 @@ i64 node_data_i64 (Pool *pool, i64 value); i64 node_data_add (Pool *pool, Var x, Var y); i64 node_data_sub (Pool *pool, Var x, Var y); -i64 node_ctrl_call (Pool *pool, i64 previous, i64 index, i64 target_proc, i64 num_args, Var *args); -i64 node_ctrl_call_by_name(Pool *pool, i64 previous, i64 index, i64 name_size, c8 *name, i64 num_args, Var *args); -i64 node_ctrl_if (Pool *pool, i64 previous, i64 index, Var condition); -i64 node_ctrl_ret (Pool *pool, i64 previous, i64 index, i64 num_values, Var *values); +i64 node_ctrl_call (Pool *pool, i64 target_proc, i64 num_args, Var *args); +i64 node_ctrl_call_by_name(Pool *pool, i64 name_size, c8 *name, i64 num_args, Var *args); +i64 node_ctrl_if (Pool *pool, Var condition); +i64 node_ctrl_ret (Pool *pool, i64 num_values, Var *values); +i64 node_ctrl_phi (Pool *pool, i64 branch, i64 num_vals, Var *vals); -i64 proc_initi (Pool *pool); +i64 proc_init (Pool *pool); void proc_destroy (Pool *pool, i64 proc); void proc_set_convention(Pool *pool, i64 proc, u16 convention); void proc_set_name (Pool *pool, i64 proc, i64 name_size, c8 *name); @@ -531,10 +533,11 @@ i64 n_i64(i64 proc, i64 value); i64 n_add(i64 proc, Var x, Var y); i64 n_sub(i64 proc, Var x, Var y); -i64 n_call (i64 proc, i64 ctrl_previous, i64 ctrl_index, i64 target_proc, i64 num_args, Var *args); -i64 n_call_by_name(i64 proc, i64 ctrl_previous, i64 ctrl_index, c8 *name, i64 num_args, Var *args); -i64 n_if (i64 proc, i64 ctrl_previous, i64 ctrl_index, Var condition); -i64 n_ret (i64 proc, i64 ctrl_previous, i64 ctrl_index, i64 num_vals, Var *vals); +i64 n_call (i64 proc, i64 target_proc, i64 num_args, Var *args); +i64 n_call_by_name(i64 proc, c8 *name, i64 num_args, Var *args); +i64 n_if (i64 proc, Var condition); +i64 n_ret (i64 proc, i64 num_vals, Var *vals); +i64 n_phi (i64 proc, i64 branch, i64 num_vals, Var *vals); i64 p_new(i64 unit, c8 *name); i64 p_new_entry(i64 unit); @@ -553,9 +556,10 @@ c8 * l_find(c8 *name, b8 silent); #define ARGS(...) \ (sizeof((Var[]) { __VA_ARGS__ }) / sizeof(Var)), \ (Var[]) { __VA_ARGS__ } -#define N_CALL(proc, prev_, index_, target_proc, ...) n_call ((proc), (prev_), (index_), (target_proc), ARGS(__VA_ARGS__)) -#define N_CALL_BY_NAME(proc, prev_, index_, name, ...) n_call_by_name((proc), (prev_), (index_), (name), ARGS(__VA_ARGS__)) -#define N_RET(proc, prev_, index_, ...) n_ret ((proc), (prev_), (index_), ARGS(__VA_ARGS__)) +#define N_CALL(proc, target_proc, ...) n_call ((proc), (target_proc), ARGS(__VA_ARGS__)) +#define N_CALL_BY_NAME(proc, name, ...) n_call_by_name((proc), (name), ARGS(__VA_ARGS__)) +#define N_RET(proc, ...) n_ret ((proc), ARGS(__VA_ARGS__)) +#define N_PHI(proc, branch, ...) n_phi ((proc), (branch), ARGS(__VA_ARGS__)) #endif @@ -1044,11 +1048,9 @@ u16 resolve_calling_convention(Pool *pool, i64 proc) { return p->convention; } -i64 node_ctrl_call(Pool *pool, i64 previous, i64 index, i64 target_proc, i64 num_args, Var *args) { +i64 node_ctrl_call(Pool *pool, i64 target_proc, i64 num_args, Var *args) { return node_init(pool, (Node) { - .op = OP_CALL, - .ctrl_previous = previous, - .ctrl_index = index, + .op = OP_CALL, .call = { .convention = resolve_calling_convention(pool, target_proc), .target_proc = target_proc, @@ -1057,11 +1059,9 @@ i64 node_ctrl_call(Pool *pool, i64 previous, i64 index, i64 target_proc, i64 num }); } -i64 node_ctrl_call_by_name(Pool *pool, i64 previous, i64 index, i64 name_size, c8 *name, i64 num_args, Var *args) { +i64 node_ctrl_call_by_name(Pool *pool, i64 name_size, c8 *name, i64 num_args, Var *args) { return node_init(pool, (Node) { - .op = OP_CALL, - .ctrl_previous = previous, - .ctrl_index = index, + .op = OP_CALL, .call = { .convention = CONV_CDECL, .target_proc = UNDEFINED, @@ -1071,28 +1071,34 @@ i64 node_ctrl_call_by_name(Pool *pool, i64 previous, i64 index, i64 name_size, c }); } -i64 node_ctrl_if(Pool *pool, i64 previous, i64 index, Var condition) { +i64 node_ctrl_if(Pool *pool, Var condition) { return node_init(pool, (Node) { - .op = OP_IF, - .ctrl_previous = previous, - .ctrl_index = index, + .op = OP_IF, .if_ = { .condition = condition, }, }); } -i64 node_ctrl_ret(Pool *pool, i64 previous, i64 index, i64 num_values, Var *values) { +i64 node_ctrl_ret(Pool *pool, i64 num_values, Var *values) { return node_init(pool, (Node) { - .op = OP_RET, - .ctrl_previous = previous, - .ctrl_index = index, + .op = OP_RET, .ret = { .vals = chunk_add(pool, num_values * sizeof *values, values), }, }); } +i64 node_ctrl_phi(Pool *pool, i64 branch, i64 num_vals, Var *vals) { + return node_init(pool, (Node) { + .op = OP_PHI, + .phi = { + .branch = branch, + .vals = chunk_add(pool, num_vals *sizeof *vals, vals), + }, + }); +} + i64 proc_init(Pool *pool) { return pool_add(pool, (Entity) { .type = ENTITY_PROC, @@ -2550,6 +2556,10 @@ b8 x86_64_emit_node( } } break; + case OP_IF: { + FAIL("Not implemented", 0); + } break; + case OP_RET: { u8 *begin = CHUNK(pool, codegen->buffer_code, u8) + codegen->offset_code; u8 *end = begin + codegen->buffer_code.size; @@ -2677,6 +2687,10 @@ b8 x86_64_emit_node( } } break; + case OP_PHI: { + FAIL("Not implemented", 0); + } break; + default: FAIL("Unknown operation", 0); } @@ -4753,26 +4767,32 @@ i64 n_sub(i64 proc, Var x, Var y) { return n; } -i64 n_call(i64 proc, i64 ctrl_previous, i64 ctrl_index, i64 target_proc, i64 num_args, Var *args) { - i64 n = node_ctrl_call(&g_pool, ctrl_previous, ctrl_index, target_proc, num_args, args); +i64 n_call(i64 proc, i64 target_proc, i64 num_args, Var *args) { + i64 n = node_ctrl_call(&g_pool, target_proc, num_args, args); + p_add(proc, n); + return n; +} + +i64 n_call_by_name(i64 proc, c8 *name, i64 num_args, Var *args) { + i64 n = node_ctrl_call_by_name(&g_pool, str_len(name, name + MAX_STRING_SIZE), name, num_args, args); p_add(proc, n); return n; } -i64 n_call_by_name(i64 proc, i64 ctrl_previous, i64 ctrl_index, c8 *name, i64 num_args, Var *args) { - i64 n = node_ctrl_call_by_name(&g_pool, ctrl_previous, ctrl_index, str_len(name, name + MAX_STRING_SIZE), name, num_args, args); +i64 n_if(i64 proc, Var condition) { + i64 n = node_ctrl_if(&g_pool, condition); p_add(proc, n); return n; } -i64 n_if(i64 proc, i64 ctrl_previous, i64 ctrl_index, Var condition) { - i64 n = node_ctrl_if(&g_pool, ctrl_previous, ctrl_index, condition); +i64 n_ret(i64 proc, i64 num_vals, Var *vals) { + i64 n = node_ctrl_ret(&g_pool, num_vals, vals); p_add(proc, n); return n; } -i64 n_ret(i64 proc, i64 ctrl_previous, i64 ctrl_index, i64 num_vals, Var *vals) { - i64 n = node_ctrl_ret(&g_pool, ctrl_previous, ctrl_index, num_vals, vals); +i64 n_phi(i64 proc, i64 branch, i64 num_vals, Var *vals) { + i64 n = node_ctrl_phi(&g_pool, branch, num_vals, vals); p_add(proc, n); return n; } @@ -4955,7 +4975,6 @@ ADD_TEST_(link_with_libc, 42, // Call puts N_CALL_BY_NAME( p, - 0, 0, "puts", // proc name n_str(p, "hello sailor") // the first argument ); @@ -4963,7 +4982,6 @@ ADD_TEST_(link_with_libc, 42, // Return 42 N_RET( p, - 0, 0, n_i32(p, 42) // the return value ); } @@ -4982,7 +5000,6 @@ ADD_TEST_(math_two_plus_two, 4, N_RET( p, - 0, 0, n_add(p, n_i32(p, 2), n_i32(p, 2)) ); ) @@ -4992,7 +5009,6 @@ ADD_TEST_(math_sixty_nine, 69, N_RET( p, - 0, 0, n_add(p, n_i32(p, 27), n_i32(p, 42)) ); ) @@ -5005,7 +5021,6 @@ ADD_TEST_(math_add_3, 1+2+3, N_RET( p, - 0, 0, n_add(p, a, b) ); ) @@ -5018,7 +5033,6 @@ ADD_TEST_(math_add_4a, 1+2+3+4, N_RET( p, - 0, 0, n_add(p, a, b) ); ) @@ -5033,7 +5047,6 @@ ADD_TEST_(math_add_5, 1+2+3+4+5, N_RET( p, - 0, 0, n_add(p, a_b, c) ); ) @@ -5048,7 +5061,6 @@ ADD_TEST_(math_add_6, 1+2+3+4+5+6, N_RET( p, - 0, 0, n_add(p, a_b, c) ); ) @@ -5065,7 +5077,6 @@ ADD_TEST_(math_add_7, 1+2+3+4+5+6+7, N_RET( p, - 0, 0, n_add(p, a_b, c_d) ); ) @@ -5083,7 +5094,6 @@ ADD_TEST_(math_add_4b, 5+6+7+8, N_RET( p, - 0, 0, c_d ); ) @@ -5100,7 +5110,6 @@ ADD_TEST_(math_add_8, 1+2+3+4+5+6+7+8, N_RET( p, - 0, 0, n_add(p, a_b, c_d) ); ) @@ -5113,7 +5122,6 @@ ADD_TEST_(math_sub_3, 3-2-1, N_RET( p, - 0, 0, n_sub(p, a, b) ); ) @@ -5126,7 +5134,6 @@ ADD_TEST_(math_sub_4, (4-3)-(2-1), N_RET( p, - 0, 0, n_sub(p, a, b) ); ) @@ -5141,7 +5148,6 @@ ADD_TEST_(math_sub_5, ((5-3)-(1-4))-2, N_RET( p, - 0, 0, n_sub(p, a_b, c) ); ) @@ -5156,7 +5162,6 @@ ADD_TEST_(math_sub_6, ((6-1)-(5-4))-(3-2), N_RET( p, - 0, 0, n_sub(p, a_b, c) ); ) @@ -5173,7 +5178,6 @@ ADD_TEST_(math_sub_7, ((7-2)-(2-3))-((4-5)-1), N_RET( p, - 0, 0, n_sub(p, a_b, c_d) ); ) @@ -5190,7 +5194,6 @@ ADD_TEST_(math_sub_8, ((8-1)-(2-3))-((4-5)-(7-6)), N_RET( p, - 0, 0, n_sub(p, a_b, c_d) ); ) @@ -5209,25 +5212,29 @@ ADD_TEST_(math_reg_reuse, (1+2+3+4+5+6+7+8+9+10), i64 i = n_add(p, h, n_i32(p, 9)); i64 j = n_add(p, i, n_i32(p, 10)); - N_RET(p, 0, 0, j); + N_RET(p, j); ) ADD_TEST_(cond_1, 1, i64 p = p_new_entry(u); i64 a = n_i32(p, 1); - i64 b = n_if(p, 0, 0, a); - N_RET(p, b, 0, 1); - N_RET(p, b, 1, 2); + i64 b = n_if(p, a); + i64 c = n_i32(p, 1); + i64 d = n_i32(p, 2); + i64 e = N_PHI(p, b, c, d); + N_RET(p, e); ) ADD_TEST_(cond_2, 2, i64 p = p_new_entry(u); i64 a = n_i32(p, 0); - i64 b = n_if(p, 0, 0, a); - N_RET(p, b, 0, 1); - N_RET(p, b, 1, 2); + i64 b = n_if(p, a); + i64 c = n_i32(p, 1); + i64 d = n_i32(p, 2); + i64 e = N_PHI(p, b, c, d); + N_RET(p, e); ) #endif // HELPERS @@ -5314,6 +5321,8 @@ i32 main(i32 argc, c8 **argv) { RUN_TEST_(math_sub_7); RUN_TEST_(math_sub_8); RUN_TEST_(math_reg_reuse); + // RUN_TEST_(cond_1); + // RUN_TEST_(cond_2); #endif #undef RUN_TEST_ diff --git a/test_cond_1 b/test_cond_1 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test_cond_1 |