ia32_transform.c 128 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

Christian Würdig's avatar
Christian Würdig committed
20
/**
Christian Würdig's avatar
Christian Würdig committed
21
 * @file
22
23
 * @brief       This file implements the IR transformation from firm into
 *              ia32-Firm.
Christian Würdig's avatar
Christian Würdig committed
24
25
 * @author      Christian Wuerdig, Matthias Braun
 * @version     $Id$
Christian Würdig's avatar
Christian Würdig committed
26
 */
27
#ifdef HAVE_CONFIG_H
28
#include "config.h"
29
30
#endif

Christian Würdig's avatar
Christian Würdig committed
31
32
#include <limits.h>

Christian Würdig's avatar
Christian Würdig committed
33
#include "irargs_t.h"
34
35
36
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
Christian Würdig's avatar
Christian Würdig committed
37
38
39
#include "iropt_t.h"
#include "irop_t.h"
#include "irprog_t.h"
Christian Würdig's avatar
Christian Würdig committed
40
#include "iredges_t.h"
41
#include "irgmod.h"
Christian Würdig's avatar
Christian Würdig committed
42
#include "irvrfy.h"
43
#include "ircons.h"
44
#include "irgwalk.h"
45
#include "irprintf.h"
46
#include "debug.h"
47
#include "irdom.h"
48
#include "archop.h"
49
#include "error.h"
50

Christian Würdig's avatar
Christian Würdig committed
51
#include "../benode_t.h"
Christian Würdig's avatar
Christian Würdig committed
52
#include "../besched.h"
Christian Würdig's avatar
Christian Würdig committed
53
#include "../beabi.h"
54
#include "../beutil.h"
55
#include "../beirg_t.h"
Michael Beck's avatar
Michael Beck committed
56
#include "../betranshlp.h"
Christian Würdig's avatar
Christian Würdig committed
57

58
#include "bearch_ia32_t.h"
59
60
61
#include "ia32_nodes_attr.h"
#include "ia32_transform.h"
#include "ia32_new_nodes.h"
Christian Würdig's avatar
Christian Würdig committed
62
#include "ia32_map_regs.h"
Christian Würdig's avatar
Christian Würdig committed
63
#include "ia32_dbg_stat.h"
64
#include "ia32_optimize.h"
65
#include "ia32_util.h"
66

Christian Würdig's avatar
Christian Würdig committed
67
68
#include "gen_ia32_regalloc_if.h"

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#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"

84
85
86
#define mode_vfp	(ia32_reg_classes[CLASS_ia32_vfp].mode)
#define mode_xmm    (ia32_reg_classes[CLASS_ia32_xmm].mode)

87
88
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)

89
/** hold the current code generator during transformation */
90
91
static ia32_code_gen_t *env_cg       = NULL;
static ir_node         *initial_fpcw = NULL;
92

93
94
extern ir_op *get_op_Mulh(void);

95
96
97
typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
        ir_node *block, ir_node *base, ir_node *index, ir_node *op1,
        ir_node *op2, ir_node *mem);
Christian Würdig's avatar
Christian Würdig committed
98

Matthias Braun's avatar
Matthias Braun committed
99
100
101
102
typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
        ir_node *block, ir_node *base, ir_node *index, ir_node *op1,
        ir_node *op2, ir_node *mem, ir_node *fpcw);

103
104
105
typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
        ir_node *block, ir_node *base, ir_node *index, ir_node *op,
        ir_node *mem);
106

Christian Würdig's avatar
Christian Würdig committed
107
108
109
110
111
112
113
114
115
116
/****************************************************************************************************
 *                  _        _                        __                           _   _
 *                 | |      | |                      / _|                         | | (_)
 *  _ __   ___   __| | ___  | |_ _ __ __ _ _ __  ___| |_ ___  _ __ _ __ ___   __ _| |_ _  ___  _ __
 * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __|  _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
 * | | | | (_) | (_| |  __/ | |_| | | (_| | | | \__ \ || (_) | |  | | | | | | (_| | |_| | (_) | | | |
 * |_| |_|\___/ \__,_|\___|  \__|_|  \__,_|_| |_|___/_| \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
 *
 ****************************************************************************************************/

117
118
static ir_node *try_create_Immediate(ir_node *node,
                                     char immediate_constraint_type);
119

120
121
122
static ir_node *create_immediate_or_transform(ir_node *node,
                                              char immediate_constraint_type);

123
124
125
126
static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
                                dbg_info *dbgi, ir_node *new_block,
                                ir_node *new_op);

127
128
129
130
/**
 * Return true if a mode can be stored in the GP register set
 */
static INLINE int mode_needs_gp_reg(ir_mode *mode) {
131
132
	if(mode == mode_fpcw)
		return 0;
133
	return mode_is_int(mode) || mode_is_reference(mode) || mode == mode_b;
134
135
}

