ia32_transform.c 101 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
/**
Christian Würdig's avatar
Christian Würdig committed
136
137
 * Collects all Projs of a node into the node array. Index is the projnum.
 * BEWARE: The caller has to assure the appropriate array size!
138
 */
Christian Würdig's avatar
Christian Würdig committed
139
140
141
142
143
144
static void ia32_collect_Projs(ir_node *irn, ir_node **projs, int size) {
	const ir_edge_t *edge;
	ir_node         *proj;
	assert(get_irn_mode(irn) == mode_T && "need mode_T");

	memset(projs, 0, size * sizeof(projs[0]));
145

Christian Würdig's avatar
Christian Würdig committed
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
	foreach_out_edge(irn, edge) {
		proj                       = get_edge_src_irn(edge);
		projs[get_Proj_proj(proj)] = proj;
	}
}

/**
 * Renumbers the proj having pn_old in the array tp pn_new
 * and removes the proj from the array.
 */
static INLINE void ia32_renumber_Proj(ir_node **projs, long pn_old, long pn_new) {
	if (projs[pn_old]) {
		set_Proj_proj(projs[pn_old], pn_new);
		projs[pn_old] = NULL;
	}
161
162
}

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/**
 * 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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
/**
* 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);
}

199
/* Generates an entity for a known FP const (used for FP Neg + Abs) */
Michael Beck's avatar
BugFix:    
Michael Beck committed
200
static ident *gen_fp_known_const(ia32_known_const_t kct) {
201
202
203
204
205
206
207
208
209
210
	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 */
	};
Michael Beck's avatar
Michael Beck committed
211
	static entity *ent_cache[ia32_known_const_max];
212
213

	const char    *tp_name, *ent_name, *cnst_str;
214
215
216
217
	ir_type       *tp;
	ir_node       *cnst;
	ir_graph      *rem;
	entity        *ent;
218
	tarval        *tv;
Michael Beck's avatar
BugFix:    
Michael Beck committed
219
	ir_mode       *mode;
220

Christian Würdig's avatar
Christian Würdig committed
221
	ent_name = names[kct].ent_name;
222
223
224
	if (! ent_cache[kct]) {
		tp_name  = names[kct].tp_name;
		cnst_str = names[kct].cnst_str;
225

Michael Beck's avatar
BugFix:    
Michael Beck committed
226
		mode = kct == ia32_SSIGN || kct == ia32_SABS ? mode_Iu : mode_Lu;
227
		tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
228
229
230
231
232
233
234
235
236
237
238
239
		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();
240
		cnst = new_Const(mode, tv);
241
242
243
244
		current_ir_graph = rem;

		set_atomic_ent_value(ent, cnst);

245
246
		/* cache the entry */
		ent_cache[kct] = ent;
247
	}
248
249

	return get_entity_ident(ent_cache[kct]);
250
251
}

Christian Würdig's avatar
Christian Würdig committed
252
253
254
255
#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
256
257
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;
258

Christian Würdig's avatar
Christian Würdig committed
259
	lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
Christian Würdig's avatar
Christian Würdig committed
260
	obstack_1grow(isa->name_obst, 0);
Christian Würdig's avatar
Christian Würdig committed
261
	isa->name_obst_size += obstack_object_size(isa->name_obst);
Christian Würdig's avatar
Christian Würdig committed
262
263
264
 	return obstack_finish(isa->name_obst);
}
#endif /* NDEBUG */
Christian Würdig's avatar
Christian Würdig committed
265

266
267
/* 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
268
	if (op1)
Christian Würdig's avatar
Christian Würdig committed
269
270
		return is_ia32_Cnst(op1) ? op1 : (is_ia32_Cnst(op2) ? op2 : NULL);
	else return is_ia32_Cnst(op2) ? op2 : NULL;
271
272
273
274
}

/* 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
275
	return !is_ia32_Cnst(op1) ? op1 : (!is_ia32_Cnst(op2) ? op2 : NULL);
276
277
278
279
280
281
282
283
284
285
286
287
288
}


/**
 * 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) {
289
290
291
292
293
294
295
296
297
298
	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;
299
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
300

301
302
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
303
	/* Mul/MulS/Mulh don't support immediates    */
