ia32_transform.c 92.8 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);
}

153
/* Generates an entity for a known FP const (used for FP Neg + Abs) */
154
static ident *gen_fp_known_const(ir_mode *mode, ia32_known_const_t kct) {
155
156
157
158
159
160
161
162
163
164
165
166
167
	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;
168
169
170
171
	ir_type       *tp;
	ir_node       *cnst;
	ir_graph      *rem;
	entity        *ent;
172
	tarval        *tv;
173

Christian Würdig's avatar
Christian Würdig committed
174
	ent_name = names[kct].ent_name;
175
176
177
	if (! ent_cache[kct]) {
		tp_name  = names[kct].tp_name;
		cnst_str = names[kct].cnst_str;
178

179
		tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
180
181
182
183
184
185
186
187
188
189
190
191
		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();
192
		cnst = new_Const(mode, tv);
193
194
195
196
		current_ir_graph = rem;

		set_atomic_ent_value(ent, cnst);

197
198
		/* cache the entry */
		ent_cache[kct] = ent;
199
	}
200
201

	return get_entity_ident(ent_cache[kct]);
202
203
}

Christian Würdig's avatar
Christian Würdig committed
204
205
206
207
#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
208
209
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;
210

Christian Würdig's avatar
Christian Würdig committed
211
	lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
Christian Würdig's avatar
Christian Würdig committed
212
	obstack_1grow(isa->name_obst, 0);
Christian Würdig's avatar
Christian Würdig committed
213
	isa->name_obst_size += obstack_object_size(isa->name_obst);
Christian Würdig's avatar
Christian Würdig committed
214
215
216
 	return obstack_finish(isa->name_obst);
}
#endif /* NDEBUG */
Christian Würdig's avatar
Christian Würdig committed
217

218
219
/* 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
220
	if (op1)
Christian Würdig's avatar
Christian Würdig committed
221
222
		return is_ia32_Cnst(op1) ? op1 : (is_ia32_Cnst(op2) ? op2 : NULL);
	else return is_ia32_Cnst(op2) ? op2 : NULL;
223
224
225
226
}

/* 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
227
	return !is_ia32_Cnst(op1) ? op1 : (!is_ia32_Cnst(op2) ? op2 : NULL);
228
229
230
231
232
233
234
235
236
237
238
239
240
}


/**
 * 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) {
241
242
243
244
245
246
247
248
249
250
	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;
251
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
252

253
254
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
255
	/* Mul/MulS/Mulh don't support immediates    */
Christian Würdig's avatar
Christian Würdig committed
256
	if (! (env->cg->opt & IA32_OPT_IMMOPS) ||
257
		func == new_rd_ia32_Mul            ||
Christian Würdig's avatar
Christian Würdig committed
258
259
260
		func == new_rd_ia32_Mulh           ||
		func == new_rd_ia32_MulS)
	{
261
262
		expr_op = op1;
		imm_op  = NULL;
263
264
265
		/* immediate operations are requested, but we are here: it a mul */
		if (env->cg->opt & IA32_OPT_IMMOPS)
			is_mul = 1;
266
267
	}
	else if (is_op_commutative(get_irn_op(env->irn))) {
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
		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) {
286
			DB((mod, LEVEL_1, "FP with immediate ..."));
Michael Beck's avatar
Michael Beck committed
287
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_fp, nomem);
288
289
290
291
			set_ia32_Immop_attr(new_op, imm_op);
			set_ia32_am_support(new_op, ia32_am_None);
		}
		else {
292
			DB((mod, LEVEL_1, "FP binop ..."));
Michael Beck's avatar
Michael Beck committed
293
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem);
294
295
			set_ia32_am_support(new_op, ia32_am_Source);
		}
296
		set_ia32_ls_mode(new_op, mode);
297
298
299
300
301
	}
	else {
		/* integer operations */
		if (imm_op) {
			/* This is expr + const */
302
			DB((mod, LEVEL_1, "INT with immediate ..."));
Michael Beck's avatar
Michael Beck committed
303
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_gp, nomem);
304
305
306
307
308
309
			set_ia32_Immop_attr(new_op, imm_op);

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Dest);
		}
		else {
310
			DB((mod, LEVEL_1, "INT binop ..."));
311
			/* This is a normal operation */
Michael Beck's avatar
Michael Beck committed
312
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem);
313
314
315
316

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Full);
		}