Christian Würdig's avatar
Christian Würdig committed
136
137
138
139
/**
 * Returns 1 if irn is a Const representing 0, 0 otherwise
 */
static INLINE int is_ia32_Const_0(ir_node *irn) {
140
141
	return is_ia32_irn(irn) && is_ia32_Const(irn) && get_ia32_immop_type(irn) == ia32_ImmConst
	       && tarval_is_null(get_ia32_Immop_tarval(irn));
Christian Würdig's avatar
Christian Würdig committed
142
143
144
145
146
147
}

/**
 * Returns 1 if irn is a Const representing 1, 0 otherwise
 */
static INLINE int is_ia32_Const_1(ir_node *irn) {
148
149
	return is_ia32_irn(irn) && is_ia32_Const(irn) && get_ia32_immop_type(irn) == ia32_ImmConst
	       && tarval_is_one(get_ia32_Immop_tarval(irn));
Christian Würdig's avatar
Christian Würdig committed
150
151
}

152
/**
Christian Würdig's avatar
Christian Würdig committed
153
154
 * Collects all Projs of a node into the node array. Index is the projnum.
 * BEWARE: The caller has to assure the appropriate array size!
155
 */
Christian Würdig's avatar
Christian Würdig committed
156
157
158
159
160
static void ia32_collect_Projs(ir_node *irn, ir_node **projs, int size) {
	const ir_edge_t *edge;
	assert(get_irn_mode(irn) == mode_T && "need mode_T");

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

Christian Würdig's avatar
Christian Würdig committed
162
	foreach_out_edge(irn, edge) {
163
164
165
166
		ir_node *proj = get_edge_src_irn(edge);
		int proj_proj = get_Proj_proj(proj);
		assert(proj_proj < size);
		projs[proj_proj] = proj;
Christian Würdig's avatar
Christian Würdig committed
167
168
169
170
171
172
173
174
	}
}

/**
 * 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) {
175
	fprintf(stderr, "Warning: renumber_Proj used!\n");
Christian Würdig's avatar
Christian Würdig committed
176
177
178
179
	if (projs[pn_old]) {
		set_Proj_proj(projs[pn_old], pn_new);
		projs[pn_old] = NULL;
	}
180
181
}

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/**
 * creates a unique ident by adding a number to a tag
 *
 * @param tag   the tag string, must contain a %d if a number
 *              should be added
 */
static ident *unique_id(const char *tag)
{
	static unsigned id = 0;
	char str[256];

	snprintf(str, sizeof(str), tag, ++id);
	return new_id_from_str(str);
}

/**
 * Get a primitive type for a mode.
 */
static ir_type *get_prim_type(pmap *types, ir_mode *mode)
{
	pmap_entry *e = pmap_find(types, mode);
	ir_type *res;

	if (! e) {
		char buf[64];
		snprintf(buf, sizeof(buf), "prim_type_%s", get_mode_name(mode));
		res = new_type_primitive(new_id_from_str(buf), mode);
209
		set_type_alignment_bytes(res, 16);
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
		pmap_insert(types, mode, res);
	}
	else
		res = e->value;
	return res;
}

/**
 * Get an entity that is initialized with a tarval
 */
