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
89
/** hold the current code generator during transformation */
static ia32_code_gen_t *env_cg = NULL;
90

91
92
extern ir_op *get_op_Mulh(void);

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

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

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

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

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

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

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

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

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

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

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

/**
 * 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) {
169
	fprintf(stderr, "Warning: renumber_Proj used!\n");
Christian Würdig's avatar
Christian Würdig committed
170
171
172
173
	if (projs[pn_old]) {
		set_Proj_proj(projs[pn_old], pn_new);
		projs[pn_old] = NULL;
	}
174
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
/**
 * 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);
203
		set_type_alignment_bytes(res, 16);
204
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
		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);
242
	} else {
243
		res = e->value;
244
245
	}

246
247
248
	return res;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return cnst;
}

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

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

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

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

		set_atomic_ent_value(ent, cnst);

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

429
	return ent_cache[kct];
430
431
}

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

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

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

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

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

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

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

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

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

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

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

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

524
	return new_node;
525
526
}

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

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

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

	return new_node;
}
560

Matthias Braun's avatar
Matthias Braun committed
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
/**
 * 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();
	ir_node  *fpcw     = be_abi_get_ignore_irn(env_cg->birg->abi,
	                                           &ia32_fp_cw_regs[REG_FPCW]);

	new_node = func(dbgi, irg, block, noreg_gp, noreg_gp, new_op1, new_op2,
	                nomem, fpcw);
	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;
}
594
595
596
597
598
599
600
601
602

/**
 * 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.
 */
603
static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
604
605
                                construct_binop_func *func)
{
Michael Beck's avatar
Michael Beck committed
606
607
	ir_node  *block   = be_transform_node(get_nodes_block(node));
	ir_node  *new_op1 = be_transform_node(op1);
608
	ir_node  *new_op2;
609
610
	ir_node  *new_op  = NULL;
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
611
612
	ir_graph *irg     = current_ir_graph;
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
613
	ir_node  *nomem   = new_NoMem();
614

615
616
	assert(! mode_is_float(get_irn_mode(node))
	         && "Shift/Rotate with float not supported");
617

618
	new_op2 = create_immediate_or_transform(op2, 'N');
619

620
	new_op = func(dbgi, irg, block, noreg, noreg, new_op1, new_op2, nomem);
621
622

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

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

Christian Würdig's avatar
Christian Würdig committed
627
	set_ia32_emit_cl(new_op);
628

629
	return new_op;
630
631
632
633
634
635
636
637
638
639
}


/**
 * 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.
 */
640
static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func)
641
{
Michael Beck's avatar
Michael Beck committed
642
643
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *new_op   = be_transform_node(op);
644
	ir_node  *new_node = NULL;
Michael Beck's avatar
Michael Beck committed
645
	ir_graph *irg      = current_ir_graph;
646
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
647
	ir_node  *noreg    = ia32_new_NoReg_gp(env_cg);
648
	ir_node  *nomem    = new_NoMem();
649

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

Michael Beck's avatar
Michael Beck committed
654
	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
655

656
	return new_node;
657
658
659
660
661
662
663
}

/**
 * Creates an ia32 Add.
 *
 * @return the created ia32 Add node
 */
664
static ir_node *gen_Add(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
665
	ir_node  *block   = be_transform_node(get_nodes_block(node));
666
	ir_node  *op1     = get_Add_left(node);
Michael Beck's avatar
Michael Beck committed
667
	ir_node  *new_op1 = be_transform_node(op1);
668
	ir_node  *op2     = get_Add_right(node);
Michael Beck's avatar
Michael Beck committed
669
	ir_node  *new_op2 = be_transform_node(op2);
670
	ir_node  *new_op  = NULL;
Michael Beck's avatar
Michael Beck committed
671
	ir_graph *irg     = current_ir_graph;
672
673
	dbg_info *dbgi    = get_irn_dbg_info(node);
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
674
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
675
676
	ir_node  *nomem   = new_NoMem();
	ir_node  *expr_op, *imm_op;
677

678
679
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
Michael Beck's avatar
Michael Beck committed
680
	imm_op  = (env_cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(new_op1, new_op2) : NULL;
681
	expr_op = get_expr_op(new_op1, new_op2);
682
683

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

	if (mode_is_float(mode)) {
Michael Beck's avatar
Michael Beck committed
686
		if (USE_SSE2(env_cg))
Matthias Braun's avatar
Matthias Braun committed
687
			return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xAdd);
688
		else
Matthias Braun's avatar
Matthias Braun committed
689
			return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd);
Christian Würdig's avatar
Christian Würdig committed
690
	}