317
318
319
320

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

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

325
326
	set_ia32_res_mode(new_op, mode);

Christian Würdig's avatar
Christian Würdig committed
327
328
329
330
	if (is_op_commutative(get_irn_op(env->irn))) {
		set_ia32_commutative(new_op);
	}

331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
	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;
351
	ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
352
353
354
	ir_node           *nomem  = new_NoMem();
	ir_node           *expr_op, *imm_op;
	tarval            *tv;
355
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
356
357
358

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

359
360
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
361
	imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, op2) : NULL;
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
	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));
377
			set_ia32_Immop_tarval(imm_op, tv);
378
379
380
381
382
383
384
385
386
		}
		else {
			imm_op = NULL;
		}
	}

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

Michael Beck's avatar
Michael Beck committed
389
		new_op = func(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
390
391
392
393
		set_ia32_Immop_attr(new_op, imm_op);
	}
	else {
		/* This is a normal shift/rot */
394
		DB((mod, LEVEL_1, "Shift/Rot binop ..."));
Michael Beck's avatar
Michael Beck committed
395
		new_op = func(dbg, irg, block, noreg, noreg, op1, op2, nomem);
396
397
398
399
400
	}

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

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

403
	set_ia32_res_mode(new_op, mode);
Christian Würdig's avatar
Christian Würdig committed
404
	set_ia32_emit_cl(new_op);
405

406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
	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;
424
	ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
425
	ir_node           *nomem  = new_NoMem();
426
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
427

Michael Beck's avatar
Michael Beck committed
428
	new_op = func(dbg, irg, block, noreg, noreg, op, nomem);
429
430

	if (mode_is_float(mode)) {
431
		DB((mod, LEVEL_1, "FP unop ..."));
432
433
434
435
		/* floating point operations don't support implicit store */
		set_ia32_am_support(new_op, ia32_am_None);
	}
	else {
436
		DB((mod, LEVEL_1, "INT unop ..."));
437
438
439
		set_ia32_am_support(new_op, ia32_am_Dest);
	}

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

442
443
	set_ia32_res_mode(new_op, mode);

444
	return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
445
446
447
448
449
450
451
}



/**
 * Creates an ia32 Add with immediate.
 *
452
453
454
455
 * @param env       The transformation environment
 * @param expr_op   The expression operator
 * @param const_op  The constant
 * @return the created ia32 Add node
456
 */
