mirror of
https://github.com/janet-lang/janet
synced 2024-11-16 05:34:48 +00:00
More work on register allocation and spilling.
Setup frontend.janet to show the basics of what is going on. Currently emitting "fake" instructions just to hash out the idea. One apparent issue is how we handle register spilling during variable argument IR instructions (function calls). Arguments should come _before_ the function call not after.
This commit is contained in:
parent
9e47cd94bd
commit
25b7c74089
1
Makefile
1
Makefile
@ -159,6 +159,7 @@ JANET_CORE_SOURCES=src/core/abstract.c \
|
||||
src/core/struct.c \
|
||||
src/core/symcache.c \
|
||||
src/core/sysir.c \
|
||||
src/core/sysir_x86.c \
|
||||
src/core/table.c \
|
||||
src/core/tuple.c \
|
||||
src/core/util.c \
|
||||
|
@ -356,6 +356,16 @@
|
||||
[]
|
||||
(eprintf "%.99M\n" (sysir/to-ir ctx)))
|
||||
|
||||
(defn dumpx64
|
||||
[]
|
||||
(print (sysir/to-x64 ctx)))
|
||||
|
||||
(defn dumpc
|
||||
[]
|
||||
(print (sysir/to-c ctx)))
|
||||
|
||||
####
|
||||
|
||||
(compile1 myprog)
|
||||
#(dump)
|
||||
(dumpx64)
|
||||
|
@ -142,6 +142,7 @@ core_src = [
|
||||
'src/core/struct.c',
|
||||
'src/core/symcache.c',
|
||||
'src/core/sysir.c',
|
||||
'src/core/sysir_x86.c',
|
||||
'src/core/table.c',
|
||||
'src/core/tuple.c',
|
||||
'src/core/util.c',
|
||||
|
@ -1839,12 +1839,23 @@ JANET_CORE_FN(cfun_sysir_toir,
|
||||
return janet_wrap_array(array);
|
||||
}
|
||||
|
||||
JANET_CORE_FN(cfun_sysir_tox64,
|
||||
"(sysir/to-x64 context &opt buffer options)",
|
||||
"Lower IR to x64 machine code.") {
|
||||
janet_arity(argc, 1, 3);
|
||||
JanetSysIRLinkage *ir = janet_getabstract(argv, 0, &janet_sysir_context_type);
|
||||
JanetBuffer *buffer = janet_optbuffer(argv, argc, 1, 0);
|
||||
janet_sys_ir_lower_to_x64(ir, buffer);
|
||||
return janet_wrap_buffer(buffer);
|
||||
}
|
||||
|
||||
void janet_lib_sysir(JanetTable *env) {
|
||||
JanetRegExt cfuns[] = {
|
||||
JANET_CORE_REG("sysir/context", cfun_sysir_context),
|
||||
JANET_CORE_REG("sysir/asm", cfun_sysir_asm),
|
||||
JANET_CORE_REG("sysir/to-c", cfun_sysir_toc),
|
||||
JANET_CORE_REG("sysir/to-ir", cfun_sysir_toir),
|
||||
JANET_CORE_REG("sysir/to-x64", cfun_sysir_tox64),
|
||||
JANET_REG_END
|
||||
};
|
||||
janet_core_cfuns_ext(env, NULL, cfuns);
|
||||
|
@ -170,11 +170,17 @@ JanetSysSpill *assign_registers(JanetSysIR *ir, JanetTable *assignments,
|
||||
void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetBuffer *buffer) {
|
||||
|
||||
/* Do register allocation */
|
||||
for (int32_t i = 0; i < janet_v_count(linkage->irs); i++) {
|
||||
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];
|
||||
@ -183,21 +189,29 @@ void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetBuffer *buffer)
|
||||
// emit load
|
||||
uint32_t reg = spill.regs[spi];
|
||||
void *x = (void *) 0x123456;
|
||||
janet_formatb(buffer, "load r%u from %p\n", reg, x);
|
||||
janet_formatb(buffer, "load r%u from %v ; SPILL\n", reg, janet_wrap_pointer(x));
|
||||
}
|
||||
if (spill.spills[spi] == JANET_SYS_SPILL_WRITE || spill.spills[spi] == JANET_SYS_SPILL_BOTH) {
|
||||
// emit store
|
||||
uint32_t reg = spill.regs[spi];
|
||||
void *x = (void *) 0x123456;
|
||||
janet_formatb(buffer, "store r%u to %p\n", reg, x);
|
||||
janet_formatb(buffer, "store r%u to %v ; SPILL\n", reg, janet_wrap_pointer(x));
|
||||
}
|
||||
}
|
||||
switch (instruction.opcode) {
|
||||
default:
|
||||
janet_formatb(buffer, "; nyi: %s\n", janet_sysop_names[instruction.opcode]);
|
||||
break;
|
||||
case JANET_SYSOP_TYPE_PRIMITIVE:
|
||||
case JANET_SYSOP_TYPE_UNION:
|
||||
case JANET_SYSOP_TYPE_STRUCT:
|
||||
case JANET_SYSOP_TYPE_BIND:
|
||||
case JANET_SYSOP_TYPE_ARRAY:
|
||||
case JANET_SYSOP_TYPE_POINTER:
|
||||
/* Non synthesized instructions */
|
||||
break;
|
||||
case JANET_SYSOP_POINTER_ADD:
|
||||
case JANET_SYSOP_POINTER_SUBTRACT:
|
||||
break;
|
||||
case JANET_SYSOP_ADD:
|
||||
case JANET_SYSOP_SUBTRACT:
|
||||
case JANET_SYSOP_MULTIPLY:
|
||||
@ -208,6 +222,24 @@ void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetBuffer *buffer)
|
||||
v2reg(assignments, instruction.three.lhs),
|
||||
v2reg(assignments, instruction.three.rhs));
|
||||
break;
|
||||
case JANET_SYSOP_MOVE:
|
||||
janet_formatb(buffer, "r%u = r%u\n",
|
||||
v2reg(assignments, instruction.two.dest),
|
||||
v2reg(assignments, instruction.two.src));
|
||||
break;
|
||||
case JANET_SYSOP_RETURN:
|
||||
janet_formatb(buffer, "return r%u\n",
|
||||
v2reg(assignments, instruction.one.src));
|
||||
break;
|
||||
case JANET_SYSOP_CONSTANT:
|
||||
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",
|
||||
v2reg(assignments, instruction.label.id));
|
||||
break;
|
||||
|
||||
// On a comparison, if next instruction is branch that reads from dest, combine into a single op.
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user