ia32_transform.c 93.7 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"
28
29
#include "type.h"
#include "entity.h"
Christian Würdig's avatar
Christian Würdig committed
30
#include "archop.h"     /* we need this for Min and Max nodes */
31

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

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

Christian Würdig's avatar
Christian Würdig committed
45
46
#include "gen_ia32_regalloc_if.h"

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#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"

62
63
extern ir_op *get_op_Mulh(void);

64
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
65
									  ir_node *op1, ir_node *op2, ir_node *mem);
Christian Würdig's avatar
Christian Würdig committed
66

67
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
68
									 ir_node *op, ir_node *mem);
69

70
typedef enum {
71
	ia32_SSIGN, ia32_DSIGN, ia32_SABS, ia32_DABS, ia32_known_const_max
72
73
} ia32_known_const_t;

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

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

/**
 * Returns 1 if irn is a Const representing 1, 0 otherwise
 */
static INLINE int is_ia32_Const_1(ir_node *irn) {
96
97
	return (is_ia32_irn(irn) && get_ia32_op_type(irn) == ia32_Const) ?
		classify_tarval(get_ia32_Immop_tarval(irn)) == TV_CLASSIFY_ONE : 0;
Christian Würdig's avatar
Christian Würdig committed
98
99
}

Christian Würdig's avatar
Christian Würdig committed
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/**
 * 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/**
 * 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;
}

135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/**
 * 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);
}

Christian Würdig's avatar
Christian Würdig committed
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/**
* SSE convert of an float node into a double node.
*/
static ir_node *gen_sse_conv_f2d(ia32_code_gen_t *cg, dbg_info *dbg, ir_graph *irg, ir_node *block,
									   ir_node *in, ir_node *old_node)
{
	ir_node *noreg = ia32_new_NoReg_gp(cg);
	ir_node *nomem = new_rd_NoMem(irg);

	ir_node *conv = new_rd_ia32_Conv_FP2FP(dbg, irg, block, noreg, noreg, in, nomem);
	set_ia32_src_mode(conv, mode_F);
	set_ia32_tgt_mode(conv, mode_D);
	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, mode_D, pn_ia32_Conv_FP2FP_res);
}

171
/* Generates an entity for a known FP const (used for FP Neg + Abs) */
172
static ident *gen_fp_known_const(ir_mode *mode, ia32_known_const_t kct) {
173
174
175
176
177
178
179
180
181
182
183
184
185
	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;
186
187
188
189
	ir_type       *tp;
	ir_node       *cnst;
	ir_graph      *rem;
	entity        *ent;
190
	tarval        *tv;
191

Christian Würdig's avatar
Christian Würdig committed
192
	ent_name = names[kct].ent_name;
193
194
195
	if (! ent_cache[kct]) {
		tp_name  = names[kct].tp_name;
		cnst_str = names[kct].cnst_str;
196

197
		tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
198
199
200
201
202
203
204
205
206
207
208
209
		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();
210
		cnst = new_Const(mode, tv);
211
212
213
214
		current_ir_graph = rem;

		set_atomic_ent_value(ent, cnst);

215
216
		/* cache the entry */
		ent_cache[kct] = ent;
217
	}
218
219

	return get_entity_ident(ent_cache[kct]);
220
221
}

Christian Würdig's avatar
Christian Würdig committed
222
223
224
225
#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
226
227
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;
228

Christian Würdig's avatar
Christian Würdig committed
229
	lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
Christian Würdig's avatar
Christian Würdig committed
230
	obstack_1grow(isa->name_obst, 0);
Christian Würdig's avatar
Christian Würdig committed
231
	isa->name_obst_size += obstack_object_size(isa->name_obst);
Christian Würdig's avatar
Christian Würdig committed
232
233
234
 	return obstack_finish(isa->name_obst);
}
#endif /* NDEBUG */
Christian Würdig's avatar
Christian Würdig committed
235

236
237
/* 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
238
	if (op1)
Christian Würdig's avatar
Christian Würdig committed
239
240
		return is_ia32_Cnst(op1) ? op1 : (is_ia32_Cnst(op2) ? op2 : NULL);
	else return is_ia32_Cnst(op2) ? op2 : NULL;
241
242
243
244
}

/* 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
245
	return !is_ia32_Cnst(op1) ? op1 : (!is_ia32_Cnst(op2) ? op2 : NULL);
246
247
248
249
250
251
252
253
254
255
256
257
258
}


/**
 * 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) {
259
260
261
262
263
264
265
266
267
268
	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();
	int      is_mul    = 0;
	ir_node  *expr_op, *imm_op;
269
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
270

271
272
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
273
	/* Mul/MulS/Mulh don't support immediates    */