Christian Würdig's avatar
Christian Würdig committed
457
static ir_node *gen_imm_Add(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
458
459
460
461
462
	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;
463
	ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
464
465
	ir_node                *nomem      = new_NoMem();
	int                     normal_add = 1;
Christian Würdig's avatar
Christian Würdig committed
466
	tarval_classification_t class_tv, class_negtv;
467
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
Christian Würdig's avatar
Christian Würdig committed
468

469
	/* try to optimize to inc/dec  */
470
	if ((env->cg->opt & IA32_OPT_INCDEC) && (get_ia32_op_type(const_op) == ia32_Const)) {
Christian Würdig's avatar
Christian Würdig committed
471
472
473
474
475
		/* 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
476
			DB((env->mod, LEVEL_2, "Add(1) to Inc ... "));
Michael Beck's avatar
Michael Beck committed
477
			new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
478
			normal_add = 0;
Christian Würdig's avatar
Christian Würdig committed
479
480
		}
		else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
Christian Würdig's avatar
Christian Würdig committed
481
			DB((mod, LEVEL_2, "Add(-1) to Dec ... "));
Michael Beck's avatar
Michael Beck committed
482
			new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
483
			normal_add = 0;
Christian Würdig's avatar
Christian Würdig committed
484
485
486
		}
	}

487
	if (normal_add) {
Michael Beck's avatar
Michael Beck committed
488
		new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
489
		set_ia32_Immop_attr(new_op, const_op);
490
		set_ia32_commutative(new_op);
491
	}
Christian Würdig's avatar
Christian Würdig committed
492
493

	return new_op;
494
495
496
497
498
}

/**
 * Creates an ia32 Add.
 *
499
 * @param env   The transformation environment
500
501
 * @return the created ia32 Add node
 */
502
static ir_node *gen_Add(ia32_transform_env_t *env) {
503
504
505
506
507
	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;
508
	ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
509
510
	ir_node  *nomem  = new_NoMem();
	ir_node  *expr_op, *imm_op;
511
512
	ir_node  *op1    = get_Add_left(env->irn);
	ir_node  *op2    = get_Add_right(env->irn);
513

514
515
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
516
	imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(op1, op2) : NULL;
517
518
519
	expr_op = get_expr_op(op1, op2);

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

	if (mode_is_float(mode)) {
522
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
523
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
524
			return gen_binop(env, op1, op2, new_rd_ia32_xAdd);
525
		else
Michael Beck's avatar
Michael Beck committed
526
			return gen_binop(env, op1, op2, new_rd_ia32_vfadd);
Christian Würdig's avatar
Christian Würdig committed
527
	}
528
529
530
531
532
533
	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                                 */
534
535
536
537
538
539
540
541
542
543
			/* 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
544

545
				DBG_OPT_LEA3(op1, op2, env->irn, new_op);
546
547
548
549
550
			}
			else {
				/* this is the 1st case */
				new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode);

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

553
554
555
556
557
558
559
560
561
562
				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);
			}
563
564
565
566

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Source);
			set_ia32_op_type(new_op, ia32_AddrModeS);
567
568
569

			/* Lea doesn't need a Proj */
			return new_op;
Christian Würdig's avatar
Christian Würdig committed
570
		}
571
572
573
		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
574

575
576
577
578
579
			/* 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
580
			new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, op1, op2, nomem);
Christian Würdig's avatar
Christian Würdig committed
581

582
583
			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Full);
584
			set_ia32_commutative(new_op);
585
		}
Christian Würdig's avatar
Christian Würdig committed
586
587
	}

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

590
591
	set_ia32_res_mode(new_op, mode);

592
	return new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Add_res);
Christian Würdig's avatar
Christian Würdig committed
593
594
595
596
}



597
598
599
/**
 * Creates an ia32 Mul.
 *
600
 * @param env   The transformation environment
601
602
 * @return the created ia32 Mul node
 */
603
604
605
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);
606
607
	ir_node *new_op;

Christian Würdig's avatar
Christian Würdig committed
608
	if (mode_is_float(env->mode)) {
609
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
610
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
611
			new_op = gen_binop(env, op1, op2, new_rd_ia32_xMul);
612
		else
Michael Beck's avatar
Michael Beck committed
613
			new_op = gen_binop(env, op1, op2, new_rd_ia32_vfmul);
Christian Würdig's avatar
Christian Würdig committed
614
615
	}
	else {
616
		new_op = gen_binop(env, op1, op2, new_rd_ia32_Mul);
Christian Würdig's avatar
Christian Würdig committed
617
	}
618

619
620
	return new_op;
}
621
622
623
624
625
626
627
628



/**
 * 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.
 *
629
 * @param env   The transformation environment
630
631
 * @return the created ia32 Mulh node
 */
632
633
634
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);
635
636
	ir_node *proj_EAX, *proj_EDX, *mulh;
	ir_node *in[1];
637

Daniel Grund's avatar
Daniel Grund committed
638
	assert(!mode_is_float(env->mode) && "Mulh with float not supported");
639
640
641
	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);
642

643
644
	/* to be on the save side */
	set_Proj_proj(proj_EAX, pn_EAX);
645