static ir_entity *get_entity_for_tv(ia32_code_gen_t *cg, ir_node *cnst)
{
	tarval *tv    = get_Const_tarval(cnst);
	pmap_entry *e = pmap_find(cg->isa->tv_ent, tv);
	ir_entity *res;
	ir_graph *rem;

	if (! e) {
		ir_mode *mode = get_irn_mode(cnst);
		ir_type *tp = get_Const_type(cnst);
		if (tp == firm_unknown_type)
			tp = get_prim_type(cg->isa->types, mode);

		res = new_entity(get_glob_type(), unique_id(".LC%u"), tp);

		set_entity_ld_ident(res, get_entity_ident(res));
		set_entity_visibility(res, visibility_local);
		set_entity_variability(res, variability_constant);
		set_entity_allocation(res, 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();
		set_atomic_ent_value(res, new_Const_type(tv, tp));
		current_ir_graph = rem;

		pmap_insert(cg->isa->tv_ent, tv, res);
248
	} else {
249
		res = e->value;
250
251
	}

252
253
254
	return res;
}

255
256
257
258
259
260
261
262
263
264
265
266
267
268
static int is_Const_0(ir_node *node) {
	if(!is_Const(node))
		return 0;

	return classify_Const(node) == CNST_NULL;
}

static int is_Const_1(ir_node *node) {
	if(!is_Const(node))
		return 0;

	return classify_Const(node) == CNST_ONE;
}

269
270
271
/**
 * Transforms a Const.
 */
272
static ir_node *gen_Const(ir_node *node) {
273
274
275
276
277
	ir_graph *irg       = current_ir_graph;
	ir_node  *old_block = get_nodes_block(node);
	ir_node  *block     = be_transform_node(old_block);
	dbg_info *dbgi      = get_irn_dbg_info(node);
	ir_mode  *mode      = get_irn_mode(node);
278
279

	if (mode_is_float(mode)) {
280
		ir_node   *res   = NULL;
Michael Beck's avatar
Michael Beck committed
281
		ir_node   *noreg = ia32_new_NoReg_gp(env_cg);
282
283
		ir_node   *nomem = new_NoMem();
		ir_node   *load;
284
285
		ir_entity *floatent;

Michael Beck's avatar
Michael Beck committed
286
		if (! USE_SSE2(env_cg)) {
287
288
289
			cnst_classify_t clss = classify_Const(node);

			if (clss == CNST_NULL) {
290
				load = new_rd_ia32_vfldz(dbgi, irg, block);
291
				res  = load;
292
			} else if (clss == CNST_ONE) {
293
				load = new_rd_ia32_vfld1(dbgi, irg, block);
294
				res  = load;
295
			} else {
Michael Beck's avatar
Michael Beck committed
296
				floatent = get_entity_for_tv(env_cg, node);
297

Matthias Braun's avatar
Matthias Braun committed
298
				load     = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
299
300
				set_ia32_op_type(load, ia32_AddrModeS);
				set_ia32_am_flavour(load, ia32_am_N);
301
				set_ia32_am_sc(load, floatent);
302
303
				set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
				res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
304
			}
305
			set_ia32_ls_mode(load, mode);
306
		} else {
Michael Beck's avatar
Michael Beck committed
307
			floatent = get_entity_for_tv(env_cg, node);
308

309
			load     = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem);
310
311
			set_ia32_op_type(load, ia32_AddrModeS);
			set_ia32_am_flavour(load, ia32_am_N);
312
			set_ia32_am_sc(load, floatent);
313
			set_ia32_ls_mode(load, mode);
314
			set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
315
316

			res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
317
318
		}

Michael Beck's avatar
Michael Beck committed
319
		SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
320
321

		/* Const Nodes before the initial IncSP are a bad idea, because
322
323
324
		 * they could be spilled and we have no SP ready at that point yet.
		 * So add a dependency to the initial frame pointer calculation to
		 * avoid that situation.
325
326
327
328
329
		 */
		if (get_irg_start_block(irg) == block) {
			add_irn_dep(load, get_irg_frame(irg));
		}

Michael Beck's avatar
Michael Beck committed
330
		SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
331
332
		return res;
	} else {
333
		ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block);
334
335
336
337
338
339
340

		/* see above */
		if (get_irg_start_block(irg) == block) {
			add_irn_dep(cnst, get_irg_frame(irg));
		}

		set_ia32_Const_attr(cnst, node);
Michael Beck's avatar
Michael Beck committed
341
		SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
342
343
344
345
346
347
348
349
350
351
		return cnst;
	}

	assert(0);
	return new_r_Bad(irg);
}

/**
 * Transforms a SymConst.
 */
352
static ir_node *gen_SymConst(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
353
	ir_graph *irg   = current_ir_graph;
354
355
	ir_node  *old_block = get_nodes_block(node);
	ir_node  *block = be_transform_node(old_block);
356
357
	dbg_info *dbgi  = get_irn_dbg_info(node);
	ir_mode  *mode  = get_irn_mode(node);
358
359
360
	ir_node  *cnst;

	if (mode_is_float(mode)) {
Michael Beck's avatar
Michael Beck committed
361
		if (USE_SSE2(env_cg))
362
			cnst = new_rd_ia32_xConst(dbgi, irg, block);
363
		else
364
			cnst = new_rd_ia32_vfConst(dbgi, irg, block);
365
366
		//set_ia32_ls_mode(cnst, mode);
		set_ia32_ls_mode(cnst, mode_E);
367
	} else {
368
		cnst = new_rd_ia32_Const(dbgi, irg, block);
369
370
371
372
373
374
375
376
377
378
	}

	/* Const Nodes before the initial IncSP are a bad idea, because
	 * they could be spilled and we have no SP ready at that point yet
	 */
	if (get_irg_start_block(irg) == block) {
		add_irn_dep(cnst, get_irg_frame(irg));
	}

	set_ia32_Const_attr(cnst, node);
Michael Beck's avatar
Michael Beck committed
379
	SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
380
381
382
383

	return cnst;
}

384
/* Generates an entity for a known FP const (used for FP Neg + Abs) */
385
ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
386
387
388
389
390
391
392
393
394
395
	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 */
	};
