ia32_transform.c 90.5 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.      */
Christian Würdig's avatar
Christian Würdig committed
249
250
251
252
253
	/* MulS and Mulh don't support immediates    */
	if (! (env->cg->opt & IA32_OPT_IMMOPS) ||
		func == new_rd_ia32_Mulh           ||
		func == new_rd_ia32_MulS)
	{
254
255
256
257
		expr_op = op1;
		imm_op  = NULL;
	}
	else if (is_op_commutative(get_irn_op(env->irn))) {
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
		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) {
276
			DB((mod, LEVEL_1, "FP with immediate ..."));
Michael Beck's avatar
Michael Beck committed
277
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_fp, nomem);
278
279
280
281
			set_ia32_Immop_attr(new_op, imm_op);
			set_ia32_am_support(new_op, ia32_am_None);
		}
		else {
282
			DB((mod, LEVEL_1, "FP binop ..."));
Michael Beck's avatar
Michael Beck committed
283
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem);
284
285
			set_ia32_am_support(new_op, ia32_am_Source);
		}
286
		set_ia32_ls_mode(new_op, mode);
287
288
289
290
291
	}
	else {
		/* integer operations */
		if (imm_op) {
			/* This is expr + const */
292
			DB((mod, LEVEL_1, "INT with immediate ..."));
Michael Beck's avatar
Michael Beck committed
293
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_gp, nomem);
294
295
296
297
298
299
			set_ia32_Immop_attr(new_op, imm_op);

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

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

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

311
312
	set_ia32_res_mode(new_op, mode);

Christian Würdig's avatar
Christian Würdig committed
313
314
315
316
	if (is_op_commutative(get_irn_op(env->irn))) {
		set_ia32_commutative(new_op);
	}

317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
	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;
337
	ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
338
339
340
	ir_node           *nomem  = new_NoMem();
	ir_node           *expr_op, *imm_op;
	tarval            *tv;
341
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
342
343
344

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

345
346
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
347
	imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, op2) : NULL;
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
	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));
363
			set_ia32_Immop_tarval(imm_op, tv);
364
365
366
367
368
369
370
371
372
		}
		else {
			imm_op = NULL;
		}
	}

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

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

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

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

389
	set_ia32_res_mode(new_op, mode);
Christian Würdig's avatar
Christian Würdig committed
390
	set_ia32_emit_cl(new_op);
391

392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
	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;
410
	ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
411
	ir_node           *nomem  = new_NoMem();
412
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
413

Michael Beck's avatar
Michael Beck committed
414
	new_op = func(dbg, irg, block, noreg, noreg, op, nomem);
415
416

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

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

428
429
	set_ia32_res_mode(new_op, mode);

430
	return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
431
432
433
434
435
436
437
}



/**
 * Creates an ia32 Add with immediate.
 *
438
439
440
441
 * @param env       The transformation environment
 * @param expr_op   The expression operator
 * @param const_op  The constant
 * @return the created ia32 Add node
442
 */
Christian Würdig's avatar
Christian Würdig committed
443
static ir_node *gen_imm_Add(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
444
445
446
447
448
	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;
449
	ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
450
451
	ir_node                *nomem      = new_NoMem();
	int                     normal_add = 1;
Christian Würdig's avatar
Christian Würdig committed
452
	tarval_classification_t class_tv, class_negtv;
453
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
Christian Würdig's avatar
Christian Würdig committed
454

455
	/* try to optimize to inc/dec  */
456
	if ((env->cg->opt & IA32_OPT_INCDEC) && (get_ia32_op_type(const_op) == ia32_Const)) {
Christian Würdig's avatar
Christian Würdig committed
457
458
459
460
461
		/* 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
462
			DB((env->mod, LEVEL_2, "Add(1) to Inc ... "));
Michael Beck's avatar
Michael Beck committed
463
			new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
464
			normal_add = 0;
Christian Würdig's avatar
Christian Würdig committed
465
466
		}
		else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
Christian Würdig's avatar
Christian Würdig committed
467
			DB((mod, LEVEL_2, "Add(-1) to Dec ... "));
Michael Beck's avatar
Michael Beck committed
468
			new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
469
			normal_add = 0;
Christian Würdig's avatar
Christian Würdig committed
470
471
472
		}
	}

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

	return new_op;
480
481
482
483
484
}

/**
 * Creates an ia32 Add.
 *
485
 * @param env   The transformation environment
486
487
 * @return the created ia32 Add node
 */
488
static ir_node *gen_Add(ia32_transform_env_t *env) {
489
490
491
492
493
	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;
494
	ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
495
496
	ir_node  *nomem  = new_NoMem();
	ir_node  *expr_op, *imm_op;
497
498
	ir_node  *op1    = get_Add_left(env->irn);
	ir_node  *op2    = get_Add_right(env->irn);
499

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

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

	if (mode_is_float(mode)) {
508
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
509
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
510
			return gen_binop(env, op1, op2, new_rd_ia32_xAdd);
511
		else
Michael Beck's avatar
Michael Beck committed
512
			return gen_binop(env, op1, op2, new_rd_ia32_vfadd);
Christian Würdig's avatar
Christian Würdig committed
513
	}
514
515
516
517
518
519
	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                                 */
520
521
522
523
524
525
526
527
528
529
			/* 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
530
531

				DBG_OPT_LEA1(op2, new_op);
532
533
534
535
536
			}
			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
537
538
				DBG_OPT_LEA2(op1, op2, new_op);

539
540
541
542
543
544
545
546
547
548
				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);
			}
549
550
551
552

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Source);
			set_ia32_op_type(new_op, ia32_AddrModeS);
553
554
555

			/* Lea doesn't need a Proj */
			return new_op;
Christian Würdig's avatar
Christian Würdig committed
556
		}
557
558
559
		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
560

561
562
563
564
565
			/* 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
566
			new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, op1, op2, nomem);
Christian Würdig's avatar
Christian Würdig committed
567

568
569
			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Full);
570
			set_ia32_commutative(new_op);
571
		}
Christian Würdig's avatar
Christian Würdig committed
572
573
	}

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

576
577
	set_ia32_res_mode(new_op, mode);

578
	return new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Add_res);
Christian Würdig's avatar
Christian Würdig committed
579
580
581
582
}



583
584
585
/**
 * Creates an ia32 Mul.
 *
586
 * @param env   The transformation environment
587
588
 * @return the created ia32 Mul node
 */
589
590
591
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);
592
593
	ir_node *new_op;

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

605
606
	return new_op;
}
607
608
609
610
611
612
613
614



