ia32_transform.c 82.6 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/**
Christian Würdig's avatar
Christian Würdig committed
2
3
 * This file implements the IR transformation from firm into ia32-Firm.
 * @author Christian Wuerdig
Christian Würdig's avatar
Christian Würdig committed
4
5
6
 * $Id$
 */

7
8
9
10
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

Christian Würdig's avatar
Christian Würdig committed
11
12
#include <limits.h>

Christian Würdig's avatar
Christian Würdig committed
13
#include "irargs_t.h"
14
15
16
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
Christian Würdig's avatar
Christian Würdig committed
17
18
19
#include "iropt_t.h"
#include "irop_t.h"
#include "irprog_t.h"
Christian Würdig's avatar
Christian Würdig committed
20
#include "iredges_t.h"
21
#include "irgmod.h"
Christian Würdig's avatar
Christian Würdig committed
22
#include "irvrfy.h"
23
24
#include "ircons.h"
#include "dbginfo.h"
25
#include "irprintf.h"
26
#include "debug.h"
27
#include "irdom.h"
Christian Würdig's avatar
Christian Würdig committed
28
#include "archop.h"     /* we need this for Min and Max nodes */
29

Christian Würdig's avatar
Christian Würdig committed
30
#include "../benode_t.h"
Christian Würdig's avatar
Christian Würdig committed
31
#include "../besched.h"
Christian Würdig's avatar
Christian Würdig committed
32
#include "../beabi.h"
Christian Würdig's avatar
Christian Würdig committed
33

34
#include "bearch_ia32_t.h"
35
36
37
#include "ia32_nodes_attr.h"
#include "ia32_transform.h"
#include "ia32_new_nodes.h"
Christian Würdig's avatar
Christian Würdig committed
38
#include "ia32_map_regs.h"
Christian Würdig's avatar
Christian Würdig committed
39
#include "ia32_dbg_stat.h"
40
#include "ia32_optimize.h"
41

Christian Würdig's avatar
Christian Würdig committed
42
43
#include "gen_ia32_regalloc_if.h"

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#define SFP_SIGN "0x80000000"
#define DFP_SIGN "0x8000000000000000"
#define SFP_ABS  "0x7FFFFFFF"
#define DFP_ABS  "0x7FFFFFFFFFFFFFFF"

#define TP_SFP_SIGN "ia32_sfp_sign"
#define TP_DFP_SIGN "ia32_dfp_sign"
#define TP_SFP_ABS  "ia32_sfp_abs"
#define TP_DFP_ABS  "ia32_dfp_abs"

#define ENT_SFP_SIGN "IA32_SFP_SIGN"
#define ENT_DFP_SIGN "IA32_DFP_SIGN"
#define ENT_SFP_ABS  "IA32_SFP_ABS"
#define ENT_DFP_ABS  "IA32_DFP_ABS"

59
60
extern ir_op *get_op_Mulh(void);

61
typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
Michael Beck's avatar
Michael Beck committed
62
									  ir_node *op1, ir_node *op2, ir_node *mem);
Christian Würdig's avatar
Christian Würdig committed
63

64
typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *base, ir_node *index, \
Michael Beck's avatar
Michael Beck committed
65
									 ir_node *op, ir_node *mem);
66

67
typedef enum {
68
	ia32_SSIGN, ia32_DSIGN, ia32_SABS, ia32_DABS, ia32_known_const_max
69
70
} ia32_known_const_t;

Christian Würdig's avatar
Christian Würdig committed
71
72
73
74
75
76
77
78
79
80
/****************************************************************************************************
 *                  _        _                        __                           _   _
 *                 | |      | |                      / _|                         | | (_)
 *  _ __   ___   __| | ___  | |_ _ __ __ _ _ __  ___| |_ ___  _ __ _ __ ___   __ _| |_ _  ___  _ __
 * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __|  _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
 * | | | | (_) | (_| |  __/ | |_| | | (_| | | | \__ \ || (_) | |  | | | | | | (_| | |_| | (_) | | | |
 * |_| |_|\___/ \__,_|\___|  \__|_|  \__,_|_| |_|___/_| \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
 *
 ****************************************************************************************************/

Christian Würdig's avatar
Christian Würdig committed
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/**
 * Returns 1 if irn is a Const representing 0, 0 otherwise
 */
static INLINE int is_ia32_Const_0(ir_node *irn) {
	return is_ia32_Const(irn) ? classify_tarval(get_ia32_Immop_tarval(irn)) == TV_CLASSIFY_NULL : 0;
}

/**
 * Returns 1 if irn is a Const representing 1, 0 otherwise
 */
static INLINE int is_ia32_Const_1(ir_node *irn) {
	return is_ia32_Const(irn) ? classify_tarval(get_ia32_Immop_tarval(irn)) == TV_CLASSIFY_ONE : 0;
}

Christian Würdig's avatar
Christian Würdig committed
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
 * Returns the Proj representing the UNKNOWN register for given mode.
 */
static ir_node *be_get_unknown_for_mode(ia32_code_gen_t *cg, ir_mode *mode) {
	be_abi_irg_t          *babi       = cg->birg->abi;
	const arch_register_t *unknwn_reg = NULL;

	if (mode_is_float(mode)) {
		unknwn_reg = USE_SSE2(cg) ? &ia32_xmm_regs[REG_XMM_UKNWN] : &ia32_vfp_regs[REG_VFP_UKNWN];
	}
	else {
		unknwn_reg = &ia32_gp_regs[REG_GP_UKNWN];
	}

	return be_abi_get_callee_save_irn(babi, unknwn_reg);
}

Christian Würdig's avatar
Christian Würdig committed
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
 * Gets the Proj with number pn from irn.
 */