396
	static ir_entity *ent_cache[ia32_known_const_max];
397
398

	const char    *tp_name, *ent_name, *cnst_str;
399
400
401
	ir_type       *tp;
	ir_node       *cnst;
	ir_graph      *rem;
402
	ir_entity     *ent;
403
	tarval        *tv;
Michael Beck's avatar
BugFix:    
Michael Beck committed
404
	ir_mode       *mode;
405

Christian Würdig's avatar
Christian Würdig committed
406
	ent_name = names[kct].ent_name;
407
408
409
	if (! ent_cache[kct]) {
		tp_name  = names[kct].tp_name;
		cnst_str = names[kct].cnst_str;
410

411
412
		mode = kct == ia32_SSIGN || kct == ia32_SABS ? mode_Iu : mode_Lu;
		//mode = mode_xmm;
413
		tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
414
415
416
417
418
419
420
421
422
423
424
425
		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();
426
		cnst = new_Const(mode, tv);
427
428
429
430
		current_ir_graph = rem;

		set_atomic_ent_value(ent, cnst);

431
432
		/* cache the entry */
		ent_cache[kct] = ent;
433
	}
434

435
	return ent_cache[kct];
436
437
}

Christian Würdig's avatar
Christian Würdig committed
438
439
440
441
#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
442
443
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;
444

Christian Würdig's avatar
Christian Würdig committed
445
	lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
Christian Würdig's avatar
Christian Würdig committed
446
447
448
449
	obstack_1grow(isa->name_obst, 0);
 	return obstack_finish(isa->name_obst);
}
#endif /* NDEBUG */
Christian Würdig's avatar
Christian Würdig committed
450

451
452
/* determine if one operator is an Imm */
static ir_node *get_immediate_op(ir_node *op1, ir_node *op2) {
453
	if (op1) {
Christian Würdig's avatar
Christian Würdig committed
454
		return is_ia32_Cnst(op1) ? op1 : (is_ia32_Cnst(op2) ? op2 : NULL);
455
456
457
	} else {
		return is_ia32_Cnst(op2) ? op2 : NULL;
	}
458
459
460
461
}

/* 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
462
	return !is_ia32_Cnst(op1) ? op1 : (!is_ia32_Cnst(op2) ? op2 : NULL);
463
464
}

465
static void fold_immediate(ir_node *node, int in1, int in2) {
466
467
468
	ir_node *left;
	ir_node *right;

Michael Beck's avatar
Michael Beck committed
469
	if (!(env_cg->opt & IA32_OPT_IMMOPS))
470
471
472
473
		return;

	left = get_irn_n(node, in1);
	right = get_irn_n(node, in2);
474
	if (! is_ia32_Cnst(right) && is_ia32_Cnst(left)) {
475
476
477
478
479
		/* we can only set right operand to immediate */
		if(!is_ia32_commutative(node))
			return;
		/* exchange left/right */
		set_irn_n(node, in1, right);
Michael Beck's avatar
Michael Beck committed
480
		set_irn_n(node, in2, ia32_get_admissible_noreg(env_cg, node, in2));
481
		copy_ia32_Immop_attr(node, left);
482
	} else if(is_ia32_Cnst(right)) {
Michael Beck's avatar
Michael Beck committed
483
		set_irn_n(node, in2, ia32_get_admissible_noreg(env_cg, node, in2));
484
		copy_ia32_Immop_attr(node, right);
485
486
487
488
	} else {
		return;
	}

489
	clear_ia32_commutative(node);
Matthias Braun's avatar
Matthias Braun committed
490
491
	set_ia32_am_support(node, get_ia32_am_support(node) & ~ia32_am_Source,
	                    get_ia32_am_arity(node));
492
}
493
494
495
496
497
498
499
500
501

/**
 * Construct a standard binary operation, set AM and immediate if required.
 *
 * @param op1   The first operand
 * @param op2   The second operand
 * @param func  The node constructor function
 * @return The constructed ia32 node.
 */
502
static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
503
                          construct_binop_func *func, int commutative)
504
{
Michael Beck's avatar
Michael Beck committed
505
506
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_graph *irg      = current_ir_graph;
507
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
508
	ir_node  *noreg_gp = ia32_new_NoReg_gp(env_cg);
509
	ir_node  *nomem    = new_NoMem();
510
	ir_node  *new_node;
511

512
	ir_node *new_op1 = be_transform_node(op1);
513
514
	ir_node *new_op2 = create_immediate_or_transform(op2, 0);
	if (is_ia32_Immediate(new_op2)) {
515
		commutative = 0;
516
517
	}

518
	new_node = func(dbgi, irg, block, noreg_gp, noreg_gp, new_op1, new_op2, nomem);
519
	if (func == new_rd_ia32_IMul) {
Matthias Braun's avatar
Matthias Braun committed
520
		set_ia32_am_support(new_node, ia32_am_Source, ia32_am_binary);
521
	} else {
Matthias Braun's avatar
Matthias Braun committed
522
		set_ia32_am_support(new_node, ia32_am_Full, ia32_am_binary);
523
524
	}

Michael Beck's avatar
Michael Beck committed
525
	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
526
	if (commutative) {
527
		set_ia32_commutative(new_node);
528
	}
Christian Würdig's avatar
Christian Würdig committed
529

530
	return new_node;
531
532
}

