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/struct.c \
|
||||||
src/core/symcache.c \
|
src/core/symcache.c \
|
||||||
src/core/sysir.c \
|
src/core/sysir.c \
|
||||||
|
src/core/sysir_x86.c \
|
||||||
src/core/table.c \
|
src/core/table.c \
|
||||||
src/core/tuple.c \
|
src/core/tuple.c \
|
||||||
src/core/util.c \
|
src/core/util.c \
|
||||||
|
@ -356,6 +356,16 @@
|
|||||||
[]
|
[]
|
||||||
(eprintf "%.99M\n" (sysir/to-ir ctx)))
|
(eprintf "%.99M\n" (sysir/to-ir ctx)))
|
||||||
|
|
||||||
|
(defn dumpx64
|
||||||
|
[]
|
||||||
|
(print (sysir/to-x64 ctx)))
|
||||||
|
|
||||||
(defn dumpc
|
(defn dumpc
|
||||||
[]
|
[]
|
||||||
(print (sysir/to-c ctx)))
|
(print (sysir/to-c ctx)))
|
||||||
|
|
||||||
|
####
|
||||||
|
|
||||||
|
(compile1 myprog)
|
||||||
|
#(dump)
|
||||||
|
(dumpx64)
|
||||||
|
@ -142,6 +142,7 @@ core_src = [
|
|||||||
'src/core/struct.c',
|
'src/core/struct.c',
|
||||||
'src/core/symcache.c',
|
'src/core/symcache.c',
|
||||||
'src/core/sysir.c',
|
'src/core/sysir.c',
|
||||||
|
'src/core/sysir_x86.c',
|
||||||
'src/core/table.c',
|
'src/core/table.c',
|
||||||
'src/core/tuple.c',
|
'src/core/tuple.c',
|
||||||
'src/core/util.c',
|
'src/core/util.c',
|
||||||
|
@ -1839,12 +1839,23 @@ JANET_CORE_FN(cfun_sysir_toir,
|
|||||||
return janet_wrap_array(array);
|
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) {
|
void janet_lib_sysir(JanetTable *env) {
|
||||||
JanetRegExt cfuns[] = {
|
JanetRegExt cfuns[] = {
|
||||||
JANET_CORE_REG("sysir/context", cfun_sysir_context),
|
JANET_CORE_REG("sysir/context", cfun_sysir_context),
|
||||||
JANET_CORE_REG("sysir/asm", cfun_sysir_asm),
|
JANET_CORE_REG("sysir/asm", cfun_sysir_asm),
|
||||||
JANET_CORE_REG("sysir/to-c", cfun_sysir_toc),
|
JANET_CORE_REG("sysir/to-c", cfun_sysir_toc),
|
||||||
JANET_CORE_REG("sysir/to-ir", cfun_sysir_toir),
|
JANET_CORE_REG("sysir/to-ir", cfun_sysir_toir),
|
||||||
|
JANET_CORE_REG("sysir/to-x64", cfun_sysir_tox64),
|
||||||
JANET_REG_END
|
JANET_REG_END
|
||||||
};
|
};
|
||||||
janet_core_cfuns_ext(env, NULL, cfuns);
|
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) {
|
void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetBuffer *buffer) {
|
||||||
|
|
||||||
/* Do register allocation */
|
/* 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]);
|
JanetSysIR *ir = janet_unwrap_pointer(linkage->ir_ordered->data[i]);
|
||||||
JanetTable *assignments = janet_table(0);
|
JanetTable *assignments = janet_table(0);
|
||||||
JanetSysSpill *spills = assign_registers(ir, assignments, 15);
|
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++) {
|
for (uint32_t j = 0; j < ir->instruction_count; j++) {
|
||||||
JanetSysInstruction instruction = ir->instructions[j];
|
JanetSysInstruction instruction = ir->instructions[j];
|
||||||
JanetSysSpill spill = spills[j];
|
JanetSysSpill spill = spills[j];
|
||||||
@ -183,21 +189,29 @@ void janet_sys_ir_lower_to_x64(JanetSysIRLinkage *linkage, JanetBuffer *buffer)
|
|||||||
// emit load
|
// emit load
|
||||||
uint32_t reg = spill.regs[spi];
|
uint32_t reg = spill.regs[spi];
|
||||||
void *x = (void *) 0x123456;
|
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) {
|
if (spill.spills[spi] == JANET_SYS_SPILL_WRITE || spill.spills[spi] == JANET_SYS_SPILL_BOTH) {
|
||||||
// emit store
|
// emit store
|
||||||
uint32_t reg = spill.regs[spi];
|
uint32_t reg = spill.regs[spi];
|
||||||
void *x = (void *) 0x123456;
|
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) {
|
switch (instruction.opcode) {
|
||||||
default:
|
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;
|
break;
|
||||||
case JANET_SYSOP_POINTER_ADD:
|
case JANET_SYSOP_POINTER_ADD:
|
||||||
case JANET_SYSOP_POINTER_SUBTRACT:
|
case JANET_SYSOP_POINTER_SUBTRACT:
|
||||||
break;
|
|
||||||
case JANET_SYSOP_ADD:
|
case JANET_SYSOP_ADD:
|
||||||
case JANET_SYSOP_SUBTRACT:
|
case JANET_SYSOP_SUBTRACT:
|
||||||
case JANET_SYSOP_MULTIPLY:
|
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.lhs),
|
||||||
v2reg(assignments, instruction.three.rhs));
|
v2reg(assignments, instruction.three.rhs));
|
||||||
break;
|
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.
|
// 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