<commit_before>/*
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

/**
 * @file
 * @brief       This file implements the mapping of 64Bit intrinsic
 *              functions to code or library calls.
 * @author      <NAME>
 * @version     $Id$
 */
#include "config.h"

#include "irgmod.h"
#include "irop.h"
#include "irnode_t.h"
#include "ircons.h"
#include "irprog_t.h"
#include "lowering.h"
#include "array.h"
#include "error.h"

#include "ia32_new_nodes.h"
#include "bearch_ia32_t.h"
#include "gen_ia32_regalloc_if.h"

/** The array of all intrinsics that must be mapped. */
static i_record *intrinsics;

/** An array to cache all entities. */
static ir_entity *i_ents[iro_Last + 1];

/*
 * Maps all intrinsic calls that the backend support
 * and map all instructions the backend did not support
 * to runtime calls.
 */
void ia32_handle_intrinsics(void) {
	if (intrinsics && ARR_LEN(intrinsics) > 0) {
		lower_intrinsics(intrinsics, ARR_LEN(intrinsics), /*part_block_used=*/1);
	}
}

#define BINOP_Left_Low   0
#define BINOP_Left_High  1
#define BINOP_Right_Low  2
#define BINOP_Right_High 3

/**
 * Replace a call be a tuple of l_res, h_res.
 */
static void resolve_call(ir_node *call, ir_node *l_res, ir_node *h_res, ir_graph *irg, ir_node *block) {
	ir_node *jmp, *res, *in[2];
	ir_node *bad   = get_irg_bad(irg);
	ir_node *nomem = get_irg_no_mem(irg);
	int     old_cse;

	in[0] = l_res;
	in[1] = h_res;
	res = new_r_Tuple(irg, block, h_res == NULL ? 1 : 2, in);

	turn_into_tuple(call, pn_Call_max);
	set_Tuple_pred(call, pn_Call_M_regular,        nomem);
	/*
	 * Beware:
	 * We do not check here if this call really has exception and regular Proj's.
	 * new_r_Jmp might than be CSEd with the real exit jmp and then bad things happen
	 * (in movgen.c from 186.crafty for example).
	 * So be sure the newly created Jmp cannot CSE.
	 */
	old_cse = get_opt_cse();
	set_opt_cse(0);
	jmp = new_r_Jmp(irg, block);
	set_opt_cse(old_cse);

	set_Tuple_pred(call, pn_Call_X_regular,        jmp);
	set_Tuple_pred(call, pn_Call_X_except,         bad);
	set_Tuple_pred(call, pn_Call_T_result,         res);
	set_Tuple_pred(call, pn_Call_M_except,         nomem);
	set_Tuple_pred(call, pn_Call_P_value_res_base, bad);
}
<commit_msg>- use edges to reroute the result in resolve_call:   this prevents some nasty warnings about unreachable Tuples   in the back end<commit_after>/*
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

/**
 * @file
 * @brief       This file implements the mapping of 64Bit intrinsic
 *              functions to code or library calls.
 * @author      <NAME>
 * @version     $Id$
 */
#include "config.h"

#include "iredges.h"
#include "irgmod.h"
#include "irop.h"
#include "irnode_t.h"
#include "ircons.h"
#include "irprog_t.h"
#include "lowering.h"
#include "array.h"
#include "error.h"

#include "ia32_new_nodes.h"
#include "bearch_ia32_t.h"
#include "gen_ia32_regalloc_if.h"

/** The array of all intrinsics that must be mapped. */
static i_record *intrinsics;

/** An array to cache all entities. */
static ir_entity *i_ents[iro_Last + 1];

/*
 * Maps all intrinsic calls that the backend support
 * and map all instructions the backend did not support
 * to runtime calls.
 */
void ia32_handle_intrinsics(void) {
	if (intrinsics && ARR_LEN(intrinsics) > 0) {
		lower_intrinsics(intrinsics, ARR_LEN(intrinsics), /*part_block_used=*/1);
	}
}

#define BINOP_Left_Low   0
#define BINOP_Left_High  1
#define BINOP_Right_Low  2
#define BINOP_Right_High 3