Christian Würdig's avatar
Christian Würdig committed
274
	if (! (env->cg->opt & IA32_OPT_IMMOPS) ||
275
		func == new_rd_ia32_Mul            ||
Christian Würdig's avatar
Christian Würdig committed
276
277
278
		func == new_rd_ia32_Mulh           ||
		func == new_rd_ia32_MulS)
	{
279
280
		expr_op = op1;
		imm_op  = NULL;
281
282
283
		/* immediate operations are requested, but we are here: it a mul */
		if (env->cg->opt & IA32_OPT_IMMOPS)
			is_mul = 1;
284
285
	}
	else if (is_op_commutative(get_irn_op(env->irn))) {
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
		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) {
304
			DB((mod, LEVEL_1, "FP with immediate ..."));
Michael Beck's avatar
Michael Beck committed
305
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_fp, nomem);
306
307
308
309
			set_ia32_Immop_attr(new_op, imm_op);
			set_ia32_am_support(new_op, ia32_am_None);
		}
		else {
310
			DB((mod, LEVEL_1, "FP binop ..."));
Michael Beck's avatar
Michael Beck committed
311
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem);
312
313
			set_ia32_am_support(new_op, ia32_am_Source);
		}
314
		set_ia32_ls_mode(new_op, mode);
315
316
317
318
319
	}
	else {
		/* integer operations */
		if (imm_op) {
			/* This is expr + const */
320
			DB((mod, LEVEL_1, "INT with immediate ..."));
Michael Beck's avatar
Michael Beck committed
321
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_gp, nomem);
322
323
324
325
326
327
			set_ia32_Immop_attr(new_op, imm_op);

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Dest);
		}
		else {
328
			DB((mod, LEVEL_1, "INT binop ..."));
329
			/* This is a normal operation */
Michael Beck's avatar
Michael Beck committed
330
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem);
331
332
333
334

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Full);
		}
335
336
337
338

		/* Muls can only have AM source */
		if (is_mul)
			set_ia32_am_support(new_op, ia32_am_Source);
339
340
	}

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

343
344
	set_ia32_res_mode(new_op, mode);

Christian Würdig's avatar
Christian Würdig committed
345
346
347
348
	if (is_op_commutative(get_irn_op(env->irn))) {
		set_ia32_commutative(new_op);
	}

349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
	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;
369
	ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
370
371
372
	ir_node           *nomem  = new_NoMem();
	ir_node           *expr_op, *imm_op;
	tarval            *tv;
373
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
374
375
376

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

377
378
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
379
	imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, op2) : NULL;
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
	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));
395
			set_ia32_Immop_tarval(imm_op, tv);
396
397
398
399
400
401
402
403
404
		}
		else {
			imm_op = NULL;
		}
	}

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

Michael Beck's avatar
Michael Beck committed
407
		new_op = func(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
408
409
410
411
		set_ia32_Immop_attr(new_op, imm_op);
	}
	else {
		/* This is a normal shift/rot */
412
		DB((mod, LEVEL_1, "Shift/Rot binop ..."));
Michael Beck's avatar
Michael Beck committed
413
		new_op = func(dbg, irg, block, noreg, noreg, op1, op2, nomem);
414
415
416
417
418
	}

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

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

421
	set_ia32_res_mode(new_op, mode);
Christian Würdig's avatar
Christian Würdig committed
422
	set_ia32_emit_cl(new_op);
423

424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
	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;
442
	ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
443
	ir_node           *nomem  = new_NoMem();
444
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
445

Michael Beck's avatar
Michael Beck committed
446
	new_op = func(dbg, irg, block, noreg, noreg, op, nomem);
447
448

	if (mode_is_float(mode)) {
449
		DB((mod, LEVEL_1, "FP unop ..."));
450
451
452
453
		/* floating point operations don't support implicit store */
		set_ia32_am_support(new_op, ia32_am_None);
	}
	else {
454
		DB((mod, LEVEL_1, "INT unop ..."));
455
456
457
		set_ia32_am_support(new_op, ia32_am_Dest);
	}

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

460
461
	set_ia32_res_mode(new_op, mode);

462
	return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
463
464
465
466
467
468
469
}