Christian Würdig's avatar
Christian Würdig committed
691

692
	/* integer ADD */
693
	if (! expr_op) {
694
695
696
697
698
699
700
701
702
703
704
705
706
		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 */
707
			new_op = new_rd_ia32_Lea(dbgi, irg, block, new_op1, noreg);
708
			set_ia32_am_sc(new_op, get_ia32_Immop_symconst(new_op2));
Matthias Braun's avatar
Matthias Braun committed
709
			set_ia32_am_flavour(new_op, ia32_am_B);
710
			set_ia32_op_type(new_op, ia32_AddrModeS);
711

712
713
714
715
			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
716

717
			new_op = new_rd_ia32_Lea(dbgi, irg, block, noreg, noreg);
Matthias Braun's avatar
Matthias Braun committed
718
			add_irn_dep(new_op, get_irg_frame(irg));
719
			DBG_OPT_LEA3(new_op1, new_op2, node, new_op);
720

721
722
			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
723
			set_ia32_am_flavour(new_op, ia32_am_OB);
724
725
726
727
728
			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);

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

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

744
			new_op = new_rd_ia32_Const(dbgi, irg, block);
745
746
			set_ia32_Const_tarval(new_op, restv);
			DBG_OPT_LEA3(new_op1, new_op2, node, new_op);
747
		}
Christian Würdig's avatar
Christian Würdig committed
748

Michael Beck's avatar
Michael Beck committed
749
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
750
751
		return new_op;
	} else if (imm_op) {
Michael Beck's avatar
Michael Beck committed
752
		if ((env_cg->opt & IA32_OPT_INCDEC) && get_ia32_immop_type(imm_op) == ia32_ImmConst) {
753
754
755
756
757
758
759
760
			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 */
761
762
				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
763
				SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
764
765
				return new_op;
			} else if (class_tv == TV_CLASSIFY_ALL_ONE || class_negtv == TV_CLASSIFY_ONE) { /* + (-1) == DEC */
766
767
				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
768
				SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
769
770
				return new_op;
			}
771
		}
Christian Würdig's avatar
Christian Würdig committed
772
773
	}

774
	/* This is a normal add */
775
	new_op = new_rd_ia32_Add(dbgi, irg, block, noreg, noreg, new_op1, new_op2, nomem);
776
777

	/* set AM support */
Matthias Braun's avatar
Matthias Braun committed
778
	set_ia32_am_support(new_op, ia32_am_Full, ia32_am_binary);
779
780
	set_ia32_commutative(new_op);

781
	fold_immediate(new_op, 2, 3);
782

Michael Beck's avatar
Michael Beck committed
783
	SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
784

785
	return new_op;
Christian Würdig's avatar
Christian Würdig committed
786
787
}

788
789
790
791
792
/**
 * Creates an ia32 Mul.
 *
 * @return the created ia32 Mul node
 */
793
static ir_node *gen_Mul(ir_node *node) {
794
795
	ir_node *op1  = get_Mul_left(node);
	ir_node *op2  = get_Mul_right(node);
796
	ir_mode *mode = get_irn_mode(node);
797

798
	if (mode_is_float(mode)) {
Michael Beck's avatar
Michael Beck committed
799
		if (USE_SSE2(env_cg))
Matthias Braun's avatar
Matthias Braun committed
800
			return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xMul);
801
		else
Matthias Braun's avatar
Matthias Braun committed
802
			return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul);
Christian Würdig's avatar
Christian Würdig committed
803
	}
804

805
806
807
808
809
	/*
		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
	*/
810
	return gen_binop(node, op1, op2, new_rd_ia32_IMul, 1);
811
}
812
813
814
815
816
817
818
819

/**
 * 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
 */
