ia32_transform.c 123 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
22
23
24
 * @file
 * @brief       This file implements the IR transformation from firm into ia32-Firm.
 * @author      Christian Wuerdig, Matthias Braun
 * @version     $Id$
Christian Würdig's avatar
Christian Würdig committed
25
 */
26
#ifdef HAVE_CONFIG_H
27
#include "config.h"
28
29
#endif

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

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

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

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

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

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

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

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

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

92
93
extern ir_op *get_op_Mulh(void);

94
95
96
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
97

Matthias Braun's avatar
Matthias Braun committed
98
99
100
101
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);

102
103
104
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);
105

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

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

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

122
123
124
125
/**
 * Return true if a mode can be stored in the GP register set
 */
static INLINE int mode_needs_gp_reg(ir_mode *mode) {
126
127
	if(mode == mode_fpcw)
		return 0;
128
	return mode_is_int(mode) || mode_is_reference(mode) || mode == mode_b;
129
130
}

Christian Würdig's avatar
Christian Würdig committed
131
132
133
134
/**
 * Returns 1 if irn is a Const representing 0, 0 otherwise
 */
static INLINE int is_ia32_Const_0(ir_node *irn) {
135
136
	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
137
138
139
140
141
142
}

/**
 * Returns 1 if irn is a Const representing 1, 0 otherwise
 */
static INLINE int is_ia32_Const_1(ir_node *irn) {
143
144
	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
145
146
}

147
/**
Christian Würdig's avatar
Christian Würdig committed
148
149
 * Collects all Projs of a node into the node array. Index is the projnum.
 * BEWARE: The caller has to assure the appropriate array size!
150
 */
Christian Würdig's avatar
Christian Würdig committed
151
152
153
154
155
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]));
156

Christian Würdig's avatar
Christian Würdig committed
157
	foreach_out_edge(irn, edge) {
158
159
160
161
		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
162
163
164
165
166
167
168
169
	}
}

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

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/**
 * 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);
204
		set_type_alignment_bytes(res, 16);
205
206
207
208
209
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
		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);
243
	} else {
244
		res = e->value;
245
246
	}

247
248
249
	return res;
}

250
251
252
253
254
255
256
257
258
259
260
261
262
263
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;
}

264
265
266
/**
 * Transforms a Const.
 */
267
static ir_node *gen_Const(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
268
	ir_graph        *irg   = current_ir_graph;
269
270
	ir_node         *old_block = get_nodes_block(node);
	ir_node         *block = be_transform_node(old_block);
271
272
	dbg_info        *dbgi  = get_irn_dbg_info(node);
	ir_mode         *mode  = get_irn_mode(node);
273
274

	if (mode_is_float(mode)) {
275
		ir_node   *res   = NULL;
Michael Beck's avatar
Michael Beck committed
276
		ir_node   *noreg = ia32_new_NoReg_gp(env_cg);
277
278
		ir_node   *nomem = new_NoMem();
		ir_node   *load;
279
280
		ir_entity *floatent;

Michael Beck's avatar
Michael Beck committed
281
		if (! USE_SSE2(env_cg)) {
282
283
284
			cnst_classify_t clss = classify_Const(node);

			if (clss == CNST_NULL) {
285
				load = new_rd_ia32_vfldz(dbgi, irg, block);
286
				res  = load;
287
			} else if (clss == CNST_ONE) {
288
				load = new_rd_ia32_vfld1(dbgi, irg, block);
289
				res  = load;
290
			} else {
Michael Beck's avatar
Michael Beck committed
291
				floatent = get_entity_for_tv(env_cg, node);
292

Matthias Braun's avatar
Matthias Braun committed
293
				load     = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
294
295
				set_ia32_op_type(load, ia32_AddrModeS);
				set_ia32_am_flavour(load, ia32_am_N);
296
				set_ia32_am_sc(load, floatent);
297
298
				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);
299
			}
300
			set_ia32_ls_mode(load, mode);
301
		} else {
Michael Beck's avatar
Michael Beck committed
302
			floatent = get_entity_for_tv(env_cg, node);
303

304
			load     = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem);
305
306
			set_ia32_op_type(load, ia32_AddrModeS);
			set_ia32_am_flavour(load, ia32_am_N);
307
			set_ia32_am_sc(load, floatent);
308
			set_ia32_ls_mode(load, mode);
309
			set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
310
311

			res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
312
313
		}