static ir_node *get_proj_for_pn(const ir_node *irn, long pn) {
	const ir_edge_t *edge;
	ir_node   *proj;
	assert(get_irn_mode(irn) == mode_T && "need mode_T");

	foreach_out_edge(irn, edge) {
		proj = get_edge_src_irn(edge);

		if (get_Proj_proj(proj) == pn)
			return proj;
	}

	return NULL;
}

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/**
 * SSE convert of an integer node into a floating point node.
 */
static ir_node *gen_sse_conv_int2float(ia32_code_gen_t *cg, dbg_info *dbg, ir_graph *irg, ir_node *block,
                                       ir_node *in, ir_node *old_node, ir_mode *tgt_mode)
{
	ir_node *noreg = ia32_new_NoReg_gp(cg);
	ir_node *nomem = new_rd_NoMem(irg);

	ir_node *conv = new_rd_ia32_Conv_I2FP(dbg, irg, block, noreg, noreg, in, nomem);
	set_ia32_src_mode(conv, get_irn_mode(in));
	set_ia32_tgt_mode(conv, tgt_mode);
	set_ia32_am_support(conv, ia32_am_Source);
	SET_IA32_ORIG_NODE(conv, ia32_get_old_node_name(cg, old_node));

	return new_rd_Proj(dbg, irg, block, conv, tgt_mode, pn_ia32_Conv_I2FP_res);
}

148
/* Generates an entity for a known FP const (used for FP Neg + Abs) */
149
static ident *gen_fp_known_const(ir_mode *mode, ia32_known_const_t kct) {
150
151
152
153
154
155
156
157
158
159
160
161
162
	static const struct {
		const char *tp_name;
		const char *ent_name;
		const char *cnst_str;
	} names [ia32_known_const_max] = {
		{ TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN },	/* ia32_SSIGN */
		{ TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN },	/* ia32_DSIGN */
		{ TP_SFP_ABS,  ENT_SFP_ABS,  SFP_ABS },		/* ia32_SABS */
		{ TP_DFP_ABS,  ENT_DFP_ABS,  DFP_ABS }		/* ia32_DABS */
	};
	static struct entity *ent_cache[ia32_known_const_max];

	const char    *tp_name, *ent_name, *cnst_str;
163
164
165
166
	ir_type       *tp;
	ir_node       *cnst;
	ir_graph      *rem;
	entity        *ent;
167
	tarval        *tv;
168

Christian Würdig's avatar
Christian Würdig committed
169
	ent_name = names[kct].ent_name;
170
171
172
	if (! ent_cache[kct]) {
		tp_name  = names[kct].tp_name;
		cnst_str = names[kct].cnst_str;
173

174
		tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
175
176
177
178
179
180
181
182
183
184
185
186
		tp  = new_type_primitive(new_id_from_str(tp_name), mode);
		ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);

		set_entity_ld_ident(ent, get_entity_ident(ent));
		set_entity_visibility(ent, visibility_local);
		set_entity_variability(ent, variability_constant);
		set_entity_allocation(ent, allocation_static);

		/* we create a new entity here: It's initialization must resist on the
		    const code irg */
		rem = current_ir_graph;
		current_ir_graph = get_const_code_irg();
187
		cnst = new_Const(mode, tv);
188
189
190
191
		current_ir_graph = rem;

		set_atomic_ent_value(ent, cnst);

192
193
		/* cache the entry */
		ent_cache[kct] = ent;
194
	}
195
196

	return get_entity_ident(ent_cache[kct]);
197
198
}

Christian Würdig's avatar
Christian Würdig committed
199
200
201
202
#ifndef NDEBUG
/**
 * Prints the old node name on cg obst and returns a pointer to it.
 */
Christian Würdig's avatar
Christian Würdig committed
203
204
const char *ia32_get_old_node_name(ia32_code_gen_t *cg, ir_node *irn) {
	ia32_isa_t *isa = (ia32_isa_t *)cg->arch_env->isa;
205

Christian Würdig's avatar
Christian Würdig committed
206
	lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
Christian Würdig's avatar
Christian Würdig committed
207
	obstack_1grow(isa->name_obst, 0);
Christian Würdig's avatar
Christian Würdig committed
208
	isa->name_obst_size += obstack_object_size(isa->name_obst);
Christian Würdig's avatar
Christian Würdig committed
209
210
211
 	return obstack_finish(isa->name_obst);
}
#endif /* NDEBUG */
Christian Würdig's avatar
Christian Würdig committed
212

213
214
/* determine if one operator is an Imm */
static ir_node *get_immediate_op(ir_node *op1, ir_node *op2) {
Christian Würdig's avatar
Christian Würdig committed
215
	if (op1)
Christian Würdig's avatar
Christian Würdig committed
216
217
		return is_ia32_Cnst(op1) ? op1 : (is_ia32_Cnst(op2) ? op2 : NULL);
	else return is_ia32_Cnst(op2) ? op2 : NULL;
218
219
220
221
}

/* determine if one operator is not an Imm */
static ir_node *get_expr_op(ir_node *op1, ir_node *op2) {
Christian Würdig's avatar
Christian Würdig committed
222
	return !is_ia32_Cnst(op1) ? op1 : (!is_ia32_Cnst(op2) ? op2 : NULL);
223
224
225
226
227
228
229
230
231
232
233
234
235
}


/**
 * Construct a standard binary operation, set AM and immediate if required.
 *
 * @param env   The transformation environment
 * @param op1   The first operand
 * @param op2   The second operand
 * @param func  The node constructor function
 * @return The constructed ia32 node.
 */
