Exemplo n.º 1
0
static void replace_with_call(ir_node *node)
{
	widen_builtin(node);

	ir_type        *const mtp      = get_Builtin_type(node);
	ir_builtin_kind const kind     = get_Builtin_kind(node);
	char     const *const name     = get_builtin_name(kind);
	ir_type        *const arg1     = get_method_param_type(mtp, 0);
	char     const *const machmode = get_gcc_machmode(arg1);
	ident          *const id       = new_id_fmt("__%s%s2", name, machmode);
	ir_entity      *const entity
		= create_compilerlib_entity(get_id_str(id), mtp);

	dbg_info *const dbgi      = get_irn_dbg_info(node);
	ir_node  *const block     = get_nodes_block(node);
	ir_node  *const mem       = get_Builtin_mem(node);
	ir_graph *const irg       = get_irn_irg(node);
	ir_node  *const callee    = new_r_Address(irg, entity);
	int       const n_params  = get_Builtin_n_params(node);
	ir_node **const params    = get_Builtin_param_arr(node);
	ir_node  *const call      = new_rd_Call(dbgi, block, mem, callee, n_params, params, mtp);
	ir_node  *const call_mem  = new_r_Proj(call, mode_M, pn_Call_M);
	ir_node  *const call_ress = new_r_Proj(call, mode_T, pn_Call_T_result);
	ir_type  *const res_type  = get_method_res_type(mtp, 0);
	ir_mode  *const res_mode  = get_type_mode(res_type);
	ir_node  *const call_res  = new_r_Proj(call_ress, res_mode, 0);

	ir_node *const in[] = {
		[pn_Builtin_M]       = call_mem,
		[pn_Builtin_max + 1] = call_res,
	};
Exemplo n.º 2
0
static ir_node *make_softfloat_call(ir_node *const n, char const *const name,
                                    size_t const arity,
                                    ir_node *const *const in)
{
	dbg_info *const dbgi     = get_irn_dbg_info(n);
	ir_node  *const block    = get_nodes_block(n);
	ir_graph *const irg      = get_irn_irg(n);
	ir_node  *const nomem    = get_irg_no_mem(irg);
	ir_node  *const callee   = create_softfloat_address(n, name);
	ir_type  *const type     = get_softfloat_type(n);
	ir_mode  *const res_mode = get_type_mode(get_method_res_type(type, 0));
	ir_node  *const call     = new_rd_Call(dbgi, block, nomem, callee, arity,
	                                       in, type);
	ir_node  *const results  = new_r_Proj(call, mode_T, pn_Call_T_result);
	ir_node  *const result   = new_r_Proj(results, res_mode, 0);
	return result;
}
Exemplo n.º 3
0
/**
 * Turn a large CopyB node into a memcpy call.
 */
static void lower_large_copyb_node(ir_node *irn)
{
	ir_graph *irg      = get_irn_irg(irn);
	ir_node  *block    = get_nodes_block(irn);
	dbg_info *dbgi     = get_irn_dbg_info(irn);
	ir_node  *mem      = get_CopyB_mem(irn);
	ir_node  *addr_src = get_CopyB_src(irn);
	ir_node  *addr_dst = get_CopyB_dst(irn);
	ir_type  *copyb_tp = get_CopyB_type(irn);
	unsigned  size     = get_type_size(copyb_tp);

	ir_node  *callee      = get_memcpy_address(irg);
	ir_type  *call_tp     = get_memcpy_methodtype();
	ir_mode  *mode_size_t = get_ir_mode(native_mode_bytes);
	ir_node  *size_cnst   = new_r_Const_long(irg, mode_size_t, size);
	ir_node  *in[]        = { addr_dst, addr_src, size_cnst };
	ir_node  *call        = new_rd_Call(dbgi, block, mem, callee, ARRAY_SIZE(in), in, call_tp);
	ir_node  *call_mem    = new_r_Proj(call, mode_M, pn_Call_M);

	exchange(irn, call_mem);
}
Exemplo n.º 4
0
static void lower_divmod(ir_node *node, ir_node *left, ir_node *right,
                         ir_node *mem, ir_mode *mode, int res_offset)
{
	dbg_info  *dbgi       = get_irn_dbg_info(node);
	ir_node   *block      = get_nodes_block(node);
	ir_node   *left_low   = get_lowered_low(left);
	ir_node   *left_high  = get_lowered_high(left);
	ir_node   *right_low  = get_lowered_low(right);
	ir_node   *right_high = get_lowered_high(right);
	ir_mode   *node_mode  = get_irn_mode(left);
	ir_entity *entity     = mode_is_signed(node_mode) ? ldivmod : uldivmod;
	ir_type   *mtp        = get_entity_type(entity);
	ir_graph  *irg        = get_irn_irg(node);
	ir_node   *addr       = new_r_Address(irg, entity);
	ir_node   *in[4];
	if (arm_cg_config.big_endian) {
		in[0] = left_high;
		in[1] = left_low;
		in[2] = right_high;
		in[3] = right_low;
	} else {
		in[0] = left_low;
		in[1] = left_high;
		in[2] = right_low;
		in[3] = right_high;
	}
	ir_node *call    = new_rd_Call(dbgi, block, mem, addr, ARRAY_SIZE(in), in,
	                               mtp);
	ir_node *resproj = new_r_Proj(call, mode_T, pn_Call_T_result);
	set_irn_pinned(call, get_irn_pinned(node));
	foreach_out_edge_safe(node, edge) {
		ir_node *proj = get_edge_src_irn(edge);
		if (!is_Proj(proj))
			continue;

		switch ((pn_Div)get_Proj_num(proj)) {
		case pn_Div_M:
			/* reroute to the call */
			set_Proj_pred(proj, call);
			set_Proj_num(proj, pn_Call_M);
			break;
		case pn_Div_X_regular:
			set_Proj_pred(proj, call);
			set_Proj_num(proj, pn_Call_X_regular);
			break;
		case pn_Div_X_except:
			set_Proj_pred(proj, call);
			set_Proj_num(proj, pn_Call_X_except);
			break;
		case pn_Div_res: {
			ir_mode *low_mode = get_irn_mode(left_low);
			if (arm_cg_config.big_endian) {
				ir_node *res_low  = new_r_Proj(resproj, low_mode, res_offset+1);
				ir_node *res_high = new_r_Proj(resproj, mode,     res_offset);
				ir_set_dw_lowered(proj, res_low, res_high);
			} else {
				ir_node *res_low  = new_r_Proj(resproj, low_mode, res_offset);
				ir_node *res_high = new_r_Proj(resproj, mode,     res_offset+1);
				ir_set_dw_lowered(proj, res_low, res_high);
			}
			break;
		}
		}
		/* mark this proj: we have handled it already, otherwise we might fall
		 * into out new nodes. */
		mark_irn_visited(proj);
	}