Christian Würdig's avatar
Christian Würdig committed
304
	if (! (env->cg->opt & IA32_OPT_IMMOPS) ||
305
		func == new_rd_ia32_Mul            ||
Christian Würdig's avatar
Christian Würdig committed
306
307
308
		func == new_rd_ia32_Mulh           ||
		func == new_rd_ia32_MulS)
	{
309
310
		expr_op = op1;
		imm_op  = NULL;
311
312
313
		/* immediate operations are requested, but we are here: it a mul */
		if (env->cg->opt & IA32_OPT_IMMOPS)
			is_mul = 1;
314
315
	}
	else if (is_op_commutative(get_irn_op(env->irn))) {
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
		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) {
334
			DB((mod, LEVEL_1, "FP with immediate ..."));
Michael Beck's avatar
Michael Beck committed
335
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_fp, nomem);
336
337
338
339
			set_ia32_Immop_attr(new_op, imm_op);
			set_ia32_am_support(new_op, ia32_am_None);
		}
		else {
340
			DB((mod, LEVEL_1, "FP binop ..."));
Michael Beck's avatar
Michael Beck committed
341
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem);
342
343
			set_ia32_am_support(new_op, ia32_am_Source);
		}
344
		set_ia32_ls_mode(new_op, mode);
345
346
347
348
349
	}
	else {
		/* integer operations */
		if (imm_op) {
			/* This is expr + const */
350
			DB((mod, LEVEL_1, "INT with immediate ..."));
Michael Beck's avatar
Michael Beck committed
351
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, expr_op, noreg_gp, nomem);
352
353
354
355
356
357
			set_ia32_Immop_attr(new_op, imm_op);

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Dest);
		}
		else {
358
			DB((mod, LEVEL_1, "INT binop ..."));
359
			/* This is a normal operation */
Michael Beck's avatar
Michael Beck committed
360
			new_op = func(dbg, irg, block, noreg_gp, noreg_gp, op1, op2, nomem);
361
362
363
364

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Full);
		}
365
366
367
368

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

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

373
374
	set_ia32_res_mode(new_op, mode);

Christian Würdig's avatar
Christian Würdig committed
375
376
377
378
	if (is_op_commutative(get_irn_op(env->irn))) {
		set_ia32_commutative(new_op);
	}

379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
	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;
399
	ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
400
401
402
	ir_node           *nomem  = new_NoMem();
	ir_node           *expr_op, *imm_op;
	tarval            *tv;
403
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
404
405
406

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

407
408
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
409
	imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, op2) : NULL;
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
	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));
425
			set_ia32_Immop_tarval(imm_op, tv);
426
427
428
429
430
431
432
433
434
		}
		else {
			imm_op = NULL;
		}
	}

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

Michael Beck's avatar
Michael Beck committed
437
		new_op = func(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
438
439
440
441
		set_ia32_Immop_attr(new_op, imm_op);
	}
	else {
		/* This is a normal shift/rot */
442
		DB((mod, LEVEL_1, "Shift/Rot binop ..."));
Michael Beck's avatar
Michael Beck committed
443
		new_op = func(dbg, irg, block, noreg, noreg, op1, op2, nomem);
444
445
446
447
448
	}

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

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

451
	set_ia32_res_mode(new_op, mode);
Christian Würdig's avatar
Christian Würdig committed
452
	set_ia32_emit_cl(new_op);
453

454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
	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;
472
	ir_node           *noreg  = ia32_new_NoReg_gp(env->cg);
473
	ir_node           *nomem  = new_NoMem();
474
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
475

Michael Beck's avatar
Michael Beck committed
476
	new_op = func(dbg, irg, block, noreg, noreg, op, nomem);
477
478

	if (mode_is_float(mode)) {
479
		DB((mod, LEVEL_1, "FP unop ..."));
480
481
482
483
		/* floating point operations don't support implicit store */
		set_ia32_am_support(new_op, ia32_am_None);
	}
	else {
484
		DB((mod, LEVEL_1, "INT unop ..."));
485
486
487
		set_ia32_am_support(new_op, ia32_am_Dest);
	}

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

490
491
	set_ia32_res_mode(new_op, mode);

492
	return new_rd_Proj(dbg, irg, block, new_op, mode, 0);
493
494
495
496
497
498
499
}



/**
 * Creates an ia32 Add with immediate.
 *
500
501
502
503
 * @param env       The transformation environment
 * @param expr_op   The expression operator
 * @param const_op  The constant
 * @return the created ia32 Add node
504
 */
