From c75afbdcd611668e7f239dcfb4ab3846a82c0c8c Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Sun, 24 Nov 2024 13:47:56 +0100 Subject: Add subtraction tests --- bxgen.c | 333 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 285 insertions(+), 48 deletions(-) diff --git a/bxgen.c b/bxgen.c index 7e2dd05..6c711f8 100755 --- a/bxgen.c +++ b/bxgen.c @@ -103,7 +103,7 @@ #/ #/ ---------------------------------------------------------------- #/ -#/ (C) 2024 Mitya Selivanov , MIT License +#/ (C) 2024 Mitya Selivanov #/ #/ ================================================================ #/ @@ -298,8 +298,7 @@ typedef struct { Var ref; Ret ret; Call call; - Var add[2]; - Var sub[2]; + Var bin_op[2]; }; } Node; @@ -970,8 +969,8 @@ i64 node_data_i64(Pool *pool, i64 value) { i64 node_data_add(Pool *pool, Var x, Var y) { return node_init(pool, (Node) { - .op = DATA_ADD, - .add = { + .op = DATA_ADD, + .bin_op = { x, y, }, @@ -980,8 +979,8 @@ i64 node_data_add(Pool *pool, Var x, Var y) { i64 node_data_sub(Pool *pool, Var x, Var y) { return node_init(pool, (Node) { - .op = DATA_SUB, - .sub = { + .op = DATA_SUB, + .bin_op = { x, y, }, @@ -1945,8 +1944,8 @@ void x86_64_emit_node( case DATA_ADD: { // NOTE Assuming static single-assignment form. - Node *x = node_by_id(pool, n->add[0]); - Node *y = node_by_id(pool, n->add[1]); + Node *x = node_by_id(pool, n->bin_op[0]); + Node *y = node_by_id(pool, n->bin_op[1]); CHECK(x != NULL, "No node",); CHECK(y != NULL, "No node",); @@ -1970,8 +1969,9 @@ void x86_64_emit_node( codegen->offset_code += 5; } break; - case DATA_ADD: { - i64 src_reg = entities[n->add[0]].reg; + case DATA_ADD: + case DATA_SUB: { + i64 src_reg = entities[n->bin_op[0]].reg; switch (src_reg) { case 1: @@ -2000,7 +2000,6 @@ void x86_64_emit_node( codegen->offset_code += 2; break; - case 4: // edx @@ -2015,8 +2014,8 @@ void x86_64_emit_node( FAIL("Not implemented",); } - entities[n->add[0]].reg = 0; - proc->occupied_reg &= ~(1 << (src_reg - 1)); + entities[n->bin_op[0]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); } break; default: @@ -2034,7 +2033,7 @@ void x86_64_emit_node( } break; case DATA_ADD: { - i64 src_reg = entities[n->add[1]].reg; + i64 src_reg = entities[n->bin_op[1]].reg; switch (src_reg) { case 1: @@ -2083,8 +2082,8 @@ void x86_64_emit_node( FAIL("Not implemented",); } - entities[n->add[1]].reg = 0; - proc->occupied_reg &= ~(1 << (src_reg - 1)); + entities[n->bin_op[1]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); } break; default: @@ -2108,7 +2107,7 @@ void x86_64_emit_node( case DATA_ADD: case DATA_SUB: { - i64 src_reg = entities[n->add[0]].reg; + i64 src_reg = entities[n->bin_op[0]].reg; switch (src_reg) { case 1: @@ -2162,8 +2161,8 @@ void x86_64_emit_node( FAIL("Not implemented",); } - entities[n->add[0]].reg = 0; - proc->occupied_reg &= ~(1 << (src_reg - 1)); + entities[n->bin_op[0]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); } break; default: @@ -2182,7 +2181,7 @@ void x86_64_emit_node( } break; case DATA_ADD: { - i64 src_reg = entities[n->add[1]].reg; + i64 src_reg = entities[n->bin_op[1]].reg; switch (src_reg) { case 1: @@ -2233,8 +2232,8 @@ void x86_64_emit_node( FAIL("Not implemented",); } - entities[n->add[1]].reg = 0; - proc->occupied_reg &= ~(1 << (src_reg - 1)); + entities[n->bin_op[1]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); } break; default: @@ -2257,7 +2256,7 @@ void x86_64_emit_node( } break; case DATA_ADD: { - i64 src_reg = entities[n->add[0]].reg; + i64 src_reg = entities[n->bin_op[0]].reg; switch (src_reg) { case 1: @@ -2301,8 +2300,8 @@ void x86_64_emit_node( FAIL("Not implemented",); } - entities[n->add[0]].reg = 0; - proc->occupied_reg &= ~(1 << (src_reg - 1)); + entities[n->bin_op[0]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); } break; default: @@ -2321,7 +2320,7 @@ void x86_64_emit_node( } break; case DATA_ADD: { - i64 src_reg = entities[n->add[1]].reg; + i64 src_reg = entities[n->bin_op[1]].reg; switch (src_reg) { case 1: @@ -2372,8 +2371,8 @@ void x86_64_emit_node( FAIL("Not implemented",); } - entities[n->add[1]].reg = 0; - proc->occupied_reg &= ~(1 << (src_reg - 1)); + entities[n->bin_op[1]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); } break; default: @@ -2396,7 +2395,7 @@ void x86_64_emit_node( } break; case DATA_ADD: { - i64 src_reg = entities[n->add[0]].reg; + i64 src_reg = entities[n->bin_op[0]].reg; switch (src_reg) { case 1: @@ -2439,8 +2438,8 @@ void x86_64_emit_node( FAIL("Not implemented",); } - entities[n->add[0]].reg = 0; - proc->occupied_reg &= ~(1 << (src_reg - 1)); + entities[n->bin_op[0]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); } break; default: @@ -2459,7 +2458,7 @@ void x86_64_emit_node( } break; case DATA_ADD: { - i64 src_reg = entities[n->add[1]].reg; + i64 src_reg = entities[n->bin_op[1]].reg; switch (src_reg) { case 1: @@ -2508,8 +2507,8 @@ void x86_64_emit_node( FAIL("Not implemented",); } - entities[n->add[1]].reg = 0; - proc->occupied_reg &= ~(1 << (src_reg - 1)); + entities[n->bin_op[1]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); } break; default: @@ -2526,7 +2525,7 @@ void x86_64_emit_node( } break; case DATA_ADD: { - i64 src_reg = entities[n->add[0]].reg; + i64 src_reg = entities[n->bin_op[0]].reg; switch (src_reg) { case 1: @@ -2576,8 +2575,8 @@ void x86_64_emit_node( FAIL("Not implemented",); } - entities[n->add[0]].reg = 0; - proc->occupied_reg &= ~(1 << (src_reg - 1)); + entities[n->bin_op[0]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); } break; default: @@ -2590,7 +2589,7 @@ void x86_64_emit_node( } break; case DATA_ADD: { - i64 src_reg = entities[n->add[1]].reg; + i64 src_reg = entities[n->bin_op[1]].reg; switch (src_reg) { case 1: @@ -2641,8 +2640,8 @@ void x86_64_emit_node( FAIL("Not implemented",); } - entities[n->add[1]].reg = 0; - proc->occupied_reg &= ~(1 << (src_reg - 1)); + entities[n->bin_op[1]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); } break; default: @@ -2661,8 +2660,8 @@ void x86_64_emit_node( case DATA_SUB: { // NOTE Assuming static single-assignment form. - Node *x = node_by_id(pool, n->sub[0]); - Node *y = node_by_id(pool, n->sub[1]); + Node *x = node_by_id(pool, n->bin_op[0]); + Node *y = node_by_id(pool, n->bin_op[1]); CHECK(x != NULL, "No node",); CHECK(y != NULL, "No node",); @@ -2688,7 +2687,52 @@ void x86_64_emit_node( case DATA_ADD: case DATA_SUB: { - FAIL("Not implemented",); + i64 src_reg = entities[n->bin_op[0]].reg; + + switch (src_reg) { + case 1: + FAIL("Not implemented",); + // eax + break; + + case 2: + FAIL("Not implemented",); + // ebx + + write_u8(LE, 0x89, begin, end); // mov eax + write_u8(LE, 0xd8, begin + 1, end); // ebx + + begin += 2; + codegen->offset_code += 2; + break; + + case 3: + // ecx + + write_u8(LE, 0x89, begin, end); // mov eax + write_u8(LE, 0xc8, begin + 1, end); // ecx + + begin += 2; + codegen->offset_code += 2; + break; + + case 4: + FAIL("Not implemented",); + // edx + + write_u8(LE, 0x89, begin, end); // mov eax + write_u8(LE, 0xd0, begin + 1, end); // edx + + begin += 2; + codegen->offset_code += 2; + break; + + default: + FAIL("Not implemented",); + } + + entities[n->bin_op[0]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); } break; default: @@ -2731,7 +2775,7 @@ void x86_64_emit_node( case DATA_ADD: case DATA_SUB: { - i64 src_reg = entities[n->add[0]].reg; + i64 src_reg = entities[n->bin_op[0]].reg; switch (src_reg) { case 1: @@ -2762,6 +2806,7 @@ void x86_64_emit_node( case 4: + FAIL("Not implemented",); // edx write_u8(LE, 0x89, begin, end); // mov ebx @@ -2772,6 +2817,7 @@ void x86_64_emit_node( break; case 5: + FAIL("Not implemented",); // esi write_u8(LE, 0x89, begin, end); // mov ebx @@ -2785,8 +2831,8 @@ void x86_64_emit_node( FAIL("Not implemented",); } - entities[n->add[0]].reg = 0; - proc->occupied_reg &= ~(1 << (src_reg - 1)); + entities[n->bin_op[0]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); } break; default: @@ -2815,8 +2861,171 @@ void x86_64_emit_node( } break; case 3: { - FAIL("Not implemented",); // ecx + + switch (x->op) { + case DATA_I32: { + FAIL("Not implemented",); + + u32 val = CHUNK(pool, x->lit, u32)[0]; + + write_u8 (LE, 0xb9, begin, end); // mov ecx + write_u32(LE, val, begin + 1, end); + + begin += 5; + codegen->offset_code += 5; + } break; + + case DATA_ADD: + case DATA_SUB: { + i64 src_reg = entities[n->bin_op[0]].reg; + + switch (src_reg) { + case 1: + // eax + + write_u8(LE, 0x89, begin, end); // mov ecx + write_u8(LE, 0xc1, begin + 1, end); // eax + + begin += 2; + codegen->offset_code += 2; + break; + + case 2: + FAIL("Not implemented",); + // ebx + + write_u8(LE, 0x89, begin, end); // mov ecx + write_u8(LE, 0xd9, begin + 1, end); // ebx + + begin += 2; + codegen->offset_code += 2; + break; + + case 3: + FAIL("Not implemented",); + // ecx + break; + + + case 4: + FAIL("Not implemented",); + // edx + + write_u8(LE, 0x89, begin, end); // mov ecx + write_u8(LE, 0xd1, begin + 1, end); // edx + + begin += 2; + codegen->offset_code += 2; + break; + + case 5: + FAIL("Not implemented",); + // esi + + write_u8(LE, 0x89, begin, end); // mov ecx + write_u8(LE, 0xf1, begin + 1, end); // esi + + begin += 2; + codegen->offset_code += 2; + break; + + default: + FAIL("Not implemented",); + } + + entities[n->bin_op[0]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); + } break; + + default: + FAIL("Not implemented",); + } + + switch (y->op) { + case DATA_I32: { + FAIL("Not implemented",); + + u32 val = CHUNK(pool, y->lit, u32)[0]; + + write_u8 (LE, 0x81, begin, end); // sub ecx + write_u8 (LE, 0xe9, begin + 1, end); + write_u32(LE, val, begin + 2, end); + + codegen->offset_code += 6; + } break; + + case DATA_ADD: + case DATA_SUB: { + i64 src_reg = entities[n->bin_op[1]].reg; + + switch (src_reg) { + case 1: + FAIL("Not implemented",); + // eax + + write_u8(LE, 0x29, begin, end); // sub ecx + write_u8(LE, 0xc1, begin + 1, end); // eax + + begin += 2; + codegen->offset_code += 2; + break; + + case 2: + // ebx + + write_u8(LE, 0x29, begin, end); // sub ecx + write_u8(LE, 0xd9, begin + 1, end); // ebx + + begin += 2; + codegen->offset_code += 2; + break; + + case 3: + FAIL("Not implemented",); + // ecx + + write_u8(LE, 0x29, begin, end); // sub ecx + write_u8(LE, 0xc9, begin + 1, end); // ecx + + begin += 2; + codegen->offset_code += 2; + break; + + + case 4: + FAIL("Not implemented",); + // edx + + write_u8(LE, 0x29, begin, end); // sub ecx + write_u8(LE, 0xd1, begin + 1, end); // edx + + begin += 2; + codegen->offset_code += 2; + break; + + case 5: + FAIL("Not implemented",); + // esi + + write_u8(LE, 0x29, begin, end); // sub ecx + write_u8(LE, 0xf1, begin + 1, end); // esi + + begin += 2; + codegen->offset_code += 2; + break; + + default: + FAIL("Not implemented",); + } + + entities[n->bin_op[1]].reg = 0; + proc->occupied_reg &= ~(1 << (src_reg - 1)); + } break; + + default: + FAIL("Not implemented",); + } } break; case 4: { @@ -5600,6 +5809,32 @@ ADD_TEST_(math_sub_3, 3-2-1, ); ) +ADD_TEST_(math_sub_4, (4-3)-(2-1), + i64 mainproc = p_new_entry(u); + + i64 a = n_sub(mainproc, n_i32(mainproc, 4), n_i32(mainproc, 3)); + i64 b = n_sub(mainproc, n_i32(mainproc, 2), n_i32(mainproc, 1)); + + N_RET( + mainproc, + n_sub(mainproc, a, b) + ); +) + +ADD_TEST_(math_sub_5, ((5-3)-(1-4))-2, + i64 mainproc = p_new_entry(u); + + i64 a = n_sub(mainproc, n_i32(mainproc, 5), n_i32(mainproc, 3)); + i64 b = n_sub(mainproc, n_i32(mainproc, 1), n_i32(mainproc, 4)); + i64 c = n_i32(mainproc, 2); + i64 a_b = n_sub(mainproc, a, b); + + N_RET( + mainproc, + n_sub(mainproc, a_b, c) + ); +) + #endif // HELPERS i32 main(i32 argc, c8 **argv) { @@ -5678,6 +5913,8 @@ i32 main(i32 argc, c8 **argv) { RUN_TEST_(math_add_4b); RUN_TEST_(math_add_8); RUN_TEST_(math_sub_3); + RUN_TEST_(math_sub_4); + RUN_TEST_(math_sub_5); #endif #undef RUN_TEST_ -- cgit v1.2.3