mie: implement instruction selection graph generation for binary ops and load/store

This commit is contained in:
2025-08-29 15:46:52 +01:00
parent 7fdae9f1e0
commit 9c1e0958b0
19 changed files with 1343 additions and 13 deletions

85
mie/target/select.c Normal file
View File

@@ -0,0 +1,85 @@
#include <mie/select/opcode.h>
#include <mie/target/select.h>
#include <mie/target/target.h>
#include <stdio.h>
#define NODE_NAME(op, name) \
case MIE_SELECT_OP_##op: \
return snprintf(out, max, name)
static size_t node_name(
const struct mie_target *target, unsigned int opcode, char *out, size_t max)
{
switch (opcode) {
NODE_NAME(ENTRY, "Entry");
NODE_NAME(ROOT, "Root");
NODE_NAME(BLOCK, "Root");
NODE_NAME(CONSTANT, "Constant");
NODE_NAME(FRAME_INDEX, "FrameIndex");
NODE_NAME(REGISTER, "Register");
NODE_NAME(COPY_FROM_REG, "CopyFromReg");
NODE_NAME(COPY_TO_REG, "CopyToReg");
NODE_NAME(GLOBAL_ADDRESS, "GlobalAddress");
NODE_NAME(LOAD, "Load");
NODE_NAME(STORE, "Store");
NODE_NAME(ADD, "Add");
NODE_NAME(SUB, "Sub");
NODE_NAME(MUL, "Mul");
NODE_NAME(DIV, "Div");
NODE_NAME(XOR, "Xor");
NODE_NAME(BR, "Branch");
NODE_NAME(BR_COND, "CondBranch");
default:
return snprintf(out, max, "UNKNOWN");
}
return 0;
}
const struct mie_target_select_ops __mie_builtin_select_ops = {
.s_node_name = node_name,
};
size_t mie_target_select_node_name(
const struct mie_target *target, unsigned int opcode, char *out, size_t max)
{
size_t w = snprintf(out, max, "%s::", target->t_name);
if (w < max) {
max -= w;
} else {
max = 0;
}
out += w;
if (target->t_select && target->t_select->s_node_name) {
w += target->t_select->s_node_name(target, opcode, out, max);
} else {
w += snprintf(out, max, "%u", opcode);
}
return w;
}
enum mie_status mie_target_select_lower_call(
const struct mie_target *target, struct mie_select_builder *builder,
struct mie_instr *instr)
{
if (!target->t_select || !target->t_select->s_lower_call) {
return MIE_ERR_NOT_SUPPORTED;
}
return target->t_select->s_lower_call(target, builder, instr);
}
enum mie_status mie_target_select_lower_msg(
const struct mie_target *target, struct mie_select_builder *builder,
struct mie_instr *instr)
{
if (!target->t_select || !target->t_select->s_lower_msg) {
return MIE_ERR_NOT_SUPPORTED;
}
return target->t_select->s_lower_call(target, builder, instr);
}