Christian Würdig's avatar
Christian Würdig committed
505
static ir_node *gen_imm_Add(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
506
507
508
509
510
	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;
511
	ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
512
513
	ir_node                *nomem      = new_NoMem();
	int                     normal_add = 1;
Christian Würdig's avatar
Christian Würdig committed
514
	tarval_classification_t class_tv, class_negtv;
515
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
Christian Würdig's avatar
Christian Würdig committed
516

517
	/* try to optimize to inc/dec  */
518
	if ((env->cg->opt & IA32_OPT_INCDEC) && (get_ia32_op_type(const_op) == ia32_Const)) {
Christian Würdig's avatar
Christian Würdig committed
519
520
521
522
523
		/* 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
524
			DB((env->mod, LEVEL_2, "Add(1) to Inc ... "));
Michael Beck's avatar
Michael Beck committed
525
			new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
526
			normal_add = 0;
Christian Würdig's avatar
Christian Würdig committed
527
528
		}
		else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
Christian Würdig's avatar
Christian Würdig committed
529
			DB((mod, LEVEL_2, "Add(-1) to Dec ... "));
Michael Beck's avatar
Michael Beck committed
530
			new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
531
			normal_add = 0;
Christian Würdig's avatar
Christian Würdig committed
532
533
534
		}
	}

535
	if (normal_add) {
Michael Beck's avatar
Michael Beck committed
536
		new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
537
		set_ia32_Immop_attr(new_op, const_op);
538
		set_ia32_commutative(new_op);
539
	}
Christian Würdig's avatar
Christian Würdig committed
540
541

	return new_op;
542
543
544
545
546
}

/**
 * Creates an ia32 Add.
 *
547
 * @param env   The transformation environment
548
549
 * @return the created ia32 Add node
 */
550
static ir_node *gen_Add(ia32_transform_env_t *env) {
551
552
553
554
555
	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;
556
	ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
557
558
	ir_node  *nomem  = new_NoMem();
	ir_node  *expr_op, *imm_op;
559
560
	ir_node  *op1    = get_Add_left(env->irn);
	ir_node  *op2    = get_Add_right(env->irn);
561

562
563
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
564
	imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(op1, op2) : NULL;
565
566
567
	expr_op = get_expr_op(op1, op2);

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

	if (mode_is_float(mode)) {
570
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
571
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
572
			return gen_binop(env, op1, op2, new_rd_ia32_xAdd);
573
		else
Michael Beck's avatar
Michael Beck committed
574
			return gen_binop(env, op1, op2, new_rd_ia32_vfadd);
Christian Würdig's avatar
Christian Würdig committed
575
	}
576
577
578
579
580
581
	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                                 */
582
583
584
585
586
587
588
589
590
591
			/* 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
592

593
				DBG_OPT_LEA3(op1, op2, env->irn, new_op);
594
595
596
597
598
			}
			else {
				/* this is the 1st case */
				new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode);

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

601
602
603
604
605
606
607
608
609
610
				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);
			}
611
612
613
614

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Source);
			set_ia32_op_type(new_op, ia32_AddrModeS);
615
616
617

			/* Lea doesn't need a Proj */
			return new_op;
Christian Würdig's avatar
Christian Würdig committed
618
		}
619
620
621
		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
622

623
624
625
626
627
			/* 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
628
			new_op = new_rd_ia32_Add(dbg, irg, block, noreg, noreg, op1, op2, nomem);
Christian Würdig's avatar
Christian Würdig committed
629

630
631
			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Full);
632
			set_ia32_commutative(new_op);
633
		}
Christian Würdig's avatar
Christian Würdig committed
634
635
	}

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

638
639
	set_ia32_res_mode(new_op, mode);

640
	return new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Add_res);
Christian Würdig's avatar
Christian Würdig committed
641
642
643
644
}



645
646
647
/**
 * Creates an ia32 Mul.
 *
648
 * @param env   The transformation environment
649
650
 * @return the created ia32 Mul node
 */
651
652
653
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);
654
655
	ir_node *new_op;

Christian Würdig's avatar
Christian Würdig committed
656
	if (mode_is_float(env->mode)) {
657
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
658
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
659
			new_op = gen_binop(env, op1, op2, new_rd_ia32_xMul);
660
		else
Michael Beck's avatar
Michael Beck committed
661
			new_op = gen_binop(env, op1, op2, new_rd_ia32_vfmul);
Christian Würdig's avatar
Christian Würdig committed
662
663
	}
	else {
664
		new_op = gen_binop(env, op1, op2, new_rd_ia32_Mul);
Christian Würdig's avatar
Christian Würdig committed
665
	}