Michael Beck's avatar
Michael Beck committed
314
		SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
315
316

		/* Const Nodes before the initial IncSP are a bad idea, because
317
318
319
		 * 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.
320
321
322
323
324
		 */
		if (get_irg_start_block(irg) == block) {
			add_irn_dep(load, get_irg_frame(irg));
		}

Michael Beck's avatar
Michael Beck committed
325
		SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
326
327
		return res;
	} else {
328
		ir_node *cnst = new_rd_ia32_Const(dbgi, irg, block);
329
330
331
332
333
334
335

		/* 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
336
		SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
337
338
339
340
341
342
343
344
345
346
		return cnst;
	}

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

/**
 * Transforms a SymConst.
 */
347
static ir_node *gen_SymConst(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
348
	ir_graph *irg   = current_ir_graph;
349
350
	ir_node  *old_block = get_nodes_block(node);
	ir_node  *block = be_transform_node(old_block);
351
352
	dbg_info *dbgi  = get_irn_dbg_info(node);
	ir_mode  *mode  = get_irn_mode(node);
353
354
355
	ir_node  *cnst;

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

	/* 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
374
	SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
375
376
377
378

	return cnst;
}

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

	const char    *tp_name, *ent_name, *cnst_str;
394
395
396
	ir_type       *tp;
	ir_node       *cnst;
	ir_graph      *rem;
397
	ir_entity     *ent;
398
	tarval        *tv;
Michael Beck's avatar
BugFix:    
Michael Beck committed
399
	ir_mode       *mode;
400

Christian Würdig's avatar
Christian Würdig committed
401
	ent_name = names[kct].ent_name;
402
403
404
	if (! ent_cache[kct]) {
		tp_name  = names[kct].tp_name;
		cnst_str = names[kct].cnst_str;
405

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

		set_atomic_ent_value(ent, cnst);

426
427
		/* cache the entry */
		ent_cache[kct] = ent;
428
	}
429

430
	return ent_cache[kct];
431
432
}

Christian Würdig's avatar
Christian Würdig committed
433
434
435
436
#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
437
438
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;
439

Christian Würdig's avatar
Christian Würdig committed
440
	lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
Christian Würdig's avatar
Christian Würdig committed
441
442
443
444
	obstack_1grow(isa->name_obst, 0);
 	return obstack_finish(isa->name_obst);
}
#endif /* NDEBUG */
Christian Würdig's avatar
Christian Würdig committed
445

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

/* 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
457
	return !is_ia32_Cnst(op1) ? op1 : (!is_ia32_Cnst(op2) ? op2 : NULL);
458
459
}

460
static void fold_immediate(ir_node *node, int in1, int in2) {
461
462
463
	ir_node *left;
	ir_node *right;

Michael Beck's avatar
Michael Beck committed
464
	if (!(env_cg->opt & IA32_OPT_IMMOPS))
465
466
467
468
		return;

	left = get_irn_n(node, in1);
	right = get_irn_n(node, in2);
469
	if (! is_ia32_Cnst(right) && is_ia32_Cnst(left)) {
470
471
472
473
474
		/* 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
475
		set_irn_n(node, in2, ia32_get_admissible_noreg(env_cg, node, in2));
476
		copy_ia32_Immop_attr(node, left);
477
	} else if(is_ia32_Cnst(right)) {
Michael Beck's avatar
Michael Beck committed
478
		set_irn_n(node, in2, ia32_get_admissible_noreg(env_cg, node, in2));
479
		copy_ia32_Immop_attr(node, right);
480
481
482
483
	} else {
		return;
	}

484
	clear_ia32_commutative(node);
Matthias Braun's avatar
Matthias Braun committed
485
486
	set_ia32_am_support(node, get_ia32_am_support(node) & ~ia32_am_Source,
	                    get_ia32_am_arity(node));
487
}
488
489
490
491
492
493
494
495
496

/**
 * 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.
 */
497
static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
498
                          construct_binop_func *func, int commutative)