820
static ir_node *gen_Mulh(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
821
	ir_node  *block   = be_transform_node(get_nodes_block(node));
822
	ir_node  *op1     = get_irn_n(node, 0);
Michael Beck's avatar
Michael Beck committed
823
	ir_node  *new_op1 = be_transform_node(op1);
824
	ir_node  *op2     = get_irn_n(node, 1);
Michael Beck's avatar
Michael Beck committed
825
826
	ir_node  *new_op2 = be_transform_node(op2);
	ir_graph *irg     = current_ir_graph;
827
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
828
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
829
	ir_mode  *mode    = get_irn_mode(node);
Matthias Braun's avatar
Matthias Braun committed
830
	ir_node  *proj_EDX, *res;
831

832
	assert(!mode_is_float(mode) && "Mulh with float not supported");
833
	if (mode_is_signed(mode)) {
Matthias Braun's avatar
Matthias Braun committed
834
835
		res = new_rd_ia32_IMul1OP(dbgi, irg, block, noreg, noreg, new_op1,
		                          new_op2, new_NoMem());
Matthias Braun's avatar
Matthias Braun committed
836
	} else {
Matthias Braun's avatar
Matthias Braun committed
837
838
		res = new_rd_ia32_Mul(dbgi, irg, block, noreg, noreg, new_op1, new_op2,
		                      new_NoMem());
Matthias Braun's avatar
Matthias Braun committed
839
	}
840

Matthias Braun's avatar
Matthias Braun committed
841
	set_ia32_commutative(res);
Matthias Braun's avatar
Matthias Braun committed
842
	set_ia32_am_support(res, ia32_am_Source, ia32_am_binary);
Matthias Braun's avatar
Matthias Braun committed
843

844
	proj_EDX = new_rd_Proj(dbgi, irg, block, res, mode_Iu, pn_EDX);
845
846

	return proj_EDX;
847
848
}

849
850


851
852
853
/**
 * Creates an ia32 And.
 *
854
 * @return The created ia32 And node
855
 */
856
static ir_node *gen_And(ir_node *node) {
857
858
	ir_node *op1 = get_And_left(node);
	ir_node *op2 = get_And_right(node);
859

860
	assert (! mode_is_float(get_irn_mode(node)));
861
	return gen_binop(node, op1, op2, new_rd_ia32_And, 1);
862
863
864
865
866
867
868
}



/**
 * Creates an ia32 Or.
 *
869
 * @return The created ia32 Or node
870
 */
871
static ir_node *gen_Or(ir_node *node) {
872
873
	ir_node *op1 = get_Or_left(node);
	ir_node *op2 = get_Or_right(node);
874

875
	assert (! mode_is_float(get_irn_mode(node)));
876
	return gen_binop(node, op1, op2, new_rd_ia32_Or, 1);
877
878
879
880
881
882
883
}



/**
 * Creates an ia32 Eor.
 *
884
 * @return The created ia32 Eor node
885
 */
886
static ir_node *gen_Eor(ir_node *node) {
887
888
	ir_node *op1 = get_Eor_left(node);
	ir_node *op2 = get_Eor_right(node);
889

890
	assert(! mode_is_float(get_irn_mode(node)));
891
	return gen_binop(node, op1, op2, new_rd_ia32_Xor, 1);
892
893
894
895
896
897
}


/**
 * Creates an ia32 Sub.
 *
898
 * @return The created ia32 Sub node
899
 */
900
static ir_node *gen_Sub(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
901
	ir_node  *block   = be_transform_node(get_nodes_block(node));
902
	ir_node  *op1     = get_Sub_left(node);
Michael Beck's avatar
Michael Beck committed
903
	ir_node  *new_op1 = be_transform_node(op1);
904
	ir_node  *op2     = get_Sub_right(node);
Michael Beck's avatar
Michael Beck committed
905
	ir_node  *new_op2 = be_transform_node(op2);
906
	ir_node  *new_op  = NULL;
Michael Beck's avatar
Michael Beck committed
907
	ir_graph *irg     = current_ir_graph;
908
	dbg_info *dbgi    = get_irn_dbg_info(node);
909
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
910
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
911
	ir_node  *nomem   = new_NoMem();
912
913
	ir_node  *expr_op, *imm_op;

914
915
	/* Check if immediate optimization is on and */
	/* if it's an operation with immediate.      */
Michael Beck's avatar
Michael Beck committed
916
	imm_op  = (env_cg->opt & IA32_OPT_IMMOPS) ? get_immediate_op(NULL, new_op2) : NULL;
917
	expr_op = get_expr_op(new_op1, new_op2);
918
919
920
921

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

	if (mode_is_float(mode)) {