static void handle_intrinsic(ir_node *node, void *data) { (void)data; if (is_Div(node)) { ir_mode *mode = get_Div_resmode(node); if (get_mode_arithmetic(mode) == irma_twos_complement) { ir_entity *entity = mode_is_signed(mode) ? divsi3 : udivsi3; be_map_exc_node_to_runtime_call(node, mode, entity, pn_Div_M, pn_Div_X_regular, pn_Div_X_except, pn_Div_res); } } else if (is_Mod(node)) { ir_mode *mode = get_Mod_resmode(node); assert(get_mode_arithmetic(mode) == irma_twos_complement); ir_entity *entity = mode_is_signed(mode) ? modsi3 : umodsi3; be_map_exc_node_to_runtime_call(node, mode, entity, pn_Mod_M, pn_Mod_X_regular, pn_Mod_X_except, pn_Mod_res); } }
/** * @return An Address representing the function that replaces the given node. */ static ir_node *create_softfloat_address(const ir_node *n, const char *name) { ir_type *const method = get_softfloat_type(n); /* Parameter types. */ char const *first_param = ""; char const *second_param = ""; unsigned float_types = 0; unsigned double_types = 0; switch (get_method_n_params(method)) { case 2: { ir_type *const param_type = get_method_param_type(method, 1); ir_mode *const mode = get_type_mode(param_type); if (mode == mode_F) { second_param = "sf"; float_types++; } else if (mode == mode_D) { second_param = "df"; double_types++; } else if (mode == mode_Iu || mode == mode_Is) { second_param = "si"; } else if (mode == mode_Lu || mode == mode_Ls) { second_param = "di"; } } /* FALLTHROUGH */ case 1: { ir_type *const param_type = get_method_param_type(method, 0); ir_mode *const mode = get_type_mode(param_type); if (mode == mode_F) { first_param = float_types > 0 ? "" : "sf"; float_types++; } else if (mode == mode_D) { first_param = double_types > 0 ? "" : "df"; double_types++; } else if (mode == mode_Iu || mode == mode_Is) { first_param = "si"; } else if (mode == mode_Lu || mode == mode_Ls) { first_param = "di"; } break; } default: break; } /* Result type. */ char const *result = ""; ir_mode *const mode = is_Div(n) ? get_Div_resmode(n) : get_irn_mode(n); if (mode == mode_F) { result = float_types > 0 ? "" : "sf"; float_types++; } else if (mode == mode_D) { result = double_types > 0 ? "" : "df"; double_types++; } else if (mode == mode_Iu || mode == mode_Hu || mode == mode_Bu || mode == mode_Is || mode == mode_Hs || mode == mode_Bs) result = "si"; else if (mode == mode_Lu || mode == mode_Ls) result = "di"; assert(float_types <= 3); assert(double_types <= 3); ident *const id = float_types + double_types > 1 ? new_id_fmt("__%s%s%s%s%u", name, first_param, second_param, result, float_types + double_types) : new_id_fmt("__%s%s%s%s", name, first_param, second_param, result); ir_graph *const irg = get_irn_irg(n); ir_entity *const ent = create_compilerlib_entity(id, method); return new_r_Address(irg, ent); }