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, };
/* * The 64-bit version of libgcc does not contain some builtin * functions for 32-bit values (__<builtin>si2) anymore. */ static void widen_builtin(ir_node *node) { ir_type *mtp = get_Builtin_type(node); ir_type *arg1 = get_method_param_type(mtp, 0); // Nothing to do, if argument size is at least machine size. if (get_type_size(arg1) >= ir_target_pointer_size()) return; // Only touch builtins with no 32-bit version. ir_builtin_kind kind = get_Builtin_kind(node); if (kind != ir_bk_clz && kind != ir_bk_ctz && kind != ir_bk_ffs && kind != ir_bk_parity && kind != ir_bk_popcount) { return; } ir_mode *target_mode = get_reference_offset_mode(mode_P); dbg_info *dbgi = get_irn_dbg_info(node); ir_node *block = get_nodes_block(node); ir_node *op = get_irn_n(node, n_Builtin_max + 1); ir_node *conv = new_rd_Conv(dbgi, block, op, target_mode); set_irn_n(node, n_Builtin_max + 1, conv); ir_type *new_arg1 = get_type_for_mode(target_mode); ir_type *new_result = get_method_res_type(mtp, 0); ir_type *new_type = new_type_method(1, 1, false, cc_cdecl_set, mtp_no_property); set_method_param_type(new_type, 0, new_arg1); set_method_res_type(new_type, 0, new_result); set_Builtin_type(node, new_type); }
/** * Adapts the method type of a va_arg Builtin. */ static bool lower_Builtin(ir_node *node) { if (get_Builtin_kind(node) != ir_bk_va_arg) return false; ir_type *tp = get_Builtin_type(node); ir_type *lower_tp = lower_type_if_needed(tp); if (lower_tp != tp) { set_Builtin_type(node, lower_tp); } return true; }