/**
 * 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.
 *
615
 * @param env   The transformation environment
616
617
 * @return the created ia32 Mulh node
 */
618
619
620
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);
621
622
	ir_node *proj_EAX, *proj_EDX, *mulh;
	ir_node *in[1];
623

Daniel Grund's avatar
Daniel Grund committed
624
	assert(!mode_is_float(env->mode) && "Mulh with float not supported");
625
626
627
	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);
628

629
630
	/* to be on the save side */
	set_Proj_proj(proj_EAX, pn_EAX);
631

632
	if (is_ia32_ImmConst(mulh) || is_ia32_ImmSymConst(mulh)) {
633
634
635
636
637
638
639
640
641
642
643
644
645
646
		/* 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;
647
648
}

649
650


651
652
653
/**
 * Creates an ia32 And.
 *
654
655
 * @param env   The transformation environment
 * @return The created ia32 And node
656
 */
657
658
659
660
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
661
662
	assert (! mode_is_float(env->mode));
	return gen_binop(env, op1, op2, new_rd_ia32_And);
663
664
665
666
667
668
669
}



/**
 * Creates an ia32 Or.
 *
670
671
 * @param env   The transformation environment
 * @return The created ia32 Or node
672
 */
673
674
675
676
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
677
678
	assert (! mode_is_float(env->mode));
	return gen_binop(env, op1, op2, new_rd_ia32_Or);
679
680
681
682
683
684
685
}



/**
 * Creates an ia32 Eor.
 *
686
687
 * @param env   The transformation environment
 * @return The created ia32 Eor node
688
 */
689
690
691
692
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
693
694
	assert(! mode_is_float(env->mode));
	return gen_binop(env, op1, op2, new_rd_ia32_Eor);
695
696
697
698
699
700
701
}



/**
 * Creates an ia32 Max.
 *
702
703
 * @param env      The transformation environment
 * @return the created ia32 Max node
704
 */
705
706
707
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);
708
709
710
	ir_node *new_op;

	if (mode_is_float(env->mode)) {
711
		FP_USED(env->cg);
712
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
713
			new_op = gen_binop(env, op1, op2, new_rd_ia32_xMax);
714
715
716
		else {
			assert(0);
		}
717
718
719
720
	}
	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
721
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
722
723
724
	}

	return new_op;
725
726
727
728
729
730
731
}



/**
 * Creates an ia32 Min.
 *
732
733
 * @param env      The transformation environment
 * @return the created ia32 Min node
734
 */
735
736
737
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);
738
739
740
	ir_node *new_op;

	if (mode_is_float(env->mode)) {
741
		FP_USED(env->cg);
742
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
743
			new_op = gen_binop(env, op1, op2, new_rd_ia32_xMin);
744
745
746
		else {
			assert(0);
		}
747
748
749
750
	}
	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
751
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
752
753
754
	}

	return new_op;
755
756
757
758
759
760
761
}



/**
 * Creates an ia32 Sub with immediate.
 *
762
763
764
 * @param env        The transformation environment
 * @param expr_op    The first operator
 * @param const_op   The constant operator
765
 * @return The created ia32 Sub node
766
 */