533
534
535
536
537
538
539
540
/**
 * Construct a standard binary operation, set AM and immediate if required.
 *
 * @param op1   The first operand
 * @param op2   The second operand
 * @param func  The node constructor function
 * @return The constructed ia32 node.
 */
Matthias Braun's avatar
Matthias Braun committed
541
542
static ir_node *gen_binop_sse_float(ir_node *node, ir_node *op1, ir_node *op2,
                                    construct_binop_func *func)
543
{
Michael Beck's avatar
Michael Beck committed
544
545
546
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1  = be_transform_node(op1);
	ir_node  *new_op2  = be_transform_node(op2);
547
	ir_node  *new_node = NULL;
548
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
549
	ir_graph *irg      = current_ir_graph;
550
	ir_mode  *mode     = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
551
	ir_node  *noreg_gp = ia32_new_NoReg_gp(env_cg);
552
553
	ir_node  *nomem    = new_NoMem();

Matthias Braun's avatar
Matthias Braun committed
554
555
556
	new_node = func(dbgi, irg, block, noreg_gp, noreg_gp, new_op1, new_op2,
	                nomem);
	set_ia32_am_support(new_node, ia32_am_Source, ia32_am_binary);
557
558
559
	if (is_op_commutative(get_irn_op(node))) {
		set_ia32_commutative(new_node);
	}
560
	set_ia32_ls_mode(new_node, mode);
561

Michael Beck's avatar
Michael Beck committed
562
	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
563
564
565

	return new_node;
}
566

567
568
569
570
571
572
573
574
575
576
577
578
579
static ir_node *get_fpcw(void)
{
	ir_node *fpcw;
	if(initial_fpcw != NULL)
		return initial_fpcw;

	fpcw         = be_abi_get_ignore_irn(env_cg->birg->abi,
	                                     &ia32_fp_cw_regs[REG_FPCW]);
	initial_fpcw = be_transform_node(fpcw);

	return initial_fpcw;
}

Matthias Braun's avatar
Matthias Braun committed
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
/**
 * Construct a standard binary operation, set AM and immediate if required.
 *
 * @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_x87_float(ir_node *node, ir_node *op1, ir_node *op2,
                                    construct_binop_float_func *func)
{
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1  = be_transform_node(op1);
	ir_node  *new_op2  = be_transform_node(op2);
	ir_node  *new_node = NULL;
	dbg_info *dbgi     = get_irn_dbg_info(node);
	ir_graph *irg      = current_ir_graph;
	ir_node  *noreg_gp = ia32_new_NoReg_gp(env_cg);
	ir_node  *nomem    = new_NoMem();

	new_node = func(dbgi, irg, block, noreg_gp, noreg_gp, new_op1, new_op2,
601
	                nomem, get_fpcw());
Matthias Braun's avatar
Matthias Braun committed
602
603
604
605
606
607
608
609
610
	set_ia32_am_support(new_node, ia32_am_Source, ia32_am_binary);
	if (is_op_commutative(get_irn_op(node))) {
		set_ia32_commutative(new_node);
	}

	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));

	return new_node;
}
611
612
613
614
615
616
617
618
619

/**
 * Construct a shift/rotate binary operation, sets AM and immediate if required.
 *
 * @param op1   The first operand
 * @param op2   The second operand
 * @param func  The node constructor function
 * @return The constructed ia32 node.
 */
620
static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
621
622
                                construct_binop_func *func)
{
Michael Beck's avatar
Michael Beck committed
623
624
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
625
	ir_node  *new_op2;
626
627
	ir_node  *new_op  = NULL;
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
628
629
	ir_graph *irg     = current_ir_graph;
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
630
	ir_node  *nomem   = new_NoMem();
631

632
633
	assert(! mode_is_float(get_irn_mode(node))
	         && "Shift/Rotate with float not supported");
634

635
	new_op2 = create_immediate_or_transform(op2, 'N');
636

637
	new_op = func(dbgi, irg, block, noreg, noreg, new_op1, new_op2, nomem);
638
639

	/* set AM support */
Matthias Braun's avatar
Matthias Braun committed
640
	set_ia32_am_support(new_op, ia32_am_Dest, ia32_am_binary);
641

Michael Beck's avatar
Michael Beck committed
642
	SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
Christian Würdig's avatar
Christian Würdig committed
643

Christian Würdig's avatar
Christian Würdig committed
644
	set_ia32_emit_cl(new_op);
645

646
647
648
649
650
651
652
	/* lowered shift instruction may have a dependency operand, handle it here */
	if (get_irn_arity(node) == 3) {
		/* we have a dependency */
		ir_node *new_dep = be_transform_node(get_irn_n(node, 2));
		add_irn_dep(new_op, new_dep);
	}

653
	return new_op;
654
655
656
657
658
659
660
661
662
663
}


