summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2024-11-24 13:47:56 +0100
committerMitya Selivanov <automainint@guattari.tech>2024-11-24 13:47:56 +0100
commitc75afbdcd611668e7f239dcfb4ab3846a82c0c8c (patch)
tree23e17ff84d994d8e083584a9c02542438d03e0f5
parent46a3f595a4f86acbf6abc47e177327416ff498a6 (diff)
downloadbxgen-c75afbdcd611668e7f239dcfb4ab3846a82c0c8c.zip
Add subtraction tests
-rwxr-xr-xbxgen.c333
1 files 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 <guattari.tech>, MIT License
+#/ (C) 2024 Mitya Selivanov <guattari.tech>
#/
#/ ================================================================
#/
@@ -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_