static ir_node *gen_binop(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, construct_binop_func *func) {
236
237
238
239
240
241
242
243
	ir_node           *new_op   = NULL;
	ir_mode           *mode     = env->mode;
	dbg_info          *dbg      = env->dbg;
	ir_graph          *irg      = env->irg;
	ir_node           *block    = env->block;
	ir_node           *noreg_gp = ia32_new_NoReg_gp(env->cg);
	ir_node           *noreg_fp = ia32_new_NoReg_fp(env->cg);
	ir_node           *nomem    = new_NoMem();
244
	ir_node           *expr_op, *imm_op;
245
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
246

247
248
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
249
	if (! (env->cg->opt & IA32_OPT_IMMOPS)) {
250
251
252
253
		expr_op = op1;
		imm_op  = NULL;
	}
	else if (is_op_commutative(get_irn_op(env->irn))) {
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
		imm_op  = get_immediate_op(op1, op2);
		expr_op = get_expr_op(op1, op2);
	}
	else {
		imm_op  = get_immediate_op(NULL, op2);
		expr_op = get_expr_op(op1, op2);
	}

	assert((expr_op || imm_op) && "invalid operands");

	if (!expr_op) {
		/* We have two consts here: not yet supported */
		imm_op = NULL;
	}

	if (mode_is_float(mode)) {
		/* floating point operations */
		if (imm_op) {
272
			DB((mod, LEVEL_1, "FP with immediate ..."));
Michael Beck's avatar
Michael Beck committed
273
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_fp, nomem);
274
275
276
277
			set_ia32_Immop_attr(new_op, imm_op);
			set_ia32_am_support(new_op, ia32_am_None);
		}
		else {
278
			DB((mod, LEVEL_1, "FP binop ..."));
Michael Beck's avatar
Michael Beck committed
279
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem);
280
281
			set_ia32_am_support(new_op, ia32_am_Source);
		}
282
		set_ia32_ls_mode(new_op, mode);
283
284
285
286
287
	}
	else {
		/* integer operations */
		if (imm_op) {
			/* This is expr + const */
288
			DB((mod, LEVEL_1, "INT with immediate ..."));
Michael Beck's avatar
Michael Beck committed
289
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_gp, nomem);
290
291
292
293
294
295
			set_ia32_Immop_attr(new_op, imm_op);

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Dest);
		}
		else {
296
			DB((mod, LEVEL_1, "INT binop ..."));
297
			/* This is a normal operation */
Michael Beck's avatar
Michael Beck committed
298
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem);
299
300
301
302
303
304

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Full);
		}
	}

Christian Würdig's avatar
Christian Würdig committed
305
	SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
Christian Würdig's avatar
Christian Würdig committed
306

307
308
	set_ia32_res_mode(new_op, mode);

Christian Würdig's avatar
Christian Würdig committed
309
310
311
312
	if (is_op_commutative(get_irn_op(env->irn))) {
		set_ia32_commutative(new_op);
	}

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
	return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
}



/**
 * Construct a shift/rotate binary operation, sets AM and immediate if required.
 *
 * @param env   The transformation environment
 * @param op1   The first operand
 * @param op2   The second operand
 * @param func  The node constructor function
 * @return The constructed ia32 node.
 */
static ir_node *gen_shift_binop(ia32_transform_env_t *env, ir_node *op1, ir_node *op2, construct_binop_func *func) {
	ir_node           *new_op = NULL;
	ir_mode           *mode   = env->mode;
	dbg_info          *dbg    = env->dbg;
	ir_graph          *irg    = env->irg;
	ir_node           *block  = env->block;
333
	ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
334
335
336
	ir_node           *nomem  = new_NoMem();
	ir_node           *expr_op, *imm_op;
	tarval            *tv;
337
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
338
339
340

	assert(! mode_is_float(mode) && "Shift/Rotate with float not supported");

341
342
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
343
	imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, op2) : NULL;
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
	expr_op = get_expr_op(op1, op2);

	assert((expr_op || imm_op) && "invalid operands");

	if (!expr_op) {
		/* We have two consts here: not yet supported */
		imm_op = NULL;
	}

	/* Limit imm_op within range imm8 */
	if (imm_op) {
		tv = get_ia32_Immop_tarval(imm_op);

		if (tv) {
			tv = tarval_mod(tv, new_tarval_from_long(32, mode_Iu));
359
			set_ia32_Immop_tarval(imm_op, tv);
360
361
362
363
364
365
366
367
368
		}
		else {
			imm_op = NULL;
		}
	}

	/* integer operations */
	if (imm_op) {
		/* This is shift/rot with const */
369
		DB((mod, LEVEL_1, "Shift/Rot with immediate ..."));
370

Michael Beck's avatar
Michael Beck committed
371
		new_op = func(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
372
373
374
375
		set_ia32_Immop_attr(new_op, imm_op);
	}
	else {
		/* This is a normal shift/rot */
376
		DB((mod, LEVEL_1, "Shift/Rot binop ..."));
Michael Beck's avatar
Michael Beck committed
377
		new_op = func(dbg, irg, block, noreg, noreg, op1, op2, nomem);
378
379
380
381
382
	}

	/* set AM support */
	set_ia32_am_support(new_op, ia32_am_Dest);

Christian Würdig's avatar
Christian Würdig committed
383
	SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
Christian Würdig's avatar
Christian Würdig committed
384

385
	set_ia32_res_mode(new_op, mode);
Christian Würdig's avatar
Christian Würdig committed
386
	set_ia32_emit_cl(new_op);
387

388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
	return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
}


/**
 * Construct a standard unary operation, set AM and immediate if required.
 *
 * @param env   The transformation environment
 * @param op    The operand
 * @param func  The node constructor function
 * @return The constructed ia32 node.
 */