666

667
668
	return new_op;
}
669
670
671
672
673
674
675
676



/**
 * 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.
 *
677
 * @param env   The transformation environment
678
679
 * @return the created ia32 Mulh node
 */
680
681
682
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);
683
684
	ir_node *proj_EAX, *proj_EDX, *mulh;
	ir_node *in[1];
685

Daniel Grund's avatar
Daniel Grund committed
686
	assert(!mode_is_float(env->mode) && "Mulh with float not supported");
687
688
689
	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);
690

691
692
	/* to be on the save side */
	set_Proj_proj(proj_EAX, pn_EAX);
693

694
	if (is_ia32_ImmConst(mulh) || is_ia32_ImmSymConst(mulh)) {
695
696
697
698
699
700
701
702
703
704
705
706
707
708
		/* 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;
709
710
}

711
712


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



/**
 * Creates an ia32 Or.
 *
732
733
 * @param env   The transformation environment
 * @return The created ia32 Or node
734
 */
735
736
737
738
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
739
740
	assert (! mode_is_float(env->mode));
	return gen_binop(env, op1, op2, new_rd_ia32_Or);
741
742
743
744
745
746
747
}



/**
 * Creates an ia32 Eor.
 *
748
749
 * @param env   The transformation environment
 * @return The created ia32 Eor node
750
 */
751
752
753
754
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
755
756
	assert(! mode_is_float(env->mode));
	return gen_binop(env, op1, op2, new_rd_ia32_Eor);
757
758
759
760
761
762
763
}



/**
 * Creates an ia32 Max.
 *
764
765
 * @param env      The transformation environment
 * @return the created ia32 Max node
766
 */
767
768
769
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);
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_xMax);
776
777
778
		else {
			assert(0);
		}
779
780
781
782
	}
	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
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 Min.
 *
794
795
 * @param env      The transformation environment
 * @return the created ia32 Min node
796
 */
797
798
799
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);
800
801
802
	ir_node *new_op;

	if (mode_is_float(env->mode)) {
803
		FP_USED(env->cg);
804
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
805
			new_op = gen_binop(env, op1, op2, new_rd_ia32_xMin);
806
807
808
		else {
			assert(0);
		}
809
810
811
812
	}
	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
813
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env->cg, env->irn));
814
815
816
	}

	return new_op;
817
818
819
820
821
822
823
}



/**
 * Creates an ia32 Sub with immediate.
 *
824
825
826
 * @param env        The transformation environment
 * @param expr_op    The first operator
 * @param const_op   The constant operator
827
 * @return The created ia32 Sub node
828
 */
Christian Würdig's avatar
Christian Würdig committed
829
static ir_node *gen_imm_Sub(ia32_transform_env_t *env, ir_node *expr_op, ir_node *const_op) {
830
831
832
833
834
	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;
835
	ir_node                *noreg      = ia32_new_NoReg_gp(env->cg);
836
837
	ir_node                *nomem      = new_NoMem();
	int                     normal_sub = 1;
Christian Würdig's avatar
Christian Würdig committed
838
	tarval_classification_t class_tv, class_negtv;
839
	DEBUG_ONLY(firm_dbg_module_t *mod = env->mod;)
Christian Würdig's avatar
Christian Würdig committed
840

841
	/* try to optimize to inc/dec  */
842
	if ((env->cg->opt & IA32_OPT_INCDEC) && tv) {
Christian Würdig's avatar
Christian Würdig committed
843
844
845
846
847
		/* 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
848
			DB((mod, LEVEL_2, "Sub(1) to Dec ... "));
Michael Beck's avatar
Michael Beck committed
849
			new_op     = new_rd_ia32_Dec(dbg, irg, block, noreg, noreg, expr_op, nomem);
850
			normal_sub = 0;
Christian Würdig's avatar
Christian Würdig committed
851
852
		}
		else if (class_negtv == TV_CLASSIFY_ONE) { /* - (-1) == Sub */
Christian Würdig's avatar
Christian Würdig committed
853
			DB((mod, LEVEL_2, "Sub(-1) to Inc ... "));
Michael Beck's avatar
Michael Beck committed
854
			new_op     = new_rd_ia32_Inc(dbg, irg, block, noreg, noreg, expr_op, nomem);
855
			normal_sub = 0;
Christian Würdig's avatar
Christian Würdig committed
856
857
858
		}
	}