646
	if (is_ia32_ImmConst(mulh) || is_ia32_ImmSymConst(mulh)) {
647
648
649
650
651
652
653
654
655
656
657
658
659
660
		/* 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;
661
662
}

663
664


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



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



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



/**
 * Creates an ia32 Max.
 *
716
717
 * @param env      The transformation environment
 * @return the created ia32 Max node
718
 */
719
720
721
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);
722
723
724
	ir_node *new_op;

	if (mode_is_float(env->mode)) {
725
		FP_USED(env->cg);
726
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
727
			new_op = gen_binop(env, op1, op2, new_rd_ia32_xMax);
728
729
730
		else {
			assert(0);
		}
731
732
733
734
	}
	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
735
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
736
737
738
	}

	return new_op;
739
740
741
742
743
744
745
}



/**
 * Creates an ia32 Min.
 *
746
747
 * @param env      The transformation environment
 * @return the created ia32 Min node
748
 */
749
750
751
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);
752
753
754
	ir_node *new_op;

	if (mode_is_float(env->mode)) {
755
		FP_USED(env->cg);
756
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
757
			new_op = gen_binop(env, op1, op2, new_rd_ia32_xMin);
758
759
760
		else {
			assert(0);
		}
761
762
763
764
	}
	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
765
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
766
767
768
	}

	return new_op;
769
770
771
772
773
774
775
}



/**
 * Creates an ia32 Sub with immediate.
 *
776
777
778
 * @param env        The transformation environment
 * @param expr_op    The first operator
 * @param const_op   The constant operator
779
 * @return The created ia32 Sub node
780
 */
Christian Würdig's avatar
Christian Würdig committed
781
static ir_node *gen_imm_Sub(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
782
783
784
785
786
	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;
787
	ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
788
789
	ir_node                *nomem      = new_NoMem();
	int                     normal_sub = 1;
Christian Würdig's avatar
Christian Würdig committed
790
	tarval_classification_t class_tv, class_negtv;
791
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
Christian Würdig's avatar
Christian Würdig committed
792

793
	/* try to optimize to inc/dec  */
794
	if ((env->cg->opt & IA32_OPT_INCDEC) && tv) {
Christian Würdig's avatar
Christian Würdig committed
795
796
797
798
799
		/* 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
800
			DB((mod, LEVEL_2, "Sub(1) to Dec ... "));
Michael Beck's avatar
Michael Beck committed
801
			new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
802
			normal_sub = 0;
Christian Würdig's avatar
Christian Würdig committed
803
804
		}
		else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
Christian Würdig's avatar
Christian Würdig committed
805
			DB((mod, LEVEL_2, "Sub(-1) to Inc ... "));
Michael Beck's avatar
Michael Beck committed
806
			new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
807
			normal_sub = 0;
Christian Würdig's avatar
Christian Würdig committed
808
809
810
		}
	}

811
	if (normal_sub) {
Michael Beck's avatar
Michael Beck committed
812
		new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
813
814
		set_ia32_Immop_attr(new_op, const_op);
	}
Christian Würdig's avatar
Christian Würdig committed
815
816

	return new_op;
817
818
819
820
821
}

/**
 * Creates an ia32 Sub.
 *
822
823
 * @param env   The transformation environment
 * @return The created ia32 Sub node
824
 */
825
static ir_node *gen_Sub(ia32_transform_env_t *env) {
826
827
828
829
830
	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;
831
	ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
832
	ir_node  *nomem  = new_NoMem();
833
834
	ir_node  *op1    = get_Sub_left(env->irn);
	ir_node  *op2    = get_Sub_right(env->irn);
835
836
	ir_node  *expr_op, *imm_op;

837
838
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
839
	imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, op2) : NULL;
840
841
842
843
844
	expr_op = get_expr_op(op1, op2);

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

	if (mode_is_float(mode)) {
845
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
846
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
847
			return gen_binop(env, op1, op2, new_rd_ia32_xSub);
848
		else
Michael Beck's avatar
Michael Beck committed
849
			return gen_binop(env, op1, op2, new_rd_ia32_vfsub);
Christian Würdig's avatar
Christian Würdig committed
850
	}
851
852
	else {
		/* integer SUB */
853
		if (! expr_op) {
854
855
856
			/* 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                                 */
857
			/* We need to check for:                                       */
858
859
			/*  1) symconst - const    -> becomes a LEA                    */
			/*  2) symconst - symconst -> becomes a const - LEA as the elf */
860
861
862
863
864
865
866
867
			/*        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
868

869
				DBG_OPT_LEA3(op1, op2, env->irn, new_op);
870
871
872
873
874
			}
			else {
				/* this is the 1st case */
				new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode);

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

877
878
879
880
881
882
883
884
885
886
887
				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);
			}
888
889
890
891

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Source);
			set_ia32_op_type(new_op, ia32_AddrModeS);