/**
 * Reroute edges from the pn_Call_T_result proj of a call.
 *
 * @param proj   the pn_Call_T_result Proj
 * @param l_res  the lower 32 bit result
 * @param h_res  the upper 32 bit result or NULL
 * @param irg    the graph to replace on
 */
static void reroute_result(ir_node *proj, ir_node *l_res, ir_node *h_res, ir_graph *irg) {
	const ir_edge_t *edge, *next;

	foreach_out_edge_safe(proj, edge, next) {
		ir_node *proj = get_edge_src_irn(edge);
		long    pn    = get_Proj_proj(proj);

		if (pn == 0) {
			edges_reroute(proj, l_res, irg);
		} else if (pn == 1 && h_res != NULL) {
			edges_reroute(proj, h_res, irg);
		} else {
			panic("Unsupported Result-Proj from Call found");
		}
	}
}

/**
 * Replace a call be a tuple of l_res, h_res.
 *
 * @param call   the call node to replace
 * @param l_res  the lower 32 bit result
 * @param h_res  the upper 32 bit result or NULL
 * @param irg    the graph to replace on
 * @param block  the block to replace on (always the call block)
 */
static void resolve_call(ir_node *call, ir_node *l_res, ir_node *h_res, ir_graph *irg, ir_node *block) {
	ir_node *jmp, *res, *in[2];
	ir_node *bad   = get_irg_bad(irg);
	ir_node *nomem = get_irg_no_mem(irg);
	int     old_cse;

	if (edges_activated(irg)) {
		/* use rerouting to prevent some warning in the backend */
		const ir_edge_t *edge, *next;

		foreach_out_edge_safe(call, edge, next) {
			ir_node *proj = get_edge_src_irn(edge);
			pn_Call pn    = get_Proj_proj(proj);

			switch (pn) {
			case pn_Call_X_regular:
				/* Beware:
				 * We do not check here if this call really has exception and regular Proj's.
				 * new_r_Jmp might than be CSEd with the real exit jmp and then bad things happen
				 * (in movgen.c from 186.crafty for example).
				 * So be sure the newly created Jmp cannot CSE.
				 */
				old_cse = get_opt_cse();
				set_opt_cse(0);
				jmp = new_r_Jmp(irg, block);
				set_opt_cse(old_cse);
				edges_reroute(proj, jmp, irg);
				break;

			case pn_Call_X_except:
			case pn_Call_P_value_res_base:
				/* should not happen here */
				edges_reroute(proj, bad, irg);
				break;
			case pn_Call_M_except:
				/* should not happen here */
				edges_reroute(proj, nomem, irg);
				break;
			case pn_Call_T_result:
				reroute_result(proj, l_res, h_res, irg);
				break;
			default:
				panic("Wrong Proj from Call");
			}
			kill_node(proj);
		}
		kill_node(call);
	} else {
		/* no edges, build Tuple */
		if (h_res == NULL)
			res = l_res;
		else {
			in[0] = l_res;
			in[1] = h_res;
			res = new_r_Tuple(irg, block, 2, in);
		}

		turn_into_tuple(call, pn_Call_max);
		set_Tuple_pred(call, pn_Call_M_regular,        nomem);
		/*
		 * Beware:
		 * We do not check here if this call really has exception and regular Proj's.
		 * new_r_Jmp might than be CSEd with the real exit jmp and then bad things happen
		 * (in movgen.c from 186.crafty for example).
		 * So be sure the newly created Jmp cannot CSE.
		 */
		old_cse = get_opt_cse();
		set_opt_cse(0);
		jmp = new_r_Jmp(irg, block);
		set_opt_cse(old_cse);

		set_Tuple_pred(call, pn_Call_X_regular,        jmp);
		set_Tuple_pred(call, pn_Call_X_except,         bad);
		set_Tuple_pred(call, pn_Call_T_result,         res);
		set_Tuple_pred(call, pn_Call_M_except,         nomem);
		set_Tuple_pred(call, pn_Call_P_value_res_base, bad);
	}
}

{'fraction_non_alphanumeric': 0.09857761286332715, 'fraction_numerical': 0.010265924551638838, 'mean_word_length': 3.578708946772367, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3368826', 'n_tokens_mistral': 3169, 'n_tokens_neox': 2921, 'n_words': 925}