<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 functions to finalize the irg for emit.
 * @author  <NAME>
 * @version $Id$
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "irnode.h"
#include "ircons.h"
#include "irgmod.h"
#include "irgwalk.h"
#include "iredges.h"
#include "irprintf.h"
#include "pdeq.h"
#include "error.h"

#include "../bearch_t.h"
#include "../besched_t.h"
#include "../benode_t.h"

#include "bearch_ia32_t.h"
#include "ia32_finish.h"
#include "ia32_new_nodes.h"
#include "ia32_map_regs.h"
#include "ia32_transform.h"
#include "ia32_dbg_stat.h"
#include "ia32_optimize.h"
#include "gen_ia32_regalloc_if.h"

DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)

/**
 * Transforms a Sub or xSub into Neg--Add iff OUT_REG == SRC2_REG.
 * THIS FUNCTIONS MUST BE CALLED AFTER REGISTER ALLOCATION.
 */
static void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) {
	ir_graph *irg;
	ir_node *in1, *in2, *noreg, *nomem, *res;
	ir_node *noreg_fp, *block;
	dbg_info *dbg;
	const arch_register_t *in1_reg, *in2_reg, *out_reg;

	/* fix_am will solve this for AddressMode variants */
	if(get_ia32_op_type(irn) != ia32_Normal)
		return;

	noreg    = ia32_new_NoReg_gp(cg);
	noreg_fp = ia32_new_NoReg_xmm(cg);
	nomem    = new_rd_NoMem(cg->irg);
	in1      = get_irn_n(irn, n_ia32_binary_left);
	in2      = get_irn_n(irn, n_ia32_binary_right);
	in1_reg  = arch_get_irn_register(cg->arch_env, in1);
	in2_reg  = arch_get_irn_register(cg->arch_env, in2);
	out_reg  = get_ia32_out_reg(irn, 0);

	irg     = cg->irg;
	block   = get_nodes_block(irn);

	/* in case of sub and OUT == SRC2 we can transform the sequence into neg src2 -- add */
	if (out_reg != in2_reg)
		return;

	dbg = get_irn_dbg_info(irn);

	/* generate the neg src2 */
	if(is_ia32_xSub(irn)) {
		int size;
		ir_entity *entity;
		ir_mode *op_mode = get_ia32_ls_mode(irn);

		assert(get_irn_mode(irn) != mode_T);

		res = new_rd_ia32_xXor(dbg, irg, block, noreg, noreg, nomem, in2, noreg_fp);
		size = get_mode_size_bits(op_mode);
		entity = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
		set_ia32_am_sc(res, entity);
		set_ia32_op_type(res, ia32_AddrModeS);
		set_ia32_ls_mode(res, op_mode);

		arch_set_irn_register(cg->arch_env, res, in2_reg);

		/* add to schedule */
		sched_add_before(irn, res);

		/* generate the add */
		res = new_rd_ia32_xAdd(dbg, irg, block, noreg, noreg, nomem, res, in1);
		set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);
		set_ia32_ls_mode(res, get_ia32_ls_mode(irn));

		/* exchange the add and the sub */
		edges_reroute(irn, res, irg);

		/* add to schedule */
		sched_add_before(irn, res);
	} else {
		ir_node         *res_proj   = NULL;
		ir_node         *flags_proj = NULL;
		const ir_edge_t *edge;

		if(get_irn_mode(irn) == mode_T) {
			/* collect the Proj uses */
			foreach_out_edge(irn, edge) {
				ir_node *proj = get_edge_src_irn(edge);
				long     pn   = get_Proj_proj(proj);
				if(pn == pn_ia32_Sub_res) {
					assert(res_proj == NULL);
					res_proj = proj;
				} else {
					assert(pn == pn_ia32_Sub_flags);<commit_msg>Remove redudant set_ia32_am_support() call.<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 functions to finalize the irg for emit.
 * @author  <NAME>
 * @version $Id$
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "irnode.h"
#include "ircons.h"
#include "irgmod.h"
#include "irgwalk.h"
#include "iredges.h"
#include "irprintf.h"
#include "pdeq.h"
#include "error.h"

#include "../bearch_t.h"
#include "../besched_t.h"
#include "../benode_t.h"

#include "bearch_ia32_t.h"
#include "ia32_finish.h"
#include "ia32_new_nodes.h"
#include "ia32_map_regs.h"
#include "ia32_transform.h"
#include "ia32_dbg_stat.h"
#include "ia32_optimize.h"
#include "gen_ia32_regalloc_if.h"

DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)

/**
 * Transforms a Sub or xSub into Neg--Add iff OUT_REG == SRC2_REG.
 * THIS FUNCTIONS MUST BE CALLED AFTER REGISTER ALLOCATION.
 */
static void ia32_transform_sub_to_neg_add(ir_node *irn, ia32_code_gen_t *cg) {
	ir_graph *irg;
	ir_node *in1, *in2, *noreg, *nomem, *res;
	ir_node *noreg_fp, *block;
	dbg_info *dbg;
	const arch_register_t *in1_reg, *in2_reg, *out_reg;

	/* fix_am will solve this for AddressMode variants */
	if(get_ia32_op_type(irn) != ia32_Normal)
		return;

	noreg    = ia32_new_NoReg_gp(cg);
	noreg_fp = ia32_new_NoReg_xmm(cg);
	nomem    = new_rd_NoMem(cg->irg);
	in1      = get_irn_n(irn, n_ia32_binary_left);
	in2      = get_irn_n(irn, n_ia32_binary_right);
	in1_reg  = arch_get_irn_register(cg->arch_env, in1);
	in2_reg  = arch_get_irn_register(cg->arch_env, in2);
	out_reg  = get_ia32_out_reg(irn, 0);

	irg     = cg->irg;
	block   = get_nodes_block(irn);

	/* in case of sub and OUT == SRC2 we can transform the sequence into neg src2 -- add */
	if (out_reg != in2_reg)
		return;

	dbg = get_irn_dbg_info(irn);

	/* generate the neg src2 */
	if(is_ia32_xSub(irn)) {
		int size;
		ir_entity *entity;
		ir_mode *op_mode = get_ia32_ls_mode(irn);

		assert(get_irn_mode(irn) != mode_T);

		res = new_rd_ia32_xXor(dbg, irg, block, noreg, noreg, nomem, in2, noreg_fp);
		size = get_mode_size_bits(op_mode);
		entity = ia32_gen_fp_known_const(size == 32 ? ia32_SSIGN : ia32_DSIGN);
		set_ia32_am_sc(res, entity);
		set_ia32_op_type(res, ia32_AddrModeS);
		set_ia32_ls_mode(res, op_mode);

		arch_set_irn_register(cg->arch_env, res, in2_reg);

		/* add to schedule */
		sched_add_before(irn, res);

		/* generate the add */
		res = new_rd_ia32_xAdd(dbg, irg, block, noreg, noreg, nomem, res, in1);
		set_ia32_ls_mode(res, get_ia32_ls_mode(irn));

		/* exchange the add and the sub */
		edges_reroute(irn, res, irg);

		/* add to schedule */
		sched_add_before(irn, res);
	} else {
		ir_node         *res_proj   = NULL;
		ir_node         *flags_proj = NULL;
		const ir_edge_t *edge;

		if(get_irn_mode(irn) == mode_T) {
			/* collect the Proj uses */
			foreach_out_edge(irn, edge) {
				ir_node *proj = get_edge_src_irn(edge);
				long     pn   = get_Proj_proj(proj);
				if(pn == pn_ia32_Sub_res) {
					assert(res_proj == NULL);
					res_proj = proj;
				} else {
					assert(pn == pn_ia32_Sub_flags);
{'fraction_non_alphanumeric': 0.11686938127974617, 'fraction_numerical': 0.025912215758857746, 'mean_word_length': 4.097708894878706, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, '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': '6477517', 'n_tokens_mistral': 3294, 'n_tokens_neox': 3028, 'n_words': 741}