/**
 * Construct a standard unary operation, set AM and immediate if required.
 *
 * @param op    The operand
 * @param func  The node constructor function
 * @return The constructed ia32 node.
 */
664
static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func)
665
{
Michael Beck's avatar
Michael Beck committed
666
667
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *new_op   = be_transform_node(op);
668
	ir_node  *new_node = NULL;
Michael Beck's avatar
Michael Beck committed
669
	ir_graph *irg      = current_ir_graph;
670
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
671
	ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
672
	ir_node  *nomem    = new_NoMem();
673

674
675
	new_node = func(dbgi, irg, block, noreg, noreg, new_op, nomem);
	DB((dbg, LEVEL_1, "INT unop ..."));
Matthias Braun's avatar
Matthias Braun committed
676
	set_ia32_am_support(new_node, ia32_am_Dest, ia32_am_unary);
Christian Würdig's avatar
Christian Würdig committed
677

Michael Beck's avatar
Michael Beck committed
678
	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
679

680
	return new_node;
681
682
683
684
685
686
687
}

/**
 * Creates an ia32 Add.
 *
 * @return the created ia32 Add node
 */
688
static ir_node *gen_Add(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
689
	ir_node  *block   = be_transform_node(get_nodes_block(node));
690
	ir_node  *op1     = get_Add_left(node);
Michael Beck's avatar
Michael Beck committed
691
	ir_node  *new_op1 = be_transform_node(op1);
692
	ir_node  *op2     = get_Add_right(node);
Michael Beck's avatar
Michael Beck committed
693
	ir_node  *new_op2 = be_transform_node(op2);
694
	ir_node  *new_op  = NULL;
Michael Beck's avatar
Michael Beck committed
695
	ir_graph *irg     = current_ir_graph;
696
697
	dbg_info *dbgi    = get_irn_dbg_info(node);
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
698
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
699
700
	ir_node  *nomem   = new_NoMem();
	ir_node  *expr_op, *imm_op;
701

702
703
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
Michael Beck's avatar
Michael Beck committed
704
	imm_op  = (env_cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(new_op1, new_op2) : NULL;
705
	expr_op = get_expr_op(new_op1, new_op2);
706
707

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

	if (mode_is_float(mode)) {
Michael Beck's avatar
Michael Beck committed
710
		if (USE_SSE2(env_cg))
Matthias Braun's avatar
Matthias Braun committed
711
			return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xAdd);
712
		else
Matthias Braun's avatar
Matthias Braun committed
713
			return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd);
Christian Würdig's avatar
Christian Würdig committed
714
	}
Christian Würdig's avatar
Christian Würdig committed
715

716
	/* integer ADD */