Christian Würdig's avatar
Christian Würdig committed
767
static ir_node *gen_imm_Sub(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
768
769
770
771
772
	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;
773
	ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
774
775
	ir_node                *nomem      = new_NoMem();
	int                     normal_sub = 1;
Christian Würdig's avatar
Christian Würdig committed
776
	tarval_classification_t class_tv, class_negtv;
777
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
Christian Würdig's avatar
Christian Würdig committed
778

779
	/* try to optimize to inc/dec  */
780
	if ((env->cg->opt & IA32_OPT_INCDEC) && tv) {
Christian Würdig's avatar
Christian Würdig committed
781
782
783
784
785
		/* 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
786
			DB((mod, LEVEL_2, "Sub(1) to Dec ... "));
Michael Beck's avatar
Michael Beck committed
787
			new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
788
			normal_sub = 0;
Christian Würdig's avatar
Christian Würdig committed
789
790
		}
		else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
Christian Würdig's avatar
Christian Würdig committed
791
			DB((mod, LEVEL_2, "Sub(-1) to Inc ... "));
Michael Beck's avatar
Michael Beck committed
792
			new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
793
			normal_sub = 0;
Christian Würdig's avatar
Christian Würdig committed
794
795
796
		}
	}

797
	if (normal_sub) {
Michael Beck's avatar
Michael Beck committed
798
		new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
799
800
		set_ia32_Immop_attr(new_op, const_op);
	}
Christian Würdig's avatar
Christian Würdig committed
801
802

	return new_op;
803
804
805
806
807
}

/**
 * Creates an ia32 Sub.
 *
808
809
 * @param env   The transformation environment
 * @return The created ia32 Sub node
810
 */
811
static ir_node *gen_Sub(ia32_transform_env_t *env) {
812
813
814
815
816
	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;
817
	ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
818
	ir_node  *nomem  = new_NoMem();
819
820
	ir_node  *op1    = get_Sub_left(env->irn);
	ir_node  *op2    = get_Sub_right(env->irn);
821
822
	ir_node  *expr_op, *imm_op;

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

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

	if (mode_is_float(mode)) {
831
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
832
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
833
			return gen_binop(env, op1, op2, new_rd_ia32_xSub);
834
		else
Michael Beck's avatar
Michael Beck committed
835
			return gen_binop(env, op1, op2, new_rd_ia32_vfsub);
Christian Würdig's avatar
Christian Würdig committed
836
	}
837
838
839
840
841
842
	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                                 */
843
844
845
846
847
848
849
850
851
852
853
			/* 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
854
855

				DBG_OPT_LEA1(op2, new_op);
856
857
858
859
860
			}
			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
861
862
				DBG_OPT_LEA2(op1, op2, new_op);

863
864
865
866
867
868
869
870
871
872
873
				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);
			}
874
875
876
877

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Source);
			set_ia32_op_type(new_op, ia32_AddrModeS);
878
879
880

			/* Lea doesn't need a Proj */
			return new_op;
881
882
883
884
885
886
887
888
889
890
		}
		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
891
			new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, op1, op2, nomem);
892
893
894
895
896
897

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

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

900
901
	set_ia32_res_mode(new_op, mode);

902
	return new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Sub_res);
903
904
}

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

906
907

/**
Christian Würdig's avatar
Christian Würdig committed
908
909
 * Generates an ia32 DivMod with additional infrastructure for the
 * register allocator if needed.
910
 *
Christian Würdig's avatar
Christian Würdig committed
911
912
913
914
915
916
 * @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
 */
917
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
918
919
920
921
922
923
924
925
	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;
926
927
928
929
	ir_node  *mem;

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

	if (mode_is_signed(mode)) {
		/* in signed mode, we need to sign extend the dividend */
Michael Beck's avatar
Michael Beck committed
947
948
949
		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
950
951
	}
	else {
952
		edx_node = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode_Iu);
953
		set_ia32_Const_type(edx_node, ia32_Const);
Christian Würdig's avatar
Christian Würdig committed
954
955
956
		set_ia32_Immop_tarval(edx_node, get_tarval_null(mode_Iu));
	}

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

	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");

968
969
		if (get_irn_op(irn) == op_Div) {
			set_Proj_proj(proj, pn_DivMod_res_div);
970
			in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode, pn_DivMod_res_mod);
Christian Würdig's avatar
Christian Würdig committed
971
972
		}
		else {
973
			set_Proj_proj(proj, pn_DivMod_res_mod);
974
			in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode, pn_DivMod_res_div);
Christian Würdig's avatar
Christian Würdig committed
975
976
		}

977
		be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
Christian Würdig's avatar
Christian Würdig committed
978
979
	}

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

982
	set_ia32_res_mode(res, mode);
983

Christian Würdig's avatar
Christian Würdig committed
984
985
986
987
988
989
	return res;
}


/**
 * Wrapper for generate_DivMod. Sets flavour_Mod.
990
991
 *
 * @param env      The transformation environment
992
 */
993
994
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);
995
996
997
}

/**
Christian Würdig's avatar
Christian Würdig committed
998
 * Wrapper for generate_DivMod. Sets flavour_Div.
999
1000
 *
 * @param env      The transformation environment
For faster browsing, not all history is shown. View entire blame