1
0
mirror of https://github.com/janet-lang/janet synced 2024-11-18 06:34:48 +00:00

More work on sysir.

This commit is contained in:
Calvin Rose 2024-06-07 10:09:53 -05:00
parent 25b7c74089
commit 3e273ce03a

View File

@ -27,6 +27,10 @@
#include "vector.h"
#endif
/*
* Wrap stuff up in a context struct
*/
static uint32_t v2reg(JanetTable *assignments, uint32_t var) {
return (uint32_t) janet_unwrap_number(janet_table_get(assignments, janet_wrap_number(var)));
}
@ -167,23 +171,8 @@ JanetSysSpill *assign_registers(JanetSysIR *ir, JanetTable *assignments,
return spills;
}
void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetBuffer *buffer) {
/* Do register allocation */
for (int32_t i = 0; i < linkage->ir_ordered->count; i++) {
JanetSysIR *ir = janet_unwrap_pointer(linkage->ir_ordered->data[i]);
JanetTable *assignments = janet_table(0);
JanetSysSpill *spills = assign_registers(ir, assignments, 15);
/* Emit prelude */
if (ir->link_name != NULL) {
janet_formatb(buffer, ".%s\n", ir->link_name);
} else {
janet_formatb(buffer, "._section_%d\n", i);
}
for (uint32_t j = 0; j < ir->instruction_count; j++) {
JanetSysInstruction instruction = ir->instructions[j];
JanetSysSpill spill = spills[j];
static void do_spills(JanetBuffer *buffer, JanetSysSpill *spills, uint32_t index) {
JanetSysSpill spill = spills[index];
for (int spi = 0; spi < 3; spi++) {
if (spill.spills[spi] == JANET_SYS_SPILL_READ || spill.spills[spi] == JANET_SYS_SPILL_BOTH) {
// emit load
@ -198,6 +187,25 @@ void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetBuffer *buffer)
janet_formatb(buffer, "store r%u to %v ; SPILL\n", reg, janet_wrap_pointer(x));
}
}
}
void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetBuffer *buffer) {
/* Do register allocation */
for (int32_t i = 0; i < linkage->ir_ordered->count; i++) {
JanetSysIR *ir = janet_unwrap_pointer(linkage->ir_ordered->data[i]);
JanetTable *assignments = janet_table(0);
/* 16 total 64 bit registers - 3 temp */
JanetSysSpill *spills = assign_registers(ir, assignments, 13);
/* Emit prelude */
if (ir->link_name != NULL) {
janet_formatb(buffer, ".%s\n", ir->link_name);
} else {
janet_formatb(buffer, "._section_%d\n", i);
}
for (uint32_t j = 0; j < ir->instruction_count; j++) {
JanetSysInstruction instruction = ir->instructions[j];
switch (instruction.opcode) {
default:
janet_formatb(buffer, "; nyi: %s\n", janet_sysop_names[instruction.opcode]);
@ -216,6 +224,7 @@ void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetBuffer *buffer)
case JANET_SYSOP_SUBTRACT:
case JANET_SYSOP_MULTIPLY:
case JANET_SYSOP_DIVIDE:
do_spills(buffer, spills, j);
janet_formatb(buffer, "r%u = %s r%u, r%u\n",
v2reg(assignments, instruction.three.dest),
janet_sysop_names[instruction.opcode],
@ -223,24 +232,50 @@ void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetBuffer *buffer)
v2reg(assignments, instruction.three.rhs));
break;
case JANET_SYSOP_MOVE:
do_spills(buffer, spills, j);
janet_formatb(buffer, "r%u = r%u\n",
v2reg(assignments, instruction.two.dest),
v2reg(assignments, instruction.two.src));
break;
case JANET_SYSOP_RETURN:
do_spills(buffer, spills, j);
janet_formatb(buffer, "return r%u\n",
v2reg(assignments, instruction.one.src));
break;
case JANET_SYSOP_CONSTANT:
do_spills(buffer, spills, j);
janet_formatb(buffer, "r%u = constant $%v\n",
v2reg(assignments, instruction.constant.dest),
ir->constants[instruction.constant.constant]);
break;
case JANET_SYSOP_LABEL:
janet_formatb(buffer, ":label_%u\n",
do_spills(buffer, spills, j);
janet_formatb(buffer, "label_%u:\n",
v2reg(assignments, instruction.label.id));
break;
case JANET_SYSOP_EQ:
case JANET_SYSOP_NEQ:
case JANET_SYSOP_LT:
case JANET_SYSOP_LTE:
case JANET_SYSOP_GT:
case JANET_SYSOP_GTE:
do_spills(buffer, spills, j);
janet_formatb(buffer, "r%u = %s r%u, r%u\n",
v2reg(assignments, instruction.three.dest),
janet_sysop_names[instruction.opcode],
v2reg(assignments, instruction.three.lhs),
v2reg(assignments, instruction.three.rhs));
break;
case JANET_SYSOP_BRANCH:
case JANET_SYSOP_BRANCH_NOT:
do_spills(buffer, spills, j);
janet_formatb(buffer, "branch label_%u if r%u\n",
instruction.branch.to,
v2reg(assignments, instruction.branch.cond));
break;
case JANET_SYSOP_CALLK:
do_spills(buffer, spills, j);
break;
// On a comparison, if next instruction is branch that reads from dest, combine into a single op.
}
}