717
	if (! expr_op) {
718
719
720
721
722
723
724
725
726
727
728
729
730
		ia32_immop_type_t tp1 = get_ia32_immop_type(new_op1);
		ia32_immop_type_t tp2 = get_ia32_immop_type(new_op2);

		/* 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                                 */
		/* 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 (tp1 == ia32_ImmSymConst && tp2 == ia32_ImmSymConst) {
			/* this is the 2nd case */
731
			new_op = new_rd_ia32_Lea(dbgi, irg, block, new_op1, noreg);
732
			set_ia32_am_sc(new_op, get_ia32_Immop_symconst(new_op2));
Matthias Braun's avatar
Matthias Braun committed
733
			set_ia32_am_flavour(new_op, ia32_am_B);
734
			set_ia32_op_type(new_op, ia32_AddrModeS);
735

736
737
738
739
			DBG_OPT_LEA3(new_op1, new_op2, node, new_op);
		} else if (tp1 == ia32_ImmSymConst) {
			tarval *tv = get_ia32_Immop_tarval(new_op2);
			long offs = get_tarval_long(tv);
Christian Würdig's avatar
Christian Würdig committed
740

741
			new_op = new_rd_ia32_Lea(dbgi, irg, block, noreg, noreg);
Matthias Braun's avatar
Matthias Braun committed
742
			add_irn_dep(new_op, get_irg_frame(irg));
743
			DBG_OPT_LEA3(new_op1, new_op2, node, new_op);
744

745
746
			set_ia32_am_sc(new_op, get_ia32_Immop_symconst(new_op1));
			add_ia32_am_offs_int(new_op, offs);
Matthias Braun's avatar
Matthias Braun committed
747
			set_ia32_am_flavour(new_op, ia32_am_OB);
748
749
750
751
752
			set_ia32_op_type(new_op, ia32_AddrModeS);
		} else if (tp2 == ia32_ImmSymConst) {
			tarval *tv = get_ia32_Immop_tarval(new_op1);
			long offs = get_tarval_long(tv);

753
			new_op = new_rd_ia32_Lea(dbgi, irg, block, noreg, noreg);
Matthias Braun's avatar
Matthias Braun committed
754
			add_irn_dep(new_op, get_irg_frame(irg));
755
			DBG_OPT_LEA3(new_op1, new_op2, node, new_op);
Christian Würdig's avatar
Christian Würdig committed
756

757
758
			add_ia32_am_offs_int(new_op, offs);
			set_ia32_am_sc(new_op, get_ia32_Immop_symconst(new_op2));
Matthias Braun's avatar
Matthias Braun committed
759
			set_ia32_am_flavour(new_op, ia32_am_OB);
760
761
762
763
764
765
766
767
			set_ia32_op_type(new_op, ia32_AddrModeS);
		} else {
			tarval *tv1 = get_ia32_Immop_tarval(new_op1);
			tarval *tv2 = get_ia32_Immop_tarval(new_op2);
			tarval *restv = tarval_add(tv1, tv2);

			DEBUG_ONLY(ir_fprintf(stderr, "Warning: add with 2 consts not folded: %+F\n", node));

768
			new_op = new_rd_ia32_Const(dbgi, irg, block);
769
770
			set_ia32_Const_tarval(new_op, restv);
			DBG_OPT_LEA3(new_op1, new_op2, node, new_op);
771
		}
Christian Würdig's avatar
Christian Würdig committed
772

Michael Beck's avatar
Michael Beck committed
773
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
774
775
		return new_op;
	} else if (imm_op) {
Michael Beck's avatar
Michael Beck committed
776
		if ((env_cg->opt & IA32_OPT_INCDEC) && get_ia32_immop_type(imm_op) == ia32_ImmConst) {
777
778
779
780
781
782
783
784
			tarval_classification_t class_tv, class_negtv;
			tarval *tv = get_ia32_Immop_tarval(imm_op);

			/* optimize tarvals */
			class_tv    = classify_tarval(tv);
			class_negtv = classify_tarval(tarval_neg(tv));

			if (class_tv == TV_CLASSIFY_ONE) { /* + 1 == INC */
785
786
				DB((dbg, LEVEL_2, "Add(1) to Inc ... "));
				new_op     = new_rd_ia32_Inc(dbgi, irg, block, noreg, noreg, expr_op, nomem);
Michael Beck's avatar
Michael Beck committed
787
				SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
788
789
				return new_op;
			} else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
790
791
				DB((dbg, LEVEL_2, "Add(-1) to Dec ... "));
				new_op     = new_rd_ia32_Dec(dbgi, irg, block, noreg, noreg, expr_op, nomem);
Michael Beck's avatar
Michael Beck committed
792
				SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
793
794
				return new_op;
			}
795
		}
Christian Würdig's avatar
Christian Würdig committed
796
797
	}

798
	/* This is a normal add */
799
	new_op = new_rd_ia32_Add(dbgi, irg, block, noreg, noreg, new_op1, new_op2, nomem);
800
801

	/* set AM support */
Matthias Braun's avatar
Matthias Braun committed
802
	set_ia32_am_support(new_op, ia32_am_Full, ia32_am_binary);
803
804
	set_ia32_commutative(new_op);

805
	fold_immediate(new_op, 2, 3);
806

Michael Beck's avatar
Michael Beck committed
807
	SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
808

809
	return new_op;
Christian Würdig's avatar
Christian Würdig committed
810
811
}

812
813
814
815
816
/**
 * Creates an ia32 Mul.
 *
 * @return the created ia32 Mul node
 */
817
static ir_node *gen_Mul(ir_node *node) {
818
819
	ir_node *op1  = get_Mul_left(node);
	ir_node *op2  = get_Mul_right(node);
820
	ir_mode *mode = get_irn_mode(node);
821

822
	if (mode_is_float(mode)) {
Michael Beck's avatar
Michael Beck committed
823
		if (USE_SSE2(env_cg))
Matthias Braun's avatar
Matthias Braun committed
824
			return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xMul);
825
		else
Matthias Braun's avatar
Matthias Braun committed
826
			return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul);
Christian Würdig's avatar
Christian Würdig committed
827
	}