499
{
Michael Beck's avatar
Michael Beck committed
500
501
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_graph *irg      = current_ir_graph;
502
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
503
	ir_node  *noreg_gp = ia32_new_NoReg_gp(env_cg);
504
	ir_node  *nomem    = new_NoMem();
505
	ir_node  *new_node;
506

507
	ir_node *new_op1 = be_transform_node(op1);
508
509
	ir_node *new_op2 = create_immediate_or_transform(op2, 0);
	if (is_ia32_Immediate(new_op2)) {
510
		commutative = 0;
511
512
	}

513
	new_node = func(dbgi, irg, block, noreg_gp, noreg_gp, new_op1, new_op2, nomem);
514
	if (func == new_rd_ia32_IMul) {
Matthias Braun's avatar
Matthias Braun committed
515
		set_ia32_am_support(new_node, ia32_am_Source, ia32_am_binary);
516
	} else {
Matthias Braun's avatar
Matthias Braun committed
517
		set_ia32_am_support(new_node, ia32_am_Full, ia32_am_binary);
518
519
	}

Michael Beck's avatar
Michael Beck committed
520
	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
521
	if (commutative) {
522
		set_ia32_commutative(new_node);
523
	}
Christian Würdig's avatar
Christian Würdig committed
524

525
	return new_node;
526
527
}

528
529
530
531
532
533
534
535
/**
 * 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
536
537
static ir_node *gen_binop_sse_float(ir_node *node, ir_node *op1, ir_node *op2,
                                    construct_binop_func *func)
538
{
Michael Beck's avatar
Michael Beck committed
539
540
541
	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);
542
	ir_node  *new_node = NULL;
543
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
544
	ir_graph *irg      = current_ir_graph;
545
	ir_mode  *mode     = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
546
	ir_node  *noreg_gp = ia32_new_NoReg_gp(env_cg);
547
548
	ir_node  *nomem    = new_NoMem();

Matthias Braun's avatar
Matthias Braun committed
549
550
551
	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);
552
553
554
	if (is_op_commutative(get_irn_op(node))) {
		set_ia32_commutative(new_node);
	}
555
	set_ia32_ls_mode(new_node, mode);
556

Michael Beck's avatar
Michael Beck committed
557
	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
558
559
560

	return new_node;
}
561

562
563
564
565
566
567
568
569
570
571
572
573
574
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
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
/**
 * 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,
596
	                nomem, get_fpcw());
Matthias Braun's avatar
Matthias Braun committed
597
598
599
600
601
602
603
604
605
	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;
}
606
607
608
609
610
611
612
613
614

/**
 * 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.
 */
615
static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
616
617
                                construct_binop_func *func)
{
Michael Beck's avatar
Michael Beck committed
618
619
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
620
	ir_node  *new_op2;
621
622
	ir_node  *new_op  = NULL;
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
623
624
	ir_graph *irg     = current_ir_graph;
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
625
	ir_node  *nomem   = new_NoMem();
626

627
628
	assert(! mode_is_float(get_irn_mode(node))
	         && "Shift/Rotate with float not supported");
629

630
	new_op2 = create_immediate_or_transform(op2, 'N');
631

632
	new_op = func(dbgi, irg, block, noreg, noreg, new_op1, new_op2, nomem);
633
634

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

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

Christian Würdig's avatar
Christian Würdig committed
639
	set_ia32_emit_cl(new_op);
640

641
	return new_op;
642
643
644
645
646
647
648
649
650
651
}


/**
 * 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.
 */
652
static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func)
653
{
Michael Beck's avatar
Michael Beck committed
654
655
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *new_op   = be_transform_node(op);
656
	ir_node  *new_node = NULL;
Michael Beck's avatar
Michael Beck committed
657
	ir_graph *irg      = current_ir_graph;
658
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
659
	ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
660
	ir_node  *nomem    = new_NoMem();
661

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

Michael Beck's avatar
Michael Beck committed
666
	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
667

668
	return new_node;
669
670
671
672
673
674
675
}

/**
 * Creates an ia32 Add.
 *
 * @return the created ia32 Add node
 */
