asm: implement a mie backend for ivy assembly generation

This commit is contained in:
2025-09-08 15:47:48 +01:00
parent 9f8bdc9365
commit ea42f738df
4 changed files with 737 additions and 2 deletions

View File

@@ -11,5 +11,5 @@ else ()
endif () endif ()
target_include_directories(ivy-asm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/) target_include_directories(ivy-asm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/)
target_link_libraries(ivy-asm ivy-common Bluelib::Core Bluelib::Object) target_link_libraries(ivy-asm ivy-common mie Bluelib::Core Bluelib::Object)
target_compile_definitions(ivy-asm PRIVATE IVY_EXPORT=1 IVY_STATIC=${IVY_STATIC}) target_compile_definitions(ivy-asm PRIVATE IVY_EXPORT=1 IVY_STATIC=${IVY_STATIC})

307
asm/include/ivy/asm/mie.h Normal file
View File

@@ -0,0 +1,307 @@
#ifndef IVY_ASM_MIE_H_
#define IVY_ASM_MIE_H_
#include <ivy/misc.h>
#include <ivy/opcode.h>
struct mie_target;
enum ivy_select_opcode {
IVY_SELECT_OP_NONE = IVY_INSTR_NONE,
IVY_SELECT_OP_LDR = IVY_INSTR_LDR,
IVY_SELECT_OP_STR = IVY_INSTR_STR,
IVY_SELECT_OP_PUSH = IVY_INSTR_PUSH,
IVY_SELECT_OP_POP = IVY_INSTR_POP,
IVY_SELECT_OP_MSG = IVY_INSTR_MSG,
IVY_SELECT_OP_ADD = IVY_INSTR_ADD,
IVY_SELECT_OP_SUB = IVY_INSTR_SUB,
IVY_SELECT_OP_MUL = IVY_INSTR_MUL,
IVY_SELECT_OP_DIV = IVY_INSTR_DIV,
IVY_SELECT_OP_C_EQ = IVY_INSTR_C_EQ,
IVY_SELECT_OP_C_NE = IVY_INSTR_C_NE,
IVY_SELECT_OP_C_LT = IVY_INSTR_C_LT,
IVY_SELECT_OP_C_LE = IVY_INSTR_C_LE,
IVY_SELECT_OP_C_GT = IVY_INSTR_C_GT,
IVY_SELECT_OP_C_GE = IVY_INSTR_C_GE,
IVY_SELECT_OP_BR = IVY_INSTR_BR,
IVY_SELECT_OP_BR_T = IVY_INSTR_BR_T,
IVY_SELECT_OP_BR_F = IVY_INSTR_BR_F,
IVY_SELECT_OP_OB_C = IVY_INSTR_OB_C,
IVY_SELECT_OP_OB_E = IVY_INSTR_OB_E,
IVY_SELECT_OP_LAM_C = IVY_INSTR_LAM_C,
IVY_SELECT_OP_IT_G = IVY_INSTR_IT_G,
IVY_SELECT_OP_IT_N = IVY_INSTR_IT_N,
IVY_SELECT_OP_IT_V = IVY_INSTR_IT_V,
IVY_SELECT_OP_STK_A = IVY_INSTR_STK_A,
IVY_SELECT_OP_STK_F = IVY_INSTR_STK_F,
IVY_SELECT_OP_RET = IVY_INSTR_RET,
IVY_SELECT_OP_RET_N = IVY_INSTR_RET_N,
IVY_SELECT_OP_REGISTER,
IVY_SELECT_OP_SELECTOR,
};
enum ivy_select_register {
IVY_SELECT_REG_X0,
IVY_SELECT_REG_X1,
IVY_SELECT_REG_X2,
IVY_SELECT_REG_X3,
IVY_SELECT_REG_X4,
IVY_SELECT_REG_X5,
IVY_SELECT_REG_X6,
IVY_SELECT_REG_X7,
IVY_SELECT_REG_X8,
IVY_SELECT_REG_X9,
IVY_SELECT_REG_X10,
IVY_SELECT_REG_X11,
IVY_SELECT_REG_X12,
IVY_SELECT_REG_X13,
IVY_SELECT_REG_X14,
IVY_SELECT_REG_X15,
IVY_SELECT_REG_X16,
IVY_SELECT_REG_X17,
IVY_SELECT_REG_X18,
IVY_SELECT_REG_X19,
IVY_SELECT_REG_X20,
IVY_SELECT_REG_X21,
IVY_SELECT_REG_X22,
IVY_SELECT_REG_X23,
IVY_SELECT_REG_X24,
IVY_SELECT_REG_X25,
IVY_SELECT_REG_X26,
IVY_SELECT_REG_X27,
IVY_SELECT_REG_X28,
IVY_SELECT_REG_X29,
IVY_SELECT_REG_X30,
IVY_SELECT_REG_X31,
IVY_SELECT_REG_X32,
IVY_SELECT_REG_X33,
IVY_SELECT_REG_X34,
IVY_SELECT_REG_X35,
IVY_SELECT_REG_X36,
IVY_SELECT_REG_X37,
IVY_SELECT_REG_X38,
IVY_SELECT_REG_X39,
IVY_SELECT_REG_X40,
IVY_SELECT_REG_X41,
IVY_SELECT_REG_X42,
IVY_SELECT_REG_X43,
IVY_SELECT_REG_X44,
IVY_SELECT_REG_X45,
IVY_SELECT_REG_X46,
IVY_SELECT_REG_X47,
IVY_SELECT_REG_X48,
IVY_SELECT_REG_X49,
IVY_SELECT_REG_X50,
IVY_SELECT_REG_X51,
IVY_SELECT_REG_X52,
IVY_SELECT_REG_X53,
IVY_SELECT_REG_X54,
IVY_SELECT_REG_X55,
IVY_SELECT_REG_X56,
IVY_SELECT_REG_X57,
IVY_SELECT_REG_X58,
IVY_SELECT_REG_X59,
IVY_SELECT_REG_X60,
IVY_SELECT_REG_X61,
IVY_SELECT_REG_X62,
IVY_SELECT_REG_X63,
IVY_SELECT_REG_X64,
IVY_SELECT_REG_X65,
IVY_SELECT_REG_X66,
IVY_SELECT_REG_X67,
IVY_SELECT_REG_X68,
IVY_SELECT_REG_X69,
IVY_SELECT_REG_X70,
IVY_SELECT_REG_X71,
IVY_SELECT_REG_X72,
IVY_SELECT_REG_X73,
IVY_SELECT_REG_X74,
IVY_SELECT_REG_X75,
IVY_SELECT_REG_X76,
IVY_SELECT_REG_X77,
IVY_SELECT_REG_X78,
IVY_SELECT_REG_X79,
IVY_SELECT_REG_X80,
IVY_SELECT_REG_X81,
IVY_SELECT_REG_X82,
IVY_SELECT_REG_X83,
IVY_SELECT_REG_X84,
IVY_SELECT_REG_X85,
IVY_SELECT_REG_X86,
IVY_SELECT_REG_X87,
IVY_SELECT_REG_X88,
IVY_SELECT_REG_X89,
IVY_SELECT_REG_X90,
IVY_SELECT_REG_X91,
IVY_SELECT_REG_X92,
IVY_SELECT_REG_X93,
IVY_SELECT_REG_X94,
IVY_SELECT_REG_X95,
IVY_SELECT_REG_X96,
IVY_SELECT_REG_X97,
IVY_SELECT_REG_X98,
IVY_SELECT_REG_X99,
IVY_SELECT_REG_X100,
IVY_SELECT_REG_X101,
IVY_SELECT_REG_X102,
IVY_SELECT_REG_X103,
IVY_SELECT_REG_X104,
IVY_SELECT_REG_X105,
IVY_SELECT_REG_X106,
IVY_SELECT_REG_X107,
IVY_SELECT_REG_X108,
IVY_SELECT_REG_X109,
IVY_SELECT_REG_X110,
IVY_SELECT_REG_X111,
IVY_SELECT_REG_X112,
IVY_SELECT_REG_X113,
IVY_SELECT_REG_X114,
IVY_SELECT_REG_X115,
IVY_SELECT_REG_X116,
IVY_SELECT_REG_X117,
IVY_SELECT_REG_X118,
IVY_SELECT_REG_X119,
IVY_SELECT_REG_X120,
IVY_SELECT_REG_X121,
IVY_SELECT_REG_X122,
IVY_SELECT_REG_X123,
IVY_SELECT_REG_X124,
IVY_SELECT_REG_X125,
IVY_SELECT_REG_X126,
IVY_SELECT_REG_X127,
IVY_SELECT_REG_X128,
IVY_SELECT_REG_X129,
IVY_SELECT_REG_X130,
IVY_SELECT_REG_X131,
IVY_SELECT_REG_X132,
IVY_SELECT_REG_X133,
IVY_SELECT_REG_X134,
IVY_SELECT_REG_X135,
IVY_SELECT_REG_X136,
IVY_SELECT_REG_X137,
IVY_SELECT_REG_X138,
IVY_SELECT_REG_X139,
IVY_SELECT_REG_X140,
IVY_SELECT_REG_X141,
IVY_SELECT_REG_X142,
IVY_SELECT_REG_X143,
IVY_SELECT_REG_X144,
IVY_SELECT_REG_X145,
IVY_SELECT_REG_X146,
IVY_SELECT_REG_X147,
IVY_SELECT_REG_X148,
IVY_SELECT_REG_X149,
IVY_SELECT_REG_X150,
IVY_SELECT_REG_X151,
IVY_SELECT_REG_X152,
IVY_SELECT_REG_X153,
IVY_SELECT_REG_X154,
IVY_SELECT_REG_X155,
IVY_SELECT_REG_X156,
IVY_SELECT_REG_X157,
IVY_SELECT_REG_X158,
IVY_SELECT_REG_X159,
IVY_SELECT_REG_X160,
IVY_SELECT_REG_X161,
IVY_SELECT_REG_X162,
IVY_SELECT_REG_X163,
IVY_SELECT_REG_X164,
IVY_SELECT_REG_X165,
IVY_SELECT_REG_X166,
IVY_SELECT_REG_X167,
IVY_SELECT_REG_X168,
IVY_SELECT_REG_X169,
IVY_SELECT_REG_X170,
IVY_SELECT_REG_X171,
IVY_SELECT_REG_X172,
IVY_SELECT_REG_X173,
IVY_SELECT_REG_X174,
IVY_SELECT_REG_X175,
IVY_SELECT_REG_X176,
IVY_SELECT_REG_X177,
IVY_SELECT_REG_X178,
IVY_SELECT_REG_X179,
IVY_SELECT_REG_X180,
IVY_SELECT_REG_X181,
IVY_SELECT_REG_X182,
IVY_SELECT_REG_X183,
IVY_SELECT_REG_X184,
IVY_SELECT_REG_X185,
IVY_SELECT_REG_X186,
IVY_SELECT_REG_X187,
IVY_SELECT_REG_X188,
IVY_SELECT_REG_X189,
IVY_SELECT_REG_X190,
IVY_SELECT_REG_X191,
IVY_SELECT_REG_X192,
IVY_SELECT_REG_X193,
IVY_SELECT_REG_X194,
IVY_SELECT_REG_X195,
IVY_SELECT_REG_X196,
IVY_SELECT_REG_X197,
IVY_SELECT_REG_X198,
IVY_SELECT_REG_X199,
IVY_SELECT_REG_X200,
IVY_SELECT_REG_X201,
IVY_SELECT_REG_X202,
IVY_SELECT_REG_X203,
IVY_SELECT_REG_X204,
IVY_SELECT_REG_X205,
IVY_SELECT_REG_X206,
IVY_SELECT_REG_X207,
IVY_SELECT_REG_X208,
IVY_SELECT_REG_X209,
IVY_SELECT_REG_X210,
IVY_SELECT_REG_X211,
IVY_SELECT_REG_X212,
IVY_SELECT_REG_X213,
IVY_SELECT_REG_X214,
IVY_SELECT_REG_X215,
IVY_SELECT_REG_X216,
IVY_SELECT_REG_X217,
IVY_SELECT_REG_X218,
IVY_SELECT_REG_X219,
IVY_SELECT_REG_X220,
IVY_SELECT_REG_X221,
IVY_SELECT_REG_X222,
IVY_SELECT_REG_X223,
IVY_SELECT_REG_X224,
IVY_SELECT_REG_X225,
IVY_SELECT_REG_X226,
IVY_SELECT_REG_X227,
IVY_SELECT_REG_X228,
IVY_SELECT_REG_X229,
IVY_SELECT_REG_X230,
IVY_SELECT_REG_X231,
IVY_SELECT_REG_X232,
IVY_SELECT_REG_X233,
IVY_SELECT_REG_X234,
IVY_SELECT_REG_X235,
IVY_SELECT_REG_X236,
IVY_SELECT_REG_X237,
IVY_SELECT_REG_X238,
IVY_SELECT_REG_X239,
IVY_SELECT_REG_X240,
IVY_SELECT_REG_X241,
IVY_SELECT_REG_X242,
IVY_SELECT_REG_X243,
IVY_SELECT_REG_X244,
IVY_SELECT_REG_X245,
IVY_SELECT_REG_X246,
IVY_SELECT_REG_X247,
IVY_SELECT_REG_X248,
IVY_SELECT_REG_X249,
IVY_SELECT_REG_X250,
IVY_SELECT_REG_X251,
IVY_SELECT_REG_X252,
IVY_SELECT_REG_X253,
IVY_SELECT_REG_X254,
IVY_SELECT_REG_X255,
IVY_SELECT_REG_X256,
IVY_SELECT_REG_SP,
IVY_SELECT_REG_BP,
};
IVY_API const struct mie_target *ivy_asm_mie_target(void);
#endif