859
	if (normal_sub) {
Michael Beck's avatar
Michael Beck committed
860
		new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, expr_op, noreg, nomem);
861
862
		set_ia32_Immop_attr(new_op, const_op);
	}
Christian Würdig's avatar
Christian Würdig committed
863
864

	return new_op;
865
866
867
868
869
}

/**
 * Creates an ia32 Sub.
 *
870
871
 * @param env   The transformation environment
 * @return The created ia32 Sub node
872
 */
873
static ir_node *gen_Sub(ia32_transform_env_t *env) {
874
875
876
877
878
	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;
879
	ir_node  *noreg  = ia32_new_NoReg_gp(env->cg);
880
	ir_node  *nomem  = new_NoMem();
881
882
	ir_node  *op1    = get_Sub_left(env->irn);
	ir_node  *op2    = get_Sub_right(env->irn);
883
884
	ir_node  *expr_op, *imm_op;

885
886
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
887
	imm_op  = (env->cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, op2) : NULL;
888
889
890
891
892
	expr_op = get_expr_op(op1, op2);

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

	if (mode_is_float(mode)) {
893
		FP_USED(env->cg);
Michael Beck's avatar
Michael Beck committed
894
		if (USE_SSE2(env->cg))
Christian Würdig's avatar
Christian Würdig committed
895
			return gen_binop(env, op1, op2, new_rd_ia32_xSub);
896
		else
Michael Beck's avatar
Michael Beck committed
897
			return gen_binop(env, op1, op2, new_rd_ia32_vfsub);
Christian Würdig's avatar
Christian Würdig committed
898
	}
899
900
	else {
		/* integer SUB */
901
		if (! expr_op) {
902
903
904
			/* 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                                 */
905
			/* We need to check for:                                       */
906
907
			/*  1) symconst - const    -> becomes a LEA                    */
			/*  2) symconst - symconst -> becomes a const - LEA as the elf */
908
909
910
911
912
913
914
915
			/*        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
916

917
				DBG_OPT_LEA3(op1, op2, env->irn, new_op);
918
919
920
921
922
			}
			else {
				/* this is the 1st case */
				new_op = new_rd_ia32_Lea(dbg, irg, block, noreg, noreg, mode);

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

925
926
927
928
929
930
931
932
933
934
935
				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);
			}
936
937
938
939

			/* set AM support */
			set_ia32_am_support(new_op, ia32_am_Source);
			set_ia32_op_type(new_op, ia32_AddrModeS);
940
941
942

			/* Lea doesn't need a Proj */
			return new_op;
943
944
945
946
947
948
949
950
951
952
		}
		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
953
			new_op = new_rd_ia32_Sub(dbg, irg, block, noreg, noreg, op1, op2, nomem);
954
955
956
957
958
959

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

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

962
963
	set_ia32_res_mode(new_op, mode);

964
	return new_rd_Proj(dbg, irg, block, new_op, mode, pn_ia32_Sub_res);
965
966
}

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

968
969

/**
Christian Würdig's avatar
Christian Würdig committed
970
971
 * Generates an ia32 DivMod with additional infrastructure for the
 * register allocator if needed.
972
 *
Christian Würdig's avatar
Christian Würdig committed
973
974
975
976
977
978
 * @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
 */
979
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
980
	ir_node  *res, *proj_div, *proj_mod;
Christian Würdig's avatar
Christian Würdig committed
981
982
983
984
985
986
987
	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;
988
	ir_node  *mem;
Christian Würdig's avatar
Christian Würdig committed
989
990
991
	ir_node  *projs[pn_DivMod_max];

	ia32_collect_Projs(irn, projs, pn_DivMod_max);
992
993
994

	switch (dm_flav) {
		case flavour_Div:
Christian Würdig's avatar
Christian Würdig committed
995
996
			mem  = get_Div_mem(irn);
			mode = get_irn_mode(get_proj_for_pn(irn, pn_Div_res));
997
998
			break;
		case flavour_Mod:
Christian Würdig's avatar
Christian Würdig committed
999
1000
			mem  = get_Mod_mem(irn);
			mode = get_irn_mode(get_proj_for_pn(irn, pn_Mod_res));
For faster browsing, not all history is shown. View entire blame