static test_data_t * new_test_data(const irop_t *op) { test_data_t *data = malloc(sizeof *data); memset(data, 0x0, sizeof *data); // initialise /* Obtain the operand types and set them */ IRType t_dst, t1, t2, t3, t4; typeof_primop(op->op, &t_dst, &t1, &t2, &t3, &t4); assert(t_dst != Ity_INVALID); assert(t1 != Ity_INVALID); data->result.type = t_dst; if (is_floating_point_op_with_rounding_mode(op->op)) { data->opnds[0].type = t2; data->opnds[1].type = t3; data->opnds[2].type = t4; data->opnds[3].type = Ity_INVALID; } else { data->opnds[0].type = t1; data->opnds[1].type = t2; data->opnds[2].type = t3; data->opnds[3].type = t4; } /* Set the rounding mode if the operation requires one. FIXME: We should iterate over all rounding modes. For that need FIXME: to distinguish between binary and decimal floating point */ if (is_floating_point_op_with_rounding_mode(op->op)) { // for now just pick one data->rounding_mode = Irrm_NEAREST; // same as Irrm_DFP_NEAREST } else { data->rounding_mode = NO_ROUNDING_MODE; } return data; }
/* Return the number of operands for which input values can be freely chosen. For floating point ops, the rounding mode is not counted here, as it is restricted. */ int get_num_operands(IROp op) { IRType unused, t1, t2, t3, t4; typeof_primop(op, &unused, &t1, &t2, &t3, &t4); int num_operands = 4; if (t4 == Ity_INVALID) num_operands = 3; if (t3 == Ity_INVALID) num_operands = 2; if (t2 == Ity_INVALID) num_operands = 1; if (is_floating_point_op_with_rounding_mode(op)) -- num_operands; return num_operands; }