2025-08-29 15:46:52 +01:00
|
|
|
#include "builder.h"
|
|
|
|
|
|
|
|
|
|
#include <mie/ctx.h>
|
|
|
|
|
#include <mie/ir/ptr.h>
|
|
|
|
|
#include <mie/select/graph.h>
|
|
|
|
|
|
|
|
|
|
static enum mie_status push_load(
|
|
|
|
|
struct mie_select_builder *builder, struct mie_instr *instr)
|
|
|
|
|
{
|
|
|
|
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
|
|
|
|
struct mie_load *load = (struct mie_load *)instr;
|
2025-09-08 15:42:22 +01:00
|
|
|
struct mie_type *chain_type = mie_ctx_get_type(
|
|
|
|
|
mie_select_builder_get_ctx(builder), MIE_TYPE_OTHER);
|
2025-08-29 15:46:52 +01:00
|
|
|
|
|
|
|
|
struct mie_select_value *chain
|
2025-09-08 15:42:22 +01:00
|
|
|
= mie_select_builder_get_mem_access(builder, load->l_src);
|
2025-08-29 15:46:52 +01:00
|
|
|
if (!chain) {
|
|
|
|
|
chain = &graph->g_entry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_select_value *operands[] = {
|
|
|
|
|
chain,
|
2025-09-08 15:42:22 +01:00
|
|
|
mie_select_builder_get_value(builder, load->l_src),
|
2025-08-29 15:46:52 +01:00
|
|
|
};
|
|
|
|
|
size_t nr_operands = sizeof operands / sizeof operands[0];
|
|
|
|
|
|
|
|
|
|
struct mie_type *result[] = {
|
|
|
|
|
load->l_type,
|
2025-09-08 15:42:22 +01:00
|
|
|
chain_type,
|
2025-08-29 15:46:52 +01:00
|
|
|
};
|
|
|
|
|
size_t nr_results = sizeof result / sizeof result[0];
|
|
|
|
|
|
2025-09-08 15:42:22 +01:00
|
|
|
struct mie_select_node *node;
|
2025-08-29 15:46:52 +01:00
|
|
|
enum mie_status status = mie_select_graph_get_node(
|
2025-09-08 15:42:22 +01:00
|
|
|
graph, mie_target_builtin(), MIE_SELECT_OP_LOAD, operands,
|
|
|
|
|
nr_operands, result, nr_results, &node);
|
2025-08-29 15:46:52 +01:00
|
|
|
if (status != MIE_SUCCESS) {
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-08 15:42:22 +01:00
|
|
|
struct mie_select_value value_result, chain_result;
|
|
|
|
|
mie_select_node_get_value(node, load->l_type, 0, &value_result);
|
|
|
|
|
mie_select_node_get_value(node, chain_type, 0, &chain_result);
|
|
|
|
|
|
|
|
|
|
mie_select_builder_set_mem_access(builder, load->l_src, &chain_result);
|
|
|
|
|
return mie_select_builder_set_value(
|
|
|
|
|
builder, MIE_VALUE(instr), &value_result);
|
2025-08-29 15:46:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static enum mie_status push_store(
|
|
|
|
|
struct mie_select_builder *builder, struct mie_instr *instr)
|
|
|
|
|
{
|
|
|
|
|
struct mie_store *store = (struct mie_store *)instr;
|
|
|
|
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
|
|
|
|
|
|
|
|
|
struct mie_select_value *chain
|
2025-09-08 15:42:22 +01:00
|
|
|
= mie_select_builder_get_mem_access(builder, store->s_dest);
|
2025-08-29 15:46:52 +01:00
|
|
|
if (!chain) {
|
|
|
|
|
chain = &graph->g_entry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct mie_select_value *operands[] = {
|
|
|
|
|
chain,
|
2025-09-08 15:42:22 +01:00
|
|
|
mie_select_builder_get_value(builder, store->s_val),
|
|
|
|
|
mie_select_builder_get_value(builder, store->s_dest),
|
2025-08-29 15:46:52 +01:00
|
|
|
};
|
|
|
|
|
size_t nr_operands = sizeof operands / sizeof operands[0];
|
|
|
|
|
|
|
|
|
|
struct mie_type *result[] = {
|
|
|
|
|
mie_ctx_get_type(mie_select_builder_get_ctx(builder), MIE_TYPE_OTHER),
|
|
|
|
|
};
|
|
|
|
|
size_t nr_results = sizeof result / sizeof result[0];
|
|
|
|
|
|
2025-09-08 15:42:22 +01:00
|
|
|
struct mie_select_node *node;
|
2025-08-29 15:46:52 +01:00
|
|
|
enum mie_status status = mie_select_graph_get_node(
|
2025-09-08 15:42:22 +01:00
|
|
|
graph, mie_target_builtin(), MIE_SELECT_OP_STORE, operands,
|
|
|
|
|
nr_operands, result, nr_results, &node);
|
2025-08-29 15:46:52 +01:00
|
|
|
if (status != MIE_SUCCESS) {
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-08 15:42:22 +01:00
|
|
|
struct mie_select_value value;
|
|
|
|
|
mie_select_node_get_value(node, result[0], 0, &value);
|
|
|
|
|
|
|
|
|
|
mie_select_builder_set_mem_access(builder, store->s_dest, &value);
|
|
|
|
|
return mie_select_builder_set_value(builder, MIE_VALUE(instr), &value);
|
2025-08-29 15:46:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct select_instr_type select_load = {
|
|
|
|
|
.i_push = push_load,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct select_instr_type select_store = {
|
|
|
|
|
.i_push = push_store,
|
|
|
|
|
};
|