892
893
894

			/* Lea doesn't need a Proj */
			return new_op;
895
896
897
898
899
900
901
902
903
904
		}
		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
905
			new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, op1, op2, nomem);
906
907
908
909
910
911

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

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

914
915
	set_ia32_res_mode(new_op, mode);

916
	return new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Sub_res);
917
918
}

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

920
921

/**
Christian Würdig's avatar
Christian Würdig committed
922
923
 * Generates an ia32 DivMod with additional infrastructure for the
 * register allocator if needed.
924
 *
Christian Würdig's avatar
Christian Würdig committed
925
926
927
928
929
930
 * @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
 */
931
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
932
933
934
935
936
937
938
939
	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;
940
	ir_node  *mem;
941
	int      n;
942
943
944

	switch (dm_flav) {
		case flavour_Div:
Christian Würdig's avatar
Christian Würdig committed
945
946
			mem  = get_Div_mem(irn);
			mode = get_irn_mode(get_proj_for_pn(irn, pn_Div_res));
947
948
			break;
		case flavour_Mod:
Christian Würdig's avatar
Christian Würdig committed
949
950
			mem  = get_Mod_mem(irn);
			mode = get_irn_mode(get_proj_for_pn(irn, pn_Mod_res));
951
952
			break;
		case flavour_DivMod:
Christian Würdig's avatar
Christian Würdig committed
953
954
			mem  = get_DivMod_mem(irn);
			mode = get_irn_mode(get_proj_for_pn(irn, pn_DivMod_res_div));
955
956
957
958
			break;
		default:
			assert(0);
	}
Christian Würdig's avatar
Christian Würdig committed
959
960
961

	if (mode_is_signed(mode)) {
		/* in signed mode, we need to sign extend the dividend */
Michael Beck's avatar
Michael Beck committed
962
963
964
		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
965
966
	}
	else {
967
		edx_node = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode_Iu);
968
		set_ia32_Const_type(edx_node, ia32_Const);
Christian Würdig's avatar
Christian Würdig committed
969
970
971
		set_ia32_Immop_tarval(edx_node, get_tarval_null(mode_Iu));
	}

Michael Beck's avatar
Michael Beck committed
972
	res = new_rd_ia32_DivMod(dbg, irg, block, dividend, divisor, edx_node, mem, dm_flav);
Christian Würdig's avatar
Christian Würdig committed
973
974
975
976
977
978

	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.                                    */
979
980
981
982
983
984
985
986
987
	n    = get_irn_n_edges(irn);
	proj = NULL;
	if (n == 2)
		proj = ia32_get_proj_for_mode(irn, mode_M);

	/* in case of two projs, one must be the memory proj */
	if (n == 1 || (n == 2 && proj)) {
		proj = ia32_get_res_proj(irn);
		assert(proj && "Result proj expected");
Christian Würdig's avatar
Christian Würdig committed
988

989
990
		if (get_irn_op(irn) == op_Div) {
			set_Proj_proj(proj, pn_DivMod_res_div);
991
			in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode, pn_DivMod_res_mod);
Christian Würdig's avatar
Christian Würdig committed
992
993
		}
		else {
994
			set_Proj_proj(proj, pn_DivMod_res_mod);
995
			in_keep[0] = new_rd_Proj(dbg, irg, block, res, mode, pn_DivMod_res_div);
Christian Würdig's avatar
Christian Würdig committed
996
997
		}

998
		be_new_Keep(&ia32_reg_classes[CLASS_ia32_gp], irg, block, 1, in_keep);
Christian Würdig's avatar
Christian Würdig committed
999
1000
	}

For faster browsing, not all history is shown. View entire blame