676
static ir_node *gen_Add(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
677
	ir_node  *block   = be_transform_node(get_nodes_block(node));
678
	ir_node  *op1     = get_Add_left(node);
Michael Beck's avatar
Michael Beck committed
679
	ir_node  *new_op1 = be_transform_node(op1);
680
	ir_node  *op2     = get_Add_right(node);
Michael Beck's avatar
Michael Beck committed
681
	ir_node  *new_op2 = be_transform_node(op2);
682
	ir_node  *new_op  = NULL;
Michael Beck's avatar
Michael Beck committed
683
	ir_graph *irg     = current_ir_graph;
684
685
	dbg_info *dbgi    = get_irn_dbg_info(node);
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
686
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
687
688
	ir_node  *nomem   = new_NoMem();
	ir_node  *expr_op, *imm_op;
689

690
691
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
Michael Beck's avatar
Michael Beck committed
692
	imm_op  = (env_cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(new_op1, new_op2) : NULL;
693
	expr_op = get_expr_op(new_op1, new_op2);
694
695

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

	if (mode_is_float(mode)) {
Michael Beck's avatar
Michael Beck committed
698
		if (USE_SSE2(env_cg))
Matthias Braun's avatar
Matthias Braun committed
699
			return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xAdd);
700
		else
Matthias Braun's avatar
Matthias Braun committed
701
			return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd);
Christian Würdig's avatar
Christian Würdig committed
702
	}
Christian Würdig's avatar
Christian Würdig committed
703

704
	/* integer ADD */
705
	if (! expr_op) {
706
707
708
709
710
711
712
713
714
715
716
717
718
		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 */
719
			new_op = new_rd_ia32_Lea(dbgi, irg, block, new_op1, noreg);
720
			set_ia32_am_sc(new_op, get_ia32_Immop_symconst(new_op2));
Matthias Braun's avatar
Matthias Braun committed
721
			set_ia32_am_flavour(new_op, ia32_am_B);
722
			set_ia32_op_type(new_op, ia32_AddrModeS);
723

724
725
726
727
			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
728

729
			new_op = new_rd_ia32_Lea(dbgi, irg, block, noreg, noreg);
Matthias Braun's avatar
Matthias Braun committed
730
			add_irn_dep(new_op, get_irg_frame(irg));
731
			DBG_OPT_LEA3(new_op1, new_op2, node, new_op);
732

733
734
			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
735
			set_ia32_am_flavour(new_op, ia32_am_OB);
736
737
738
739
740
			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);

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);
Christian Würdig's avatar
Christian Würdig committed
744

745
746
			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
747
			set_ia32_am_flavour(new_op, ia32_am_OB);
748
749
750
751
752
753
754
755
			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));

756
			new_op = new_rd_ia32_Const(dbgi, irg, block);
757
758
			set_ia32_Const_tarval(new_op, restv);
			DBG_OPT_LEA3(new_op1, new_op2, node, new_op);
759
		}
Christian Würdig's avatar
Christian Würdig committed
760

Michael Beck's avatar
Michael Beck committed
761
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
762
763
		return new_op;
	} else if (imm_op) {
Michael Beck's avatar
Michael Beck committed
764
		if ((env_cg->opt & IA32_OPT_INCDEC) && get_ia32_immop_type(imm_op) == ia32_ImmConst) {
765
766
767
768
769
770
771
772
			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 */
773
774
				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
775
				SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
776
777
				return new_op;
			} else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
778
779
				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
780
				SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
781
782
				return new_op;
			}
783
		}
Christian Würdig's avatar
Christian Würdig committed
784
785
	}

786
	/* This is a normal add */
787
	new_op = new_rd_ia32_Add(dbgi, irg, block, noreg, noreg, new_op1, new_op2, nomem);
788
789

	/* set AM support */
Matthias Braun's avatar
Matthias Braun committed
790
	set_ia32_am_support(new_op, ia32_am_Full, ia32_am_binary);
791
792
	set_ia32_commutative(new_op);

793
	fold_immediate(new_op, 2, 3);
794

Michael Beck's avatar
Michael Beck committed
795
	SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
796

797
	return new_op;
Christian Würdig's avatar
Christian Würdig committed
798
799
}

800
801
802
803
804
/**
 * Creates an ia32 Mul.
 *
 * @return the created ia32 Mul node
 */
805
static ir_node *gen_Mul(ir_node *node) {
806
807
	ir_node *op1  = get_Mul_left(node);
	ir_node *op2  = get_Mul_right(node);
808
	ir_mode *mode = get_irn_mode(node);
809

810
	if (mode_is_float(mode)) {
Michael Beck's avatar
Michael Beck committed
811
		if (USE_SSE2(env_cg))
Matthias Braun's avatar
Matthias Braun committed
812
			return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xMul);
813
		else
Matthias Braun's avatar
Matthias Braun committed
814
			return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul);
Christian Würdig's avatar
Christian Würdig committed
815
	}
816

817
818
819
820
821
	/*
		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
	*/