828

829
830
831
832
833
	/*
		for the lower 32bit of the result it doesn't matter whether we use
		signed or unsigned multiplication so we use IMul as it has fewer
		constraints
	*/
834
	return gen_binop(node, op1, op2, new_rd_ia32_IMul, 1);
835
}
836
837
838
839
840
841
842
843

/**
 * 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.
 *
 * @return the created ia32 Mulh node
 */
844
static ir_node *gen_Mulh(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
845
	ir_node  *block   = be_transform_node(get_nodes_block(node));
846
	ir_node  *op1     = get_irn_n(node, 0);
Michael Beck's avatar
Michael Beck committed
847
	ir_node  *new_op1 = be_transform_node(op1);
848
	ir_node  *op2     = get_irn_n(node, 1);
Michael Beck's avatar
Michael Beck committed
849
850
	ir_node  *new_op2 = be_transform_node(op2);
	ir_graph *irg     = current_ir_graph;
851
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
852
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
853
	ir_mode  *mode    = get_irn_mode(node);
Matthias Braun's avatar
Matthias Braun committed
854
	ir_node  *proj_EDX, *res;
855

856
	assert(!mode_is_float(mode) && "Mulh with float not supported");
857
	if (mode_is_signed(mode)) {
Matthias Braun's avatar
Matthias Braun committed
858
859
		res = new_rd_ia32_IMul1OP(dbgi, irg, block, noreg, noreg, new_op1,
		                          new_op2, new_NoMem());
Matthias Braun's avatar
Matthias Braun committed
860
	} else {
Matthias Braun's avatar
Matthias Braun committed
861
862
		res = new_rd_ia32_Mul(dbgi, irg, block, noreg, noreg, new_op1, new_op2,
		                      new_NoMem());
Matthias Braun's avatar
Matthias Braun committed
863
	}
864

Matthias Braun's avatar
Matthias Braun committed
865
	set_ia32_commutative(res);
Matthias Braun's avatar
Matthias Braun committed
866
	set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);
Matthias Braun's avatar
Matthias Braun committed
867

868
	proj_EDX = new_rd_Proj(dbgi, irg, block, res, mode_Iu, pn_EDX);
869
870

	return proj_EDX;
871
872
}

873
874


875
876
877
/**
 * Creates an ia32 And.
 *
878
 * @return The created ia32 And node
879
 */
880
static ir_node *gen_And(ir_node *node) {
881
882
	ir_node *op1 = get_And_left(node);
	ir_node *op2 = get_And_right(node);
883
884
	assert(! mode_is_float(get_irn_mode(node)));

Michael Beck's avatar
Michael Beck committed
885
886
	/* check for zero extension first */
	if (is_Const(op2)) {
887
888
889
890
891
892
893
894
895
896
897
898
		tarval   *tv    = get_Const_tarval(op2);
		long      v     = get_tarval_long(tv);

		if (v == 0xFF || v == 0xFFFF) {
			dbg_info *dbgi   = get_irn_dbg_info(node);
			ir_node  *block  = be_transform_node(get_nodes_block(node));
			ir_node  *new_op = be_transform_node(op1);
			ir_mode  *src_mode;
			ir_node  *res;

			if(v == 0xFF) {
				src_mode = mode_Bu;
Michael Beck's avatar
Michael Beck committed
899
			} else {
900
901
				assert(v == 0xFFFF);
				src_mode = mode_Hu;
Michael Beck's avatar
Michael Beck committed
902
			}
903
904
			res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, new_op);
			SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
Michael Beck's avatar
Michael Beck committed
905

906
			return res;
907
908
		}
	}
909

910
	return gen_binop(node, op1, op2, new_rd_ia32_And, 1);
911
912
913
914
915
916
917
}



/**
 * Creates an ia32 Or.
 *
918
 * @return The created ia32 Or node
919
 */
920
static ir_node *gen_Or(ir_node *node) {
921
922
	ir_node *op1 = get_Or_left(node);
	ir_node *op2 = get_Or_right(node);
923

924
	assert (! mode_is_float(get_irn_mode(node)));
925
	return gen_binop(node, op1, op2, new_rd_ia32_Or, 1);
926
927
928
929
930
931
932
}



/**
 * Creates an ia32 Eor.
 *
933
 * @return The created ia32 Eor node
934
 */
935
static ir_node *gen_Eor(ir_node *node) {
936
937
	ir_node *op1 = get_Eor_left(node);
	ir_node *op2 = get_Eor_right(node);
938

939
	assert(! mode_is_float(get_irn_mode(node)));
940
	return gen_binop(node, op1, op2, new_rd_ia32_Xor, 1);
941
942
943
944
945
946
}


/**
 * Creates an ia32 Sub.
 *