/**
 * Creates an ia32 Add with immediate.
 *
470
471
472
473
 * @param env       The transformation environment
 * @param expr_op   The expression operator
 * @param const_op  The constant
 * @return the created ia32 Add node
474
 */
Christian Würdig's avatar
Christian Würdig committed
475
static ir_node *gen_imm_Add(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
476
477
478
479
480
	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;
481
	ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
482
483
	ir_node                *nomem      = new_NoMem();
	int                     normal_add = 1;
Christian Würdig's avatar
Christian Würdig committed
484
	tarval_classification_t class_tv, class_negtv;
485
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
Christian Würdig's avatar
Christian Würdig committed
486

487
	/* try to optimize to inc/dec  */
488
	if ((env->cg->opt & IA32_OPT_INCDEC) && (get_ia32_op_type(const_op) == ia32_Const)) {
Christian Würdig's avatar
Christian Würdig committed
489
490
491
492
493
		/* 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
494
			DB((env->mod, LEVEL_2, "Add(1) to Inc ... "));
Michael Beck's avatar
Michael Beck committed
495
			new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
496
			normal_add = 0;
Christian Würdig's avatar
Christian Würdig committed
497
498
		}
		else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
Christian Würdig's avatar
Christian Würdig committed
499
			DB((mod, LEVEL_2, "Add(-1) to Dec ... "));
Michael Beck's avatar
Michael Beck committed
500
			new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
501
			normal_add = 0;
Christian Würdig's avatar
Christian Würdig committed
502
503
504
		}
	}

505
	if (normal_add) {
Michael Beck's avatar
Michael Beck committed
506
		new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
507
		set_ia32_Immop_attr(new_op, const_op);
508
		set_ia32_commutative(new_op);
509
	}
Christian Würdig's avatar
Christian Würdig committed
510
511

	return new_op;
512
513
514
515
516
}

/**
 * Creates an ia32 Add.
 *
517
 * @param env   The transformation environment
518
519
 * @return the created ia32 Add node
 */
520
static ir_node *gen_Add(ia32_transform_env_t *env) {
521
522
523
524
525
	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;
526
	ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
527
528
	ir_node  *nomem  = new_NoMem();
	ir_node  *expr_op, *imm_op;
529
530
	ir_node  *op1    = get_Add_left(env->irn);
	ir_node  *op2    = get_Add_right(env->irn);
531

532
533
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
534
	imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(op1, op2) : NULL;
535
536
537
	expr_op = get_expr_op(op1, op2);

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

	if (mode_is_float(mode)) {
540
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
541
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
542
			return gen_binop(env, op1, op2, new_rd_ia32_xAdd);
543
		else
Michael Beck's avatar
Michael Beck committed
544
			return gen_binop(env, op1, op2, new_rd_ia32_vfadd);
Christian Würdig's avatar
Christian Würdig committed
545
	}
546
547
548
549
550
551
	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                                 */
552
553
554
555
556
557
558
559
560
561
			/* 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
562

563
				DBG_OPT_LEA3(op1, op2, env->irn, new_op);
564
565
566
567
568
			}
			else {
				/* this is the 1st case */
				new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode);

569
				DBG_OPT_LEA3(op1, op2, env->irn, new_op);
Christian Würdig's avatar
Christian Würdig committed
570

571
572
573
574
575
576
577
578
579
580
				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);
			}
581
582
583
584

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Source);
			set_ia32_op_type(new_op, ia32_AddrModeS);
585
586
587

			/* Lea doesn't need a Proj */
			return new_op;
Christian Würdig's avatar
Christian Würdig committed
588
		}
589
590
591
		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
592

593
594
595
596
597
			/* 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
598
			new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, op1, op2, nomem);
Christian Würdig's avatar
Christian Würdig committed
599

600
601
			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Full);
602
			set_ia32_commutative(new_op);
603
		}
Christian Würdig's avatar
Christian Würdig committed
604
605
	}

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

608
609
	set_ia32_res_mode(new_op, mode);

610
	return new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Add_res);
Christian Würdig's avatar
Christian Würdig committed
611
612
613
614
}



615
616
617
/**
 * Creates an ia32 Mul.
 *
618
 * @param env   The transformation environment
619
620
 * @return the created ia32 Mul node
 */
621
622
623
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);
624
625
	ir_node *new_op;