822
	return gen_binop(node, op1, op2, new_rd_ia32_IMul, 1);
823
}
824
825
826
827
828
829
830
831

/**
 * 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
 */
832
static ir_node *gen_Mulh(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
833
	ir_node  *block   = be_transform_node(get_nodes_block(node));
834
	ir_node  *op1     = get_irn_n(node, 0);
Michael Beck's avatar
Michael Beck committed
835
	ir_node  *new_op1 = be_transform_node(op1);
836
	ir_node  *op2     = get_irn_n(node, 1);
Michael Beck's avatar
Michael Beck committed
837
838
	ir_node  *new_op2 = be_transform_node(op2);
	ir_graph *irg     = current_ir_graph;
839
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
840
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
841
	ir_mode  *mode    = get_irn_mode(node);
Matthias Braun's avatar
Matthias Braun committed
842
	ir_node  *proj_EDX, *res;
843

844
	assert(!mode_is_float(mode) && "Mulh with float not supported");
845
	if (mode_is_signed(mode)) {
Matthias Braun's avatar
Matthias Braun committed
846
847
		res = new_rd_ia32_IMul1OP(dbgi, irg, block, noreg, noreg, new_op1,
		                          new_op2, new_NoMem());
Matthias Braun's avatar
Matthias Braun committed
848
	} else {
Matthias Braun's avatar
Matthias Braun committed
849
850
		res = new_rd_ia32_Mul(dbgi, irg, block, noreg, noreg, new_op1, new_op2,
		                      new_NoMem());
Matthias Braun's avatar
Matthias Braun committed
851
	}
852

Matthias Braun's avatar
Matthias Braun committed
853
	set_ia32_commutative(res);
Matthias Braun's avatar
Matthias Braun committed
854
	set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);
Matthias Braun's avatar
Matthias Braun committed
855

856
	proj_EDX = new_rd_Proj(dbgi, irg, block, res, mode_Iu, pn_EDX);
857
858

	return proj_EDX;
859
860
}

861
862


863
864
865
/**
 * Creates an ia32 And.
 *
866
 * @return The created ia32 And node
867
 */
868
static ir_node *gen_And(ir_node *node) {
869
870
	ir_node *op1 = get_And_left(node);
	ir_node *op2 = get_And_right(node);
871

872
	assert (! mode_is_float(get_irn_mode(node)));
873
	return gen_binop(node, op1, op2, new_rd_ia32_And, 1);
874
875
876
877
878
879
880
}



/**
 * Creates an ia32 Or.
 *
881
 * @return The created ia32 Or node
882
 */
883
static ir_node *gen_Or(ir_node *node) {
884
885
	ir_node *op1 = get_Or_left(node);
	ir_node *op2 = get_Or_right(node);
886

887
	assert (! mode_is_float(get_irn_mode(node)));
888
	return gen_binop(node, op1, op2, new_rd_ia32_Or, 1);
889
890
891
892
893
894
895
}



/**
 * Creates an ia32 Eor.
 *
896
 * @return The created ia32 Eor node
897
 */
898
static ir_node *gen_Eor(ir_node *node) {
899
900
	ir_node *op1 = get_Eor_left(node);
	ir_node *op2 = get_Eor_right(node);
901

902
	assert(! mode_is_float(get_irn_mode(node)));
903
	return gen_binop(node, op1, op2, new_rd_ia32_Xor, 1);
904
905
906
907
908
909
}


/**
 * Creates an ia32 Sub.
 *
910
 * @return The created ia32 Sub node
911
 */
912
static ir_node *gen_Sub(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
913
	ir_node  *block   = be_transform_node(get_nodes_block(node));
914
	ir_node  *op1     = get_Sub_left(node);
Michael Beck's avatar
Michael Beck committed
915
	ir_node  *new_op1 = be_transform_node(op1);
916
	ir_node  *op2     = get_Sub_right(node);
Michael Beck's avatar
Michael Beck committed
917
	ir_node  *new_op2 = be_transform_node(op2);
918
	ir_node  *new_op  = NULL;
Michael Beck's avatar
Michael Beck committed
919
	ir_graph *irg     = current_ir_graph;
920
	dbg_info *dbgi    = get_irn_dbg_info(node);
921
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
922
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
923
	ir_node  *nomem   = new_NoMem();
924
925
	ir_node  *expr_op, *imm_op;