Files
mie/mie/select/binary-op.c

70 lines
2.2 KiB
C

#include "builder.h"
#include <mie/ir/op.h>
#include <mie/select/graph.h>
#define DEFINE_PUSH_FUNCTION(name, op) \
static enum mie_status push_##name( \
struct mie_select_builder *builder, struct mie_instr *instr) \
{ \
return push_op(op, builder, instr); \
}
#define DEFINE_OP(name) \
struct select_instr_type select_##name = { \
.i_push = push_##name, \
}
static enum mie_status push_op(
unsigned int opcode, struct mie_select_builder *builder,
struct mie_instr *instr)
{
struct mie_binary_op *op = (struct mie_binary_op *)instr;
struct mie_select_value *operands[] = {
mie_select_builder_get_value(builder, op->op_left),
mie_select_builder_get_value(builder, op->op_right),
};
size_t nr_operands = sizeof operands / sizeof operands[0];
struct mie_type *result[] = {
op->op_type,
};
size_t nr_results = sizeof result / sizeof result[0];
struct mie_select_node *node;
enum mie_status status = mie_select_graph_get_node(
mie_select_builder_get_graph(builder), mie_target_builtin(),
opcode, operands, nr_operands, result, nr_results, &node);
if (status != MIE_SUCCESS) {
return status;
}
struct mie_select_value value;
mie_select_node_get_value(node, op->op_type, 0, &value);
return mie_select_builder_set_value(builder, MIE_VALUE(instr), &value);
}
DEFINE_PUSH_FUNCTION(add, MIE_SELECT_OP_ADD);
DEFINE_PUSH_FUNCTION(sub, MIE_SELECT_OP_SUB);
DEFINE_PUSH_FUNCTION(mul, MIE_SELECT_OP_MUL);
DEFINE_PUSH_FUNCTION(div, MIE_SELECT_OP_DIV);
DEFINE_PUSH_FUNCTION(cmp_eq, MIE_SELECT_OP_CMP_EQ);
DEFINE_PUSH_FUNCTION(cmp_neq, MIE_SELECT_OP_CMP_NEQ);
DEFINE_PUSH_FUNCTION(cmp_lt, MIE_SELECT_OP_CMP_LT);
DEFINE_PUSH_FUNCTION(cmp_gt, MIE_SELECT_OP_CMP_GT);
DEFINE_PUSH_FUNCTION(cmp_leq, MIE_SELECT_OP_CMP_LEQ);
DEFINE_PUSH_FUNCTION(cmp_geq, MIE_SELECT_OP_CMP_GEQ);
DEFINE_OP(add);
DEFINE_OP(sub);
DEFINE_OP(mul);
DEFINE_OP(div);
DEFINE_OP(cmp_eq);
DEFINE_OP(cmp_neq);
DEFINE_OP(cmp_lt);
DEFINE_OP(cmp_gt);
DEFINE_OP(cmp_leq);
DEFINE_OP(cmp_geq);