415
asm/mie/select.c Normal file
View File

@@ -0,0 +1,415 @@
#include "mie/select/opcode.h"
#include <ivy/asm/mie.h>
#include <ivy/opcode.h>
#include <mie/ctx.h>
#include <mie/ir/const.h>
#include <mie/ir/msg.h>
#include <mie/select/builder.h>
#include <mie/select/graph.h>
#include <mie/select/node.h>
#include <mie/target/select.h>
#include <stdio.h>
#include <stdlib.h>
#define NODE_NAME(op) \
case IVY_SELECT_OP_##op: \
return snprintf(out, max, #op)
#define NODE_NAME_(op, name) \
case IVY_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(LDR);
NODE_NAME(STR);
NODE_NAME(PUSH);
NODE_NAME(POP);
NODE_NAME(MSG);
NODE_NAME(ADD);
NODE_NAME(SUB);
NODE_NAME(MUL);
NODE_NAME(DIV);
NODE_NAME_(C_EQ, "C.EQ");
NODE_NAME_(C_NE, "C.NE");
NODE_NAME_(C_LT, "C.LT");
NODE_NAME_(C_LE, "C.LE");
NODE_NAME_(C_GT, "C.GT");
NODE_NAME_(C_GE, "C.GE");
NODE_NAME(BR);
NODE_NAME_(BR_T, "BR.T");
NODE_NAME_(BR_F, "BR.F");
NODE_NAME_(OB_C, "OB.C");
NODE_NAME_(OB_E, "OB.E");
NODE_NAME_(LAM_C, "LAM.C");
NODE_NAME_(IT_G, "IT.G");
NODE_NAME_(IT_N, "IT.N");
NODE_NAME_(IT_V, "IT.V");
NODE_NAME_(STK_A, "STK.A");
NODE_NAME_(STK_F, "STK.F");
NODE_NAME(RET);
NODE_NAME_(RET_N, "RET.N");
NODE_NAME_(REGISTER, "Register");
NODE_NAME_(SELECTOR, "Selector");
default:
return snprintf(out, max, "UNKNOWN");
}
return 0;
}
static enum mie_status get_sp_register(
const struct mie_target *target, struct mie_select_builder *builder,
struct mie_select_value *out)
{
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
struct mie_type *ptr_type = mie_ctx_get_type(ctx, MIE_TYPE_PTR);
struct mie_select_node *sp_node = mie_select_builder_find_node_with_ivalue(
builder, target, IVY_SELECT_OP_REGISTER, IVY_SELECT_REG_SP);
if (sp_node) {
mie_select_node_get_value(sp_node, ptr_type, 0, out);
return MIE_SUCCESS;
}
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
enum mie_status status = mie_select_graph_get_node(
graph, target, IVY_SELECT_OP_REGISTER, NULL, 0, &ptr_type, 1,
&sp_node);
if (status != MIE_SUCCESS) {
return status;
}
sp_node->n_value.i = IVY_SELECT_REG_SP;
mie_select_node_set_description(sp_node, "$sp");
mie_select_node_get_value(sp_node, ptr_type, 0, out);
return MIE_SUCCESS;
}
static enum mie_status get_selector(
const struct mie_target *target, struct mie_select_builder *builder,
struct mie_selector *sel, struct mie_select_value *out)
{
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
struct mie_type *ptr_type = mie_ctx_get_type(ctx, MIE_TYPE_PTR);
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
b_queue *nodes = &graph->g_nodes;
b_queue_iterator it;
b_queue_foreach (&it, nodes) {
struct mie_select_node *node
= b_unbox(struct mie_select_node, it.entry, n_entry);
if (node->n_target != target) {
continue;
}
if (node->n_opcode != IVY_SELECT_OP_SELECTOR) {
continue;
}
if (!node->n_value.v || !mie_value_is_selector(node->n_value.v)) {
continue;
}
struct mie_selector *sel_node = (struct mie_selector *)node;
if (strcmp(sel->sel_value, sel_node->sel_value) != 0) {
continue;
}
mie_select_node_get_value(node, ptr_type, 0, out);
return MIE_SUCCESS;
}
struct mie_select_node *sel_node;
enum mie_status status = mie_select_graph_get_node(
graph, target, IVY_SELECT_OP_SELECTOR, NULL, 0, &ptr_type, 1,
&sel_node);
if (status != MIE_SUCCESS) {
return status;
}
sel_node->n_value.v = MIE_VALUE(sel);
mie_select_node_set_description(sel_node, "%s", sel->sel_value);
mie_select_node_get_value(sel_node, ptr_type, 0, out);
return MIE_SUCCESS;
}
static enum mie_status load_selector(
const struct mie_target *target, struct mie_select_builder *builder,
struct mie_select_value *sel, struct mie_select_value *out)
{
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
struct mie_type *id_type = mie_ctx_get_type(ctx, MIE_TYPE_ID);
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
struct mie_select_node *load_sel;
struct mie_select_value *operands[] = {
&graph->g_entry,
sel,
};
const size_t nr_operands = sizeof operands / sizeof operands[0];
struct mie_type *results[] = {
id_type,
};
const size_t nr_results = sizeof results / sizeof results[0];
enum mie_status status = mie_select_graph_get_node(
graph, mie_target_builtin(), MIE_SELECT_OP_LOAD, operands,
nr_operands, results, nr_results, &load_sel);
if (status != MIE_SUCCESS) {
return status;
}
mie_select_node_get_value(load_sel, id_type, 0, out);
return MIE_SUCCESS;
}
static enum mie_status create_stack_alloc(
const struct mie_target *target, struct mie_select_builder *builder,
size_t count, struct mie_select_value *incoming_chain,
struct mie_select_value *out)
{
struct mie_select_node *alloc;
enum mie_status status;
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
struct mie_type *chain = mie_ctx_get_type(ctx, MIE_TYPE_OTHER);
struct mie_type *i32 = mie_ctx_get_int_type(ctx, 32);
struct mie_select_value count_value;
mie_select_builder_get_const(builder, count, &count_value);
struct mie_select_value *operands[] = {
&count_value,
incoming_chain,
};
const size_t nr_operands = sizeof operands / sizeof operands[0];
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
status = mie_select_graph_get_node(
graph, target, IVY_SELECT_OP_STK_A, operands, nr_operands,
&chain, 1, &alloc);
if (status != MIE_SUCCESS) {
return status;
}
mie_select_node_get_value(alloc, chain, 0, out);
mie_select_node_set_description(
alloc, "(allocate %zu slots on stack)", count);
return MIE_SUCCESS;
}
static enum mie_status create_stack_free(
const struct mie_target *target, struct mie_select_builder *builder,
size_t count, struct mie_select_value *incoming_chain,
struct mie_select_value *out)
{
struct mie_select_node *free_node;
enum mie_status status;
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
struct mie_type *chain = mie_ctx_get_type(ctx, MIE_TYPE_OTHER);
struct mie_type *i32 = mie_ctx_get_int_type(ctx, 32);
struct mie_select_value count_value;
mie_select_builder_get_const(builder, count, &count_value);
struct mie_select_value *operands[] = {
&count_value,
incoming_chain,
};
const size_t nr_operands = sizeof operands / sizeof operands[0];
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
status = mie_select_graph_get_node(
graph, target, IVY_SELECT_OP_STK_F, operands, nr_operands,
&chain, 1, &free_node);
if (status != MIE_SUCCESS) {
return status;
}
mie_select_node_set_description(
free_node, "(free %zu slots on stack)", count);
mie_select_node_get_value(free_node, chain, 0, out);
return MIE_SUCCESS;
}
static enum mie_status create_chain_group(
const struct mie_target *target, struct mie_select_builder *builder,
struct mie_select_value **incoming_chains, size_t count,
struct mie_select_value *out)
{
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
struct mie_select_node *group = NULL;
struct mie_type *chain_type = mie_ctx_get_type(ctx, MIE_TYPE_OTHER);
enum mie_status status = mie_select_graph_get_node(
graph, mie_target_builtin(), MIE_SELECT_OP_CHAIN_GROUP,
incoming_chains, count, &chain_type, 1, &group);
if (status != MIE_SUCCESS) {
return status;
}
mie_select_node_get_value(group, chain_type, 0, out);
return MIE_SUCCESS;
}
static enum mie_status put_param_on_stack(
const struct mie_target *target, struct mie_select_builder *builder,
struct mie_select_value *in_chain, struct mie_select_value *param,
size_t offset, struct mie_select_value *out_chain)
{
struct mie_select_value sp;
struct mie_select_value offset_value;
struct mie_type *chain_type;
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
get_sp_register(target, builder, &sp);
mie_select_builder_get_const(builder, offset, &offset_value);
chain_type = mie_ctx_get_type(ctx, MIE_TYPE_OTHER);
struct mie_select_value *operands[] = {
in_chain,
param,
&sp,
&offset_value,
};
const size_t nr_operands = sizeof operands / sizeof operands[0];
struct mie_select_node *store;
enum mie_status status = mie_select_graph_get_node(
graph, target, IVY_SELECT_OP_STR, operands, nr_operands,
&chain_type, 1, &store);
mie_select_node_set_description(
store, "(store N%zu on stack + %zu)", param->v_node->n_id, offset);
mie_select_node_get_value(store, chain_type, 0, out_chain);
return MIE_SUCCESS;
}
static enum mie_status lower_msg(
const struct mie_target *target, struct mie_select_builder *builder,
struct mie_msg *msg, struct mie_select_value *result)
{
enum mie_status status = MIE_SUCCESS;
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
struct mie_ctx *ctx = mie_select_builder_get_ctx(builder);
struct mie_select_value **param_chains = calloc(
b_max(size_t, 2, msg->msg_nr_args + 1),
sizeof(struct mie_select_value *));
size_t nr_param_chains = 0;
struct mie_select_value *chain, *recipient, nr_args;
chain = mie_select_builder_get_mem_access(builder, msg->msg_recipient);
recipient = mie_select_builder_get_value(builder, msg->msg_recipient);
mie_select_builder_get_const(builder, msg->msg_nr_args, &nr_args);
if (chain) {
param_chains[nr_param_chains++] = chain;
}
for (size_t i = 0; i < msg->msg_nr_args; i++) {
struct mie_select_value *chain = mie_select_builder_get_mem_access(
builder, msg->msg_args[i]);
if (chain) {
param_chains[nr_param_chains++] = chain;
}
}
if (nr_param_chains == 0) {
param_chains[nr_param_chains++] = &graph->g_entry;
}
struct mie_select_value pre_arg_init_chain, post_arg_init_chain;
if (nr_param_chains > 1) {
status = create_chain_group(
target, builder, param_chains, nr_param_chains,
&pre_arg_init_chain);
} else {
pre_arg_init_chain = *param_chains[0];
}
struct mie_select_value stack_alloc, stack_free;
status = create_stack_alloc(
target, builder, msg->msg_nr_args, &pre_arg_init_chain,
&stack_alloc);
if (status != MIE_SUCCESS) {
return status;
}
struct mie_select_value *stack_chains = calloc(
b_max(size_t, 1, msg->msg_nr_args),
sizeof(struct mie_select_value));
size_t nr_stack_chains = 0;
nr_param_chains = 0;
for (size_t i = 0; i < msg->msg_nr_args; i++) {
struct mie_select_value *param_value
= mie_select_builder_get_value(builder, msg->msg_args[i]);
status = put_param_on_stack(
target, builder, &stack_alloc, param_value, i,
&stack_chains[nr_stack_chains]);
param_chains[nr_param_chains] = &stack_chains[nr_stack_chains];
nr_param_chains++;
nr_stack_chains++;
}
if (nr_param_chains > 1) {
status = create_chain_group(
target, builder, param_chains, nr_param_chains,
&post_arg_init_chain);
} else {
post_arg_init_chain = *param_chains[0];
}
free(param_chains);
free(stack_chains);
struct mie_select_value sel, load_sel;
get_selector(target, builder, MIE_SELECTOR(msg->msg_selector), &sel);
load_selector(target, builder, &sel, &load_sel);
struct mie_select_value *msg_params[] = {
&post_arg_init_chain,
recipient,
&load_sel,
&nr_args,
};
const size_t nr_msg_params = sizeof msg_params / sizeof msg_params[0];
struct mie_type *msg_results[] = {
mie_ctx_get_type(ctx, MIE_TYPE_OTHER),
mie_ctx_get_type(ctx, MIE_TYPE_GLUE),
};
const size_t nr_msg_results = sizeof msg_results / sizeof msg_results[0];
struct mie_select_node *msg_node;
status = mie_select_graph_get_node(
graph, target, IVY_SELECT_OP_MSG, msg_params, nr_msg_params,
msg_results, nr_msg_results, &msg_node);
result->v_node = msg_node;
result->v_index = 0;
return MIE_SUCCESS;
}
const struct mie_target_select_ops __ivy_select_ops = {
.s_node_name = node_name,
.s_lower_msg = lower_msg,
};

13
asm/mie/target.c Normal file
View File

@@ -0,0 +1,13 @@
#include <mie/target/target.h>
extern const struct mie_target_select_ops __ivy_select_ops;
static const struct mie_target ivy_target = {
.t_name = "Ivy",
.t_select = &__ivy_select_ops,
};
const struct mie_target *ivy_asm_mie_target(void)
{
return &ivy_target;
}