Christian Würdig's avatar
Christian Würdig committed
626
	if (mode_is_float(env->mode)) {
627
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
628
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
629
			new_op = gen_binop(env, op1, op2, new_rd_ia32_xMul);
630
		else
Michael Beck's avatar
Michael Beck committed
631
			new_op = gen_binop(env, op1, op2, new_rd_ia32_vfmul);
Christian Würdig's avatar
Christian Würdig committed
632
633
	}
	else {
634
		new_op = gen_binop(env, op1, op2, new_rd_ia32_Mul);
Christian Würdig's avatar
Christian Würdig committed
635
	}
636

637
638
	return new_op;
}
639
640
641
642
643
644
645
646



/**
 * 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.
 *
647
 * @param env   The transformation environment
648
649
 * @return the created ia32 Mulh node
 */
650
651
652
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);
653
654
	ir_node *proj_EAX, *proj_EDX, *mulh;
	ir_node *in[1];
655

Daniel Grund's avatar
Daniel Grund committed
656
	assert(!mode_is_float(env->mode) && "Mulh with float not supported");
657
658
659
	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);
660

661
662
	/* to be on the save side */
	set_Proj_proj(proj_EAX, pn_EAX);
663

664
	if (is_ia32_ImmConst(mulh) || is_ia32_ImmSymConst(mulh)) {
665
666
667
668
669
670
671
672
673
674
675
676
677
678
		/* 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;
679
680
}

681
682


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



/**
 * Creates an ia32 Or.
 *
702
703
 * @param env   The transformation environment
 * @return The created ia32 Or node
704
 */
705
706
707
708
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
709
710
	assert (! mode_is_float(env->mode));
	return gen_binop(env, op1, op2, new_rd_ia32_Or);
711
712
713
714
715
716
717
}



/**
 * Creates an ia32 Eor.
 *
718
719
 * @param env   The transformation environment
 * @return The created ia32 Eor node
720
 */
721
722
723
724
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
725
726
	assert(! mode_is_float(env->mode));
	return gen_binop(env, op1, op2, new_rd_ia32_Eor);
727
728
729
730
731
732
733
}



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

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

	return new_op;
757
758
759
760
761
762
763
}



/**
 * Creates an ia32 Min.
 *
764
765
 * @param env      The transformation environment
 * @return the created ia32 Min node
766
 */
767
768
769
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);
770
771
772
	ir_node *new_op;

	if (mode_is_float(env->mode)) {
773
		FP_USED(env->cg);
774
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
775
			new_op = gen_binop(env, op1, op2, new_rd_ia32_xMin);
776
777
778
		else {
			assert(0);
		}
779
780
781
782
	}
	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
783
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
784
785
786
	}

	return new_op;
787
788
789
790
791
792
793
}



/**
 * Creates an ia32 Sub with immediate.
 *
794
795
796
 * @param env        The transformation environment
 * @param expr_op    The first operator
 * @param const_op   The constant operator
797
 * @return The created ia32 Sub node
798
 */
