#include "builder.h" #include #include #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_OP(add); DEFINE_OP(sub); DEFINE_OP(mul); DEFINE_OP(div);