Exemplo n.º 1
0
/**
 * lower Alloca nodes to allocate "bytes" instead of a certain type
 */
static void lower_alloca_free(ir_node *node, void *data)
{
	(void) data;
	if (is_Alloc(node)) {
	} else if (is_Proj(node)) {
		ir_node *proj_pred = get_Proj_pred(node);
		if (is_Alloc(proj_pred)) {
			transform_Proj_Alloc(node);
		}
		return;
	} else {
		return;
	}
	if (!ir_nodeset_insert(&transformed, node))
		return;

	if (stack_alignment <= 1)
		return;

	ir_node  *const size     = get_Alloc_size(node);
	ir_node  *const mem      = get_Alloc_mem(node);
	ir_node  *const block    = get_nodes_block(node);
	dbg_info *const dbgi     = get_irn_dbg_info(node);
	ir_node  *const new_size = adjust_alloc_size(dbgi, size, block);
	ir_node  *const new_node
		= new_rd_Alloc(dbgi, block, mem, new_size, 1);
	ir_nodeset_insert(&transformed, new_node);

	if (new_node != node)
		exchange(node, new_node);
}
Exemplo n.º 2
0
static void transform_Proj_Alloc(ir_node *node)
{
	/* we might need a result adjustment */
	if (addr_delta == 0)
		return;
	if (get_Proj_proj(node) != pn_Alloc_res)
		return;
	if (ir_nodeset_contains(&transformed, node))
		return;

	ir_node  *const alloc = get_Proj_pred(node);
	dbg_info *const dbgi  = get_irn_dbg_info(alloc);
	ir_graph *const irg   = get_irn_irg(node);
	ir_node  *const block = get_nodes_block(node);
	ir_node  *const delta = new_r_Const_long(irg, mode_P, addr_delta);
	ir_node  *const dummy = new_r_Dummy(irg, mode_P);
	ir_node  *const add   = new_rd_Add(dbgi, block, dummy, delta, mode_P);

	exchange(node, add);
	ir_node *const new_proj = new_r_Proj(alloc, mode_P, pn_Alloc_res);
	set_Add_left(add, new_proj);
	ir_nodeset_insert(&transformed, new_proj);
}
Exemplo n.º 3
0
/**
 * Transforms a Cmp into the appropriate soft float function.
 */
static bool lower_Cmp(ir_node *const n)
{
	ir_node *const left    = get_Cmp_left(n);
	ir_mode *const op_mode = get_irn_mode(left);
	if (!mode_is_float(op_mode))
		return false;

	dbg_info *const dbgi = get_irn_dbg_info(n);
	ir_graph *const irg  = get_irn_irg(n);
	ir_node  *const zero = new_rd_Const_null(dbgi, irg, mode_Is);

	char const  *name     = NULL;
	char const  *name2    = NULL;
	ir_node     *result   = NULL;
	ir_relation  relation = get_Cmp_relation(n);
	switch (relation) {
	case ir_relation_false:
		result = zero;
		break;
	case ir_relation_equal:
		name = "eq";
		break;
	case ir_relation_less:
		name = "lt";
		break;
	case ir_relation_greater:
		name = "gt";
		break;
	case ir_relation_unordered:
		name     = "unord";
		relation = ir_relation_less_greater;
		break;
	case ir_relation_less_equal:
		name = "le";
		break;
	case ir_relation_greater_equal:
		name = "ge";
		break;
	case ir_relation_less_greater:
		name  = "unord";
		name2 = "ne";
		break;
	case ir_relation_less_equal_greater:
		name     = "unord";
		relation = ir_relation_equal;
		break;
	case ir_relation_unordered_equal:
		name     = "unord";
		relation = ir_relation_less_greater;
		name2    = "ne";
		break;
	case ir_relation_unordered_less:
		name     = "ge";
		relation = ir_relation_less;
		break;
	case ir_relation_unordered_less_equal:
		name     = "gt";
		relation = ir_relation_less_equal;
		break;
	case ir_relation_unordered_greater:
		name     = "le";
		relation = ir_relation_greater;
		break;
	case ir_relation_unordered_greater_equal:
		name     = "lt";
		relation = ir_relation_greater_equal;
		break;
	case ir_relation_unordered_less_greater:
		name     = "eq";
		relation = ir_relation_less_greater;
		break;
	case ir_relation_true:
		result = zero;
		break;
	}

	ir_node *const block = get_nodes_block(n);
	ir_node *const right = get_Cmp_right(n);

	if (result == NULL) {
		ir_node *const in[] = { left, right };
		result = make_softfloat_call(n, name, ARRAY_SIZE(in), in);
	}

	ir_node *cmp = new_r_Cmp(block, result, zero, relation);

	/* We need two calls into the softfloat library */
	if (name2 != NULL) {
		ir_node *const in[] = { left, right };
		result   = make_softfloat_call(n, name2, ARRAY_SIZE(in), in);
		relation = get_Cmp_relation(n);

		ir_node *const mux = new_rd_Mux(dbgi, block, cmp, result, zero);

		arch_allow_ifconv_func const allow_ifconv
			= be_get_backend_param()->allow_ifconv;
		if (!allow_ifconv(cmp, result, zero))
			ir_nodeset_insert(&created_mux_nodes, mux);

		cmp = new_r_Cmp(block, mux, zero, relation);
	}

	exchange(n, cmp);
	return true;
}