Christian Würdig's avatar
Christian Würdig committed
799
static ir_node *gen_imm_Sub(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
800
801
802
803
804
	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;
805
	ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
806
807
	ir_node                *nomem      = new_NoMem();
	int                     normal_sub = 1;
Christian Würdig's avatar
Christian Würdig committed
808
	tarval_classification_t class_tv, class_negtv;
809
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
Christian Würdig's avatar
Christian Würdig committed
810

811
	/* try to optimize to inc/dec  */
812
	if ((env->cg->opt & IA32_OPT_INCDEC) && tv) {
Christian Würdig's avatar
Christian Würdig committed
813
814
815
816
817
		/* 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
818
			DB((mod, LEVEL_2, "Sub(1) to Dec ... "));
Michael Beck's avatar
Michael Beck committed
819
			new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
820
			normal_sub = 0;
Christian Würdig's avatar
Christian Würdig committed
821
822
		}
		else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
Christian Würdig's avatar
Christian Würdig committed
823
			DB((mod, LEVEL_2, "Sub(-1) to Inc ... "));
Michael Beck's avatar
Michael Beck committed
824
			new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
825
			normal_sub = 0;
Christian Würdig's avatar
Christian Würdig committed
826
827
828
		}
	}

829
	if (normal_sub) {
Michael Beck's avatar
Michael Beck committed
830
		new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
831
832
		set_ia32_Immop_attr(new_op, const_op);
	}
Christian Würdig's avatar
Christian Würdig committed
833
834

	return new_op;
835
836
837
838
839
}

/**
 * Creates an ia32 Sub.
 *
840
841
 * @param env   The transformation environment
 * @return The created ia32 Sub node
842
 */
843
static ir_node *gen_Sub(ia32_transform_env_t *env) {
844
845
846
847
848
	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;
849
	ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
850
	ir_node  *nomem  = new_NoMem();
851
852
	ir_node  *op1    = get_Sub_left(env->irn);
	ir_node  *op2    = get_Sub_right(env->irn);
853
854
	ir_node  *expr_op, *imm_op;

855
856
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
857
	imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, op2) : NULL;
858
859
860
861
862
	expr_op = get_expr_op(op1, op2);

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

	if (mode_is_float(mode)) {
863
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
864
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
865
			return gen_binop(env, op1, op2, new_rd_ia32_xSub);
866
		else
Michael Beck's avatar
Michael Beck committed
867
			return gen_binop(env, op1, op2, new_rd_ia32_vfsub);
Christian Würdig's avatar
Christian Würdig committed
868
	}
869
870
	else {
		/* integer SUB */
871
		if (! expr_op) {
872
873
874
			/* 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                                 */
875
			/* We need to check for:                                       */
876
877
			/*  1) symconst - const    -> becomes a LEA                    */
			/*  2) symconst - symconst -> becomes a const - LEA as the elf */
878
879
880
881
882
883
884
885
			/*        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
886

887
				DBG_OPT_LEA3(op1, op2, env->irn, new_op);
888
889
890
891
892
			}
			else {
				/* this is the 1st case */
				new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode);

893
				DBG_OPT_LEA3(op1, op2, env->irn, new_op);
Christian Würdig's avatar
Christian Würdig committed
894

895
896
897
898
899
900
901
902
903
904
905
				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);
			}
906
907
908
909

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Source);
			set_ia32_op_type(new_op, ia32_AddrModeS);
910
911
912

			/* Lea doesn't need a Proj */
			return new_op;
913
914
915
916
917
918
919
920
921
922
		}
		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
923
			new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, op1, op2, nomem);
924
925
926
927
928
929

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

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

932
933
	set_ia32_res_mode(new_op, mode);

934
	return new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Sub_res);
935
936
}

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

938
939

/**
Christian Würdig's avatar
Christian Würdig committed
940
941
 * Generates an ia32 DivMod with additional infrastructure for the
 * register allocator if needed.
942
 *
Christian Würdig's avatar
Christian Würdig committed
943
944
945
946
947
948
 * @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
 */
949
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
950
951
952
953
954
955
956
957
	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;
958
	ir_node  *mem;
959
	int      n;
960
961
962

	switch (dm_flav) {
		case flavour_Div:
Christian Würdig's avatar
Christian Würdig committed
963
964
			mem  = get_Div_mem(irn);
			mode = get_irn_mode(get_proj_for_pn(irn, pn_Div_res));
965
966
			break;
		case flavour_Mod:
Christian Würdig's avatar
Christian Würdig committed
967
968
			mem  = get_Mod_mem(irn);
			mode = get_irn_mode(get_proj_for_pn(irn, pn_Mod_res));
969
970
			break;
		case flavour_DivMod:
Christian Würdig's avatar
Christian Würdig committed
971
972
			mem  = get_DivMod_mem(irn);
			mode = get_irn_mode(get_proj_for_pn(irn, pn_DivMod_res_div));
973
974
975
976
			break;
		default:
			assert(0);
	}
Christian Würdig's avatar
Christian Würdig committed
977
978
979

	if (mode_is_signed(mode)) {
		/* in signed mode, we need to sign extend the dividend */
Michael Beck's avatar
Michael Beck committed
980
981
982
		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
983
984
	}
	else {
985
		edx_node = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode_Iu);
986
		set_ia32_Const_type(edx_node, ia32_Const);
Christian Würdig's avatar
Christian Würdig committed
987
988
989
		set_ia32_Immop_tarval(edx_node, get_tarval_null(mode_Iu));
	}

Michael Beck's avatar
Michael Beck committed
990
	res = new_rd_ia32_DivMod(dbg, irg, block, dividend, divisor, edx_node, mem, dm_flav);
Christian Würdig's avatar
Christian Würdig committed
991
992
993
994
995
996

	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.                                    */
997
998
999
1000
	n    = get_irn_n_edges(irn);
	proj = NULL;
	if (n == 2)
		proj = ia32_get_proj_for_mode(irn, mode_M);
For faster browsing, not all history is shown. View entire blame