static ir_node *gen_unop(ia32_transform_env_t *env, ir_node *op, construct_unop_func *func) {
	ir_node           *new_op = NULL;
	ir_mode           *mode   = env->mode;
	dbg_info          *dbg    = env->dbg;
	ir_graph          *irg    = env->irg;
	ir_node           *block  = env->block;
406
	ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
407
	ir_node           *nomem  = new_NoMem();
408
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
409

Michael Beck's avatar
Michael Beck committed
410
	new_op = func(dbg, irg, block, noreg, noreg, op, nomem);
411
412

	if (mode_is_float(mode)) {
413
		DB((mod, LEVEL_1, "FP unop ..."));
414
415
416
417
		/* floating point operations don't support implicit store */
		set_ia32_am_support(new_op, ia32_am_None);
	}
	else {
418
		DB((mod, LEVEL_1, "INT unop ..."));
419
420
421
		set_ia32_am_support(new_op, ia32_am_Dest);
	}

Christian Würdig's avatar
Christian Würdig committed
422
	SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
Christian Würdig's avatar
Christian Würdig committed
423

424
425
	set_ia32_res_mode(new_op, mode);

426
	return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
427
428
429
430
431
432
433
}



/**
 * Creates an ia32 Add with immediate.
 *
434
435
436
437
 * @param env       The transformation environment
 * @param expr_op   The expression operator
 * @param const_op  The constant
 * @return the created ia32 Add node
438
 */
Christian Würdig's avatar
Christian Würdig committed
439
static ir_node *gen_imm_Add(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
440
441
442
443
444
	ir_node                *new_op     = NULL;
	tarval                 *tv         = get_ia32_Immop_tarval(const_op);
	dbg_info               *dbg        = env->dbg;
	ir_graph               *irg        = env->irg;
	ir_node                *block      = env->block;
445
	ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
446
447
	ir_node                *nomem      = new_NoMem();
	int                     normal_add = 1;
Christian Würdig's avatar
Christian Würdig committed
448
	tarval_classification_t class_tv, class_negtv;
449
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
Christian Würdig's avatar
Christian Würdig committed
450

451
	/* try to optimize to inc/dec  */
452
	if ((env->cg->opt & IA32_OPT_INCDEC) && (get_ia32_op_type(const_op) == ia32_Const)) {
Christian Würdig's avatar
Christian Würdig committed
453
454
455
456
457
		/* optimize tarvals */
		class_tv    = classify_tarval(tv);
		class_negtv = classify_tarval(tarval_neg(tv));

		if (class_tv == TV_CLASSIFY_ONE) { /* + 1 == INC */
Christian Würdig's avatar
Christian Würdig committed
458
			DB((env->mod, LEVEL_2, "Add(1) to Inc ... "));
Michael Beck's avatar
Michael Beck committed
459
			new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
460
			normal_add = 0;
Christian Würdig's avatar
Christian Würdig committed
461
462
		}
		else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
Christian Würdig's avatar
Christian Würdig committed
463
			DB((mod, LEVEL_2, "Add(-1) to Dec ... "));
Michael Beck's avatar
Michael Beck committed
464
			new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
465
			normal_add = 0;
Christian Würdig's avatar
Christian Würdig committed
466
467
468
		}
	}

469
	if (normal_add) {
Michael Beck's avatar
Michael Beck committed
470
		new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
471
		set_ia32_Immop_attr(new_op, const_op);
472
		set_ia32_commutative(new_op);
473
	}
Christian Würdig's avatar
Christian Würdig committed
474
475

	return new_op;
476
477
478
479
480
}

/**
 * Creates an ia32 Add.
 *
481
 * @param env   The transformation environment
482
483
 * @return the created ia32 Add node
 */
484
static ir_node *gen_Add(ia32_transform_env_t *env) {
485
486
487
488
489
	ir_node  *new_op = NULL;
	dbg_info *dbg    = env->dbg;
	ir_mode  *mode   = env->mode;
	ir_graph *irg    = env->irg;
	ir_node  *block  = env->block;
490
	ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
491
492
	ir_node  *nomem  = new_NoMem();
	ir_node  *expr_op, *imm_op;
493
494
	ir_node  *op1    = get_Add_left(env->irn);
	ir_node  *op2    = get_Add_right(env->irn);
495

496
497
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
498
	imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(op1, op2) : NULL;
499
500
501
	expr_op = get_expr_op(op1, op2);

	assert((expr_op || imm_op) && "invalid operands");
Christian Würdig's avatar
Christian Würdig committed
502
503

	if (mode_is_float(mode)) {
504
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
505
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
506
			return gen_binop(env, op1, op2, new_rd_ia32_xAdd);
507
		else
Michael Beck's avatar
Michael Beck committed
508
			return gen_binop(env, op1, op2, new_rd_ia32_vfadd);
Christian Würdig's avatar
Christian Würdig committed
509
	}
510
511
512
513
514
515
	else {
		/* integer ADD */
		if (!expr_op) {
			/* No expr_op means, that we have two const - one symconst and */
			/* one tarval or another symconst - because this case is not   */
			/* covered by constant folding                                 */
516
517
518
519
520
521
522
523
524
525
			/* We need to check for:                                       */
			/*  1) symconst + const    -> becomes a LEA                    */
			/*  2) symconst + symconst -> becomes a const + LEA as the elf */
			/*        linker doesn't support two symconsts                 */

			if (get_ia32_op_type(op1) == ia32_SymConst && get_ia32_op_type(op2) == ia32_SymConst) {
				/* this is the 2nd case */
				new_op = new_rd_ia32_Lea(dbg, irg, block, op1, noreg, mode);
				set_ia32_am_sc(new_op, get_ia32_id_cnst(op2));
				set_ia32_am_flavour(new_op, ia32_am_OB);
Christian Würdig's avatar
Christian Würdig committed
526
527

				DBG_OPT_LEA1(op2, new_op);
528
529
530
531
532
			}
			else {
				/* this is the 1st case */
				new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode);

Christian Würdig's avatar
Christian Würdig committed
533
534
				DBG_OPT_LEA2(op1, op2, new_op);

535
536
537
538
539
540
541
542
543
544
				if (get_ia32_op_type(op1) == ia32_SymConst) {
					set_ia32_am_sc(new_op, get_ia32_id_cnst(op1));
					add_ia32_am_offs(new_op, get_ia32_cnst(op2));
				}
				else {
					add_ia32_am_offs(new_op, get_ia32_cnst(op1));
					set_ia32_am_sc(new_op, get_ia32_id_cnst(op2));
				}
				set_ia32_am_flavour(new_op, ia32_am_O);
			}
545
546
547
548

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Source);
			set_ia32_op_type(new_op, ia32_AddrModeS);
549
550
551

			/* Lea doesn't need a Proj */
			return new_op;
Christian Würdig's avatar
Christian Würdig committed
552
		}
553
554
555
		else if (imm_op) {
			/* This is expr + const */
			new_op = gen_imm_Add(env, expr_op, imm_op);
Christian Würdig's avatar
Christian Würdig committed
556

557
558
559
560
561
			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Dest);
		}
		else {
			/* This is a normal add */
Michael Beck's avatar
Michael Beck committed
562
			new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, op1, op2, nomem);
Christian Würdig's avatar
Christian Würdig committed
563

564
565
			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Full);
566
			set_ia32_commutative(new_op);
567
		}
Christian Würdig's avatar
Christian Würdig committed
568
569
	}

Christian Würdig's avatar
Christian Würdig committed
570
	SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
Christian Würdig's avatar
Christian Würdig committed
571

572
573
	set_ia32_res_mode(new_op, mode);

574
	return new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Add_res);
Christian Würdig's avatar
Christian Würdig committed
575
576
577
578
}



579
580
581
/**
 * Creates an ia32 Mul.
 *
582
 * @param env   The transformation environment
583
584
 * @return the created ia32 Mul node
 */
585
586
587
static ir_node *gen_Mul(ia32_transform_env_t *env) {
	ir_node *op1 = get_Mul_left(env->irn);
	ir_node *op2 = get_Mul_right(env->irn);
588
589
	ir_node *new_op;

Christian Würdig's avatar
Christian Würdig committed
590
	if (mode_is_float(env->mode)) {
591
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
592
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
593
			new_op = gen_binop(env, op1, op2, new_rd_ia32_xMul);
594
		else
Michael Beck's avatar
Michael Beck committed
595
			new_op = gen_binop(env, op1, op2, new_rd_ia32_vfmul);
Christian Würdig's avatar
Christian Würdig committed
596
597
	}
	else {
598
		new_op = gen_binop(env, op1, op2, new_rd_ia32_Mul);
Christian Würdig's avatar
Christian Würdig committed
599
	}
600

601
602
	return new_op;
}
603
604
605
606
607
608
609
610



/**
 * Creates an ia32 Mulh.
 * Note: Mul produces a 64Bit result and Mulh returns the upper 32 bit of
 * this result while Mul returns the lower 32 bit.
 *
611
 * @param env   The transformation environment
612
613
 * @return the created ia32 Mulh node
 */
614
615
616
static ir_node *gen_Mulh(ia32_transform_env_t *env) {
	ir_node *op1 = get_irn_n(env->irn, 0);
	ir_node *op2 = get_irn_n(env->irn, 1);
617
618
	ir_node *proj_EAX, *proj_EDX, *mulh;
	ir_node *in[1];
619

Daniel Grund's avatar
Daniel Grund committed
620
	assert(!mode_is_float(env->mode) && "Mulh with float not supported");
621
622
623
	proj_EAX = gen_binop(env, op1, op2, new_rd_ia32_Mulh);
	mulh     = get_Proj_pred(proj_EAX);
	proj_EDX = new_rd_Proj(env->dbg, env->irg, env->block, mulh, env->mode, pn_EDX);
624

625
626
	/* to be on the save side */
	set_Proj_proj(proj_EAX, pn_EAX);
627

628
	if (is_ia32_ImmConst(mulh) || is_ia32_ImmSymConst(mulh)) {
629
630
631
632
633
634
635
636
637
638
639
640
641
642
		/* Mulh with const cannot have AM */
		set_ia32_am_support(mulh, ia32_am_None);
	}
	else {
		/* Mulh cannot have AM for destination */
		set_ia32_am_support(mulh, ia32_am_Source);
	}

	in[0] = proj_EAX;

	/* keep EAX */
	be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], env->irg, env->block, 1, in);

	return proj_EDX;
643
644
}

645
646


647
648
649
/**
 * Creates an ia32 And.
 *
650
651
 * @param env   The transformation environment
 * @return The created ia32 And node
652
 */
653
654
655
656
static ir_node *gen_And(ia32_transform_env_t *env) {
	ir_node *op1 = get_And_left(env->irn);
	ir_node *op2 = get_And_right(env->irn);

Michael Beck's avatar
Michael Beck committed
657
658
	assert (! mode_is_float(env->mode));
	return gen_binop(env, op1, op2, new_rd_ia32_And);
659
660
661
662
663
664
665
}



/**
 * Creates an ia32 Or.
 *
666
667
 * @param env   The transformation environment
 * @return The created ia32 Or node
668
 */
669
670
671
672
static ir_node *gen_Or(ia32_transform_env_t *env) {
	ir_node *op1 = get_Or_left(env->irn);
	ir_node *op2 = get_Or_right(env->irn);

Michael Beck's avatar
Michael Beck committed
673
674
	assert (! mode_is_float(env->mode));
	return gen_binop(env, op1, op2, new_rd_ia32_Or);
675
676
677
678
679
680
681
}



/**
 * Creates an ia32 Eor.
 *
682
683
 * @param env   The transformation environment
 * @return The created ia32 Eor node
684
 */
685
686
687
688
static ir_node *gen_Eor(ia32_transform_env_t *env) {
	ir_node *op1 = get_Eor_left(env->irn);
	ir_node *op2 = get_Eor_right(env->irn);

Michael Beck's avatar
Michael Beck committed
689
690
	assert(! mode_is_float(env->mode));
	return gen_binop(env, op1, op2, new_rd_ia32_Eor);
691
692
693
694
695
696
697
}



/**
 * Creates an ia32 Max.
 *
698
699
 * @param env      The transformation environment
 * @return the created ia32 Max node
700
 */
701
702
703
static ir_node *gen_Max(ia32_transform_env_t *env) {
	ir_node *op1 = get_irn_n(env->irn, 0);
	ir_node *op2 = get_irn_n(env->irn, 1);
704
705
706
	ir_node *new_op;

	if (mode_is_float(env->mode)) {
707
		FP_USED(env->cg);
708
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
709
			new_op = gen_binop(env, op1, op2, new_rd_ia32_xMax);
710
711
712
		else {
			assert(0);
		}
713
714
715
716
	}
	else {
		new_op = new_rd_ia32_Max(env->dbg, env->irg, env->block, op1, op2, env->mode);
		set_ia32_am_support(new_op, ia32_am_None);
Christian Würdig's avatar
Christian Würdig committed
717
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
718
719
720
	}

	return new_op;
721
722
723
724
725
726
727
}



/**
 * Creates an ia32 Min.
 *
728
729
 * @param env      The transformation environment
 * @return the created ia32 Min node
730
 */
731
732
733
static ir_node *gen_Min(ia32_transform_env_t *env) {
	ir_node *op1 = get_irn_n(env->irn, 0);
	ir_node *op2 = get_irn_n(env->irn, 1);
734
735
736
	ir_node *new_op;

	if (mode_is_float(env->mode)) {
737
		FP_USED(env->cg);
738
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
739
			new_op = gen_binop(env, op1, op2, new_rd_ia32_xMin);
740
741
742
		else {
			assert(0);
		}
743
744
745
746
	}
	else {
		new_op = new_rd_ia32_Min(env->dbg, env->irg, env->block, op1, op2, env->mode);
		set_ia32_am_support(new_op, ia32_am_None);
Christian Würdig's avatar
Christian Würdig committed
747
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
748
749
750
	}

	return new_op;
751
752
753
754
755
756
757
}



/**
 * Creates an ia32 Sub with immediate.
 *
758
759
760
 * @param env        The transformation environment
 * @param expr_op    The first operator
 * @param const_op   The constant operator
761
 * @return The created ia32 Sub node
762
 */
Christian Würdig's avatar
Christian Würdig committed
763
static ir_node *gen_imm_Sub(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
764
765
766
767
768
	ir_node                *new_op     = NULL;
	tarval                 *tv         = get_ia32_Immop_tarval(const_op);
	dbg_info               *dbg        = env->dbg;
	ir_graph               *irg        = env->irg;
	ir_node                *block      = env->block;
769
	ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
770
771
	ir_node                *nomem      = new_NoMem();
	int                     normal_sub = 1;
Christian Würdig's avatar
Christian Würdig committed
772
	tarval_classification_t class_tv, class_negtv;
773
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
Christian Würdig's avatar
Christian Würdig committed
774

775
	/* try to optimize to inc/dec  */
776
	if ((env->cg->opt & IA32_OPT_INCDEC) && tv) {
Christian Würdig's avatar
Christian Würdig committed
777
778
779
780
781
		/* optimize tarvals */
		class_tv    = classify_tarval(tv);
		class_negtv = classify_tarval(tarval_neg(tv));

		if (class_tv == TV_CLASSIFY_ONE) { /* - 1 == DEC */
Christian Würdig's avatar
Christian Würdig committed
782
			DB((mod, LEVEL_2, "Sub(1) to Dec ... "));
Michael Beck's avatar
Michael Beck committed
783
			new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
784
			normal_sub = 0;
Christian Würdig's avatar
Christian Würdig committed
785
786
		}
		else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
Christian Würdig's avatar
Christian Würdig committed
787
			DB((mod, LEVEL_2, "Sub(-1) to Inc ... "));
Michael Beck's avatar
Michael Beck committed
788
			new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
789
			normal_sub = 0;
Christian Würdig's avatar
Christian Würdig committed
790
791
792
		}
	}

793
	if (normal_sub) {
Michael Beck's avatar
Michael Beck committed
794
		new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
795
796
		set_ia32_Immop_attr(new_op, const_op);
	}
Christian Würdig's avatar
Christian Würdig committed
797
798

	return new_op;
799
800
801
802
803
}

/**
 * Creates an ia32 Sub.
 *
804
805
 * @param env   The transformation environment
 * @return The created ia32 Sub node
806
 */
807
static ir_node *gen_Sub(ia32_transform_env_t *env) {
808
809
810
811
812
	ir_node  *new_op = NULL;
	dbg_info *dbg    = env->dbg;
	ir_mode  *mode   = env->mode;
	ir_graph *irg    = env->irg;
	ir_node  *block  = env->block;
813
	ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
814
	ir_node  *nomem  = new_NoMem();
815
816
	ir_node  *op1    = get_Sub_left(env->irn);
	ir_node  *op2    = get_Sub_right(env->irn);
817
818
	ir_node  *expr_op, *imm_op;

819
820
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
821
	imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, op2) : NULL;
822
823
824
825
826
	expr_op = get_expr_op(op1, op2);

	assert((expr_op || imm_op) && "invalid operands");

	if (mode_is_float(mode)) {
827
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
828
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
829
			return gen_binop(env, op1, op2, new_rd_ia32_xSub);
830
		else
Michael Beck's avatar
Michael Beck committed
831
			return gen_binop(env, op1, op2, new_rd_ia32_vfsub);
Christian Würdig's avatar
Christian Würdig committed
832
	}
833
834
835
836
837
838
	else {
		/* integer SUB */
		if (!expr_op) {
			/* No expr_op means, that we have two const - one symconst and */
			/* one tarval or another symconst - because this case is not   */
			/* covered by constant folding                                 */
839
840
841
842
843
844
845
846
847
848
849
			/* We need to check for:                                       */
			/*  1) symconst + const    -> becomes a LEA                    */
			/*  2) symconst + symconst -> becomes a const + LEA as the elf */
			/*        linker doesn't support two symconsts                 */

			if (get_ia32_op_type(op1) == ia32_SymConst && get_ia32_op_type(op2) == ia32_SymConst) {
				/* this is the 2nd case */
				new_op = new_rd_ia32_Lea(dbg, irg, block, op1, noreg, mode);
				set_ia32_am_sc(new_op, get_ia32_id_cnst(op2));
				set_ia32_am_sc_sign(new_op);
				set_ia32_am_flavour(new_op, ia32_am_OB);
Christian Würdig's avatar
Christian Würdig committed
850
851

				DBG_OPT_LEA1(op2, new_op);
852
853
854
855
856
			}
			else {
				/* this is the 1st case */
				new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode);

Christian Würdig's avatar
Christian Würdig committed
857
858
				DBG_OPT_LEA2(op1, op2, new_op);

859
860
861
862
863
864
865
866
867
868
869
				if (get_ia32_op_type(op1) == ia32_SymConst) {
					set_ia32_am_sc(new_op, get_ia32_id_cnst(op1));
					sub_ia32_am_offs(new_op, get_ia32_cnst(op2));
				}
				else {
					add_ia32_am_offs(new_op, get_ia32_cnst(op1));
					set_ia32_am_sc(new_op, get_ia32_id_cnst(op2));
					set_ia32_am_sc_sign(new_op);
				}
				set_ia32_am_flavour(new_op, ia32_am_O);
			}
870
871
872
873

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Source);
			set_ia32_op_type(new_op, ia32_AddrModeS);
874
875
876

			/* Lea doesn't need a Proj */
			return new_op;
877
878
879
880
881
882
883
884
885
886
		}
		else if (imm_op) {
			/* This is expr - const */
			new_op = gen_imm_Sub(env, expr_op, imm_op);

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Dest);
		}
		else {
			/* This is a normal sub */
Michael Beck's avatar
Michael Beck committed
887
			new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, op1, op2, nomem);
888
889
890
891
892
893

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Full);
		}
	}

Christian Würdig's avatar
Christian Würdig committed
894
	SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
Christian Würdig's avatar
Christian Würdig committed
895

896
897
	set_ia32_res_mode(new_op, mode);

898
	return new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Sub_res);
899
900
}

Christian Würdig's avatar
Christian Würdig committed
901

902
903

/**
Christian Würdig's avatar
Christian Würdig committed
904
905
 * Generates an ia32 DivMod with additional infrastructure for the
 * register allocator if needed.
906
 *
Christian Würdig's avatar
Christian Würdig committed
907
908
909
910
911
912
 * @param env      The transformation environment
 * @param dividend -no comment- :)
 * @param divisor  -no comment- :)
 * @param dm_flav  flavour_Div/Mod/DivMod
 * @return The created ia32 DivMod node
 */
913
static ir_node *generate_DivMod(ia32_transform_env_t *env, ir_node *dividend, ir_node *divisor, ia32_op_flavour_t dm_flav) {
Christian Würdig's avatar
Christian Würdig committed
914
915
916
917
918
919
920
921
	ir_node  *res, *proj;
	ir_node  *edx_node, *cltd;
	ir_node  *in_keep[1];
	dbg_info *dbg   = env->dbg;
	ir_graph *irg   = env->irg;
	ir_node  *block = env->block;
	ir_mode  *mode  = env->mode;
	ir_node  *irn   = env->irn;
922
923
924
925
	ir_node  *mem;

	switch (dm_flav) {
		case flavour_Div:
Christian Würdig's avatar
Christian Würdig committed
926
927
			mem  = get_Div_mem(irn);
			mode = get_irn_mode(get_proj_for_pn(irn, pn_Div_res));
928
929
			break;
		case flavour_Mod:
Christian Würdig's avatar
Christian Würdig committed
930
931
			mem  = get_Mod_mem(irn);
			mode = get_irn_mode(get_proj_for_pn(irn, pn_Mod_res));
932
933
			break;
		case flavour_DivMod:
Christian Würdig's avatar
Christian Würdig committed
934
935
			mem  = get_DivMod_mem(irn);
			mode = get_irn_mode(get_proj_for_pn(irn, pn_DivMod_res_div));
936
937
938
939
			break;
		default:
			assert(0);
	}
Christian Würdig's avatar
Christian Würdig committed
940
941
942

	if (mode_is_signed(mode)) {
		/* in signed mode, we need to sign extend the dividend */
Michael Beck's avatar
Michael Beck committed
943
944
945
		cltd     = new_rd_ia32_Cdq(dbg, irg, block, dividend);
		dividend = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_ia32_Cdq_EAX);
		edx_node = new_rd_Proj(dbg, irg, block, cltd, mode_Is, pn_ia32_Cdq_EDX);
Christian Würdig's avatar
Christian Würdig committed
946
947
	}
	else {
948
		edx_node = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode_Iu);
949
		set_ia32_Const_type(edx_node, ia32_Const);
Christian Würdig's avatar
Christian Würdig committed
950
951
952
		set_ia32_Immop_tarval(edx_node, get_tarval_null(mode_Iu));
	}

Michael Beck's avatar
Michael Beck committed
953
	res = new_rd_ia32_DivMod(dbg, irg, block, dividend, divisor, edx_node, mem, dm_flav);
Christian Würdig's avatar
Christian Würdig committed
954
955
956
957
958
959
960
961
962
963

	set_ia32_n_res(res, 2);

	/* Only one proj is used -> We must add a second proj and */
	/* connect this one to a Keep node to eat up the second   */
	/* destroyed register.                                    */
	if (get_irn_n_edges(irn) == 1) {
		proj = get_edge_src_irn(get_irn_out_edge_first(irn));
		assert(is_Proj(proj) && "non-Proj to Div/Mod node");

964
965
		if (get_irn_op(irn) == op_Div) {
			set_Proj_proj(proj, pn_DivMod_res_div);
Christian Würdig's avatar
Christian Würdig committed
966
967
968
			in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Is, pn_DivMod_res_mod);
		}
		else {
969
			set_Proj_proj(proj, pn_DivMod_res_mod);
Christian Würdig's avatar
Christian Würdig committed
970
971
972
			in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode_Is, pn_DivMod_res_div);
		}

973
		be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
Christian Würdig's avatar
Christian Würdig committed
974
975
	}

Christian Würdig's avatar
Christian Würdig committed
976
	SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env->cg, env->irn));
Christian Würdig's avatar
Christian Würdig committed
977

978
979
	set_ia32_res_mode(res, mode_Is);

Christian Würdig's avatar
Christian Würdig committed
980
981
982
983
984
985
	return res;
}


/**
 * Wrapper for generate_DivMod. Sets flavour_Mod.
986
987
 *
 * @param env      The transformation environment
988
 */
989
990
static ir_node *gen_Mod(ia32_transform_env_t *env) {
	return generate_DivMod(env, get_Mod_left(env->irn), get_Mod_right(env->irn), flavour_Mod);
991
992
993
}

/**
Christian Würdig's avatar
Christian Würdig committed
994
 * Wrapper for generate_DivMod. Sets flavour_Div.
995
996
 *
 * @param env      The transformation environment
997
 */
998
999
static ir_node *gen_Div(ia32_transform_env_t *env) {
	return generate_DivMod(env, get_Div_left(env->irn), get_Div_right(env->irn), flavour_Div);
1000
1001
1002
}

/**
Christian Würdig's avatar
Christian Würdig committed
1003
 * Wrapper for generate_DivMod. Sets flavour_DivMod.
1004
 */
1005
1006
static ir_node *gen_DivMod(ia32_transform_env_t *env) {
	return generate_DivMod(env, get_DivMod_left(env->irn), get_DivMod_right(env->irn), flavour_DivMod);
Christian Würdig's avatar
Christian Würdig committed
1007
1008
1009
1010
1011
1012
1013
}



/**
 * Creates an ia32 floating Div.
 *
1014
 * @param env   The transformation environment
Christian Würdig's avatar
Christian Würdig committed
1015
 * @return The created ia32 xDiv node
Christian Würdig's avatar
Christian Würdig committed
1016
 */
1017
static ir_node *gen_Quot(ia32_transform_env_t *env) {
Christian Würdig's avatar
Christian Würdig committed
1018
1019
	ir_node *noreg = ia32_new_NoReg_gp(env->cg);
	ir_node *new_op;
Michael Beck's avatar
Michael Beck committed
1020
	ir_node *nomem = new_rd_NoMem(env->irg);
1021
1022
	ir_node *op1   = get_Quot_left(env->irn);
	ir_node *op2   = get_Quot_right(env->irn);
Christian Würdig's avatar
Christian Würdig committed
1023

1024
	FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
1025
	if (USE_SSE2(env->cg)) {
Christian Würdig's avatar
Christian Würdig committed
1026
		if (is_ia32_xConst(op2)) {
Michael Beck's avatar
Michael Beck committed
1027
			new_op = new_rd_ia32_xDiv(env->dbg, env->irg, env->block, noreg, noreg, op1, noreg, nomem);
Michael Beck's avatar
Michael Beck committed
1028
1029
1030
1031
			set_ia32_am_support(new_op, ia32_am_None);
			set_ia32_Immop_attr(new_op, op2);
		}
		else {
Michael Beck's avatar
Michael Beck committed
1032
			new_op = new_rd_ia32_xDiv(env->dbg, env->irg, env->block, noreg, noreg, op1, op2, nomem);
Michael Beck's avatar
Michael Beck committed
1033
1034
			set_ia32_am_support(new_op, ia32_am_Source);
		}
1035
1036
	}
	else {
Michael Beck's avatar
Michael Beck committed
1037
		new_op = new_rd_ia32_vfdiv(env->dbg, env->irg, env->block, noreg, noreg, op1, op2, nomem);
1038
		set_ia32_am_support(new_op, ia32_am_Source);
1039
	}
Christian Würdig's avatar
Christian Würdig committed
1040
	set_ia32_res_mode(new_op, get_irn_mode(get_proj_for_pn(env->irn, pn_Quot_res)));
Christian Würdig's avatar
Christian Würdig committed
1041
	SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
Christian Würdig's avatar
Christian Würdig committed
1042

Christian Würdig's avatar
Christian Würdig committed
1043
	return new_op;
1044
1045
1046
1047
1048
1049
1050
}



/**
 * Creates an ia32 Shl.
 *
1051
1052
 * @param env   The transformation environment
 * @return The created ia32 Shl node
1053
 */
1054
1055
static ir_node *gen_Shl(ia32_transform_env_t *env) {
	return gen_shift_binop(env, get_Shl_left(env->irn), get_Shl_right(env->irn), new_rd_ia32_Shl);
1056
1057
1058
1059
1060
1061
1062
}



/**
 * Creates an ia32 Shr.
 *
1063
1064
 * @param env   The transformation environment