ia32_transform.c 135 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
#include "height.h"
51

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

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

Christian Würdig's avatar
Christian Würdig committed
69
70
#include "gen_ia32_regalloc_if.h"

71
72
73
74
75
#define SFP_SIGN   "0x80000000"
#define DFP_SIGN   "0x8000000000000000"
#define SFP_ABS    "0x7FFFFFFF"
#define DFP_ABS    "0x7FFFFFFFFFFFFFFF"
#define DFP_INTMAX "9223372036854775807"
76
77
78
79
80

#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"
81
#define TP_INT_MAX  "ia32_int_max"
82
83
84
85
86

#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"
87
#define ENT_INT_MAX  "IA32_INT_MAX"
88

89
90
91
#define mode_vfp	(ia32_reg_classes[CLASS_ia32_vfp].mode)
#define mode_xmm    (ia32_reg_classes[CLASS_ia32_xmm].mode)

92
93
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)

94
/** hold the current code generator during transformation */
95
96
static ia32_code_gen_t *env_cg       = NULL;
static ir_node         *initial_fpcw = NULL;
97
static heights_t       *heights      = NULL;
98

99
100
extern ir_op *get_op_Mulh(void);

101
typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg,
102
103
        ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
        ir_node *op1, ir_node *op2);
Christian Würdig's avatar
Christian Würdig committed
104

105
106
107
108
typedef ir_node *construct_shift_func(dbg_info *db, ir_graph *irg,
        ir_node *block, ir_node *op1, ir_node *op2);

typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_graph *irg,
109
110
        ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
        ir_node *op);
111
112
113
114

typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_graph *irg,
        ir_node *block, ir_node *base, ir_node *index, ir_node *mem);

Matthias Braun's avatar
Matthias Braun committed
115
typedef ir_node *construct_binop_float_func(dbg_info *db, ir_graph *irg,
116
117
        ir_node *block, ir_node *base, ir_node *index, ir_node *mem,
        ir_node *op1, ir_node *op2, ir_node *fpcw);
Matthias Braun's avatar
Matthias Braun committed
118

119
typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
120
        ir_node *block, ir_node *op);
121

Christian Würdig's avatar
Christian Würdig committed
122
123
124
125
126
127
128
129
130
131
/****************************************************************************************************
 *                  _        _                        __                           _   _
 *                 | |      | |                      / _|                         | | (_)
 *  _ __   ___   __| | ___  | |_ _ __ __ _ _ __  ___| |_ ___  _ __ _ __ ___   __ _| |_ _  ___  _ __
 * | '_ \ / _ \ / _` |/ _ \ | __| '__/ _` | '_ \/ __|  _/ _ \| '__| '_ ` _ \ / _` | __| |/ _ \| '_ \
 * | | | | (_) | (_| |  __/ | |_| | | (_| | | | \__ \ || (_) | |  | | | | | | (_| | |_| | (_) | | | |
 * |_| |_|\___/ \__,_|\___|  \__|_|  \__,_|_| |_|___/_| \___/|_|  |_| |_| |_|\__,_|\__|_|\___/|_| |_|
 *
 ****************************************************************************************************/

132
133
static ir_node *try_create_Immediate(ir_node *node,
                                     char immediate_constraint_type);
134

135
136
137
static ir_node *create_immediate_or_transform(ir_node *node,
                                              char immediate_constraint_type);

138
static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
139
140
                                dbg_info *dbgi, ir_node *block,
                                ir_node *op, ir_node *orig_node);
141

142
143
144
145
/**
 * Return true if a mode can be stored in the GP register set
 */
static INLINE int mode_needs_gp_reg(ir_mode *mode) {
146
147
	if(mode == mode_fpcw)
		return 0;
148
	return mode_is_int(mode) || mode_is_reference(mode) || mode == mode_b;
149
150
}

151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/**
 * 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);
178
		set_type_alignment_bytes(res, 16);
179
180
181
182
183
184
185
186
		pmap_insert(types, mode, res);
	}
	else
		res = e->value;
	return res;
}

/**
187
 * Get an atomic entity that is initialized with a tarval
188
 */
189
static ir_entity *ia32_get_entity_for_tv(ia32_isa_t *isa, ir_node *cnst)
190
191
{
	tarval *tv    = get_Const_tarval(cnst);
192
	pmap_entry *e = pmap_find(isa->tv_ent, tv);
193
194
195
196
197
198
199
	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)
200
			tp = get_prim_type(isa->types, mode);
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

		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;

216
		pmap_insert(isa->tv_ent, tv, res);
217
	} else {
218
		res = e->value;
219
220
	}

221
222
223
	return res;
}

224
225
226
227
228
229
230
231
232
233
234
235
236
237
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;
}

238
static int is_Const_Minus_1(ir_node *node) {
Matthias Braun's avatar
Matthias Braun committed
239
240
	tarval  *tv;
	ir_mode *mode;
241
242
243
	if(!is_Const(node))
		return 0;

Matthias Braun's avatar
Matthias Braun committed
244
245
246
247
	mode = get_irn_mode(node);
	if(!mode_is_signed(mode))
		return 0;

248
249
250
251
252
253
	tv = get_Const_tarval(node);
	tv = tarval_neg(tv);

	return classify_tarval(tv) == CNST_ONE;
}

254
255
256
/**
 * Transforms a Const.
 */
257
static ir_node *gen_Const(ir_node *node) {
258
259
260
261
262
	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);
263
264

	if (mode_is_float(mode)) {
265
		ir_node   *res   = NULL;
Michael Beck's avatar
Michael Beck committed
266
		ir_node   *noreg = ia32_new_NoReg_gp(env_cg);
267
268
		ir_node   *nomem = new_NoMem();
		ir_node   *load;
269
		ir_entity *floatent;
270
		cnst_classify_t clss = classify_Const(node);
271

272
273
274
275
276
277
278
		if (USE_SSE2(env_cg)) {
			if (clss == CNST_NULL) {
				load = new_rd_ia32_xZero(dbgi, irg, block);
				set_ia32_ls_mode(load, mode);
				res  = load;
			} else {
				floatent = ia32_get_entity_for_tv(env_cg->isa, node);
279

280
281
282
283
284
285
286
287
				load     = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem,
											 mode);
				set_ia32_op_type(load, ia32_AddrModeS);
				set_ia32_am_sc(load, floatent);
				set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
				res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
			}
		} else {
288
			if (clss == CNST_NULL) {
289
				load = new_rd_ia32_vfldz(dbgi, irg, block);
290
				res  = load;
291
			} else if (clss == CNST_ONE) {
292
				load = new_rd_ia32_vfld1(dbgi, irg, block);
293
				res  = load;
294
			} else {
295
				floatent = ia32_get_entity_for_tv(env_cg->isa, node);
296

Matthias Braun's avatar
Matthias Braun committed
297
				load     = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
298
				set_ia32_op_type(load, ia32_AddrModeS);
299
				set_ia32_am_sc(load, floatent);
300
301
				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);
302
			}
303
			set_ia32_ls_mode(load, mode);
304
305
		}

Michael Beck's avatar
Michael Beck committed
306
		SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
307
308

		/* Const Nodes before the initial IncSP are a bad idea, because
309
310
311
		 * 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.
312
313
314
315
316
		 */
		if (get_irg_start_block(irg) == block) {
			add_irn_dep(load, get_irg_frame(irg));
		}

Michael Beck's avatar
Michael Beck committed
317
		SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
318
319
		return res;
	} else {
320
321
322
323
324
325
326
327
328
329
330
331
332
333
		ir_node *cnst;
		tarval  *tv = get_Const_tarval(node);
		long     val;

		tv = tarval_convert_to(tv, mode_Iu);

		if(tv == get_tarval_bad() || tv == get_tarval_undefined()
				|| tv == NULL) {
			panic("couldn't convert constant tarval (%+F)", node);
		}
		val = get_tarval_long(tv);

		cnst = new_rd_ia32_Const(dbgi, irg, block, NULL, 0, val);
		SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
334
335
336
337
338
339
340
341
342
343
344
345
346

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

		return cnst;
	}
}

/**
 * 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)) {
356
357
358
		ir_node *noreg = ia32_new_NoReg_gp(env_cg);
		ir_node *nomem = new_NoMem();

Michael Beck's avatar
Michael Beck committed
359
		if (USE_SSE2(env_cg))
360
			cnst = new_rd_ia32_xLoad(dbgi, irg, block, noreg, noreg, nomem, mode_E);
361
		else
362
363
			cnst = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode_E);
		set_ia32_am_sc(cnst, get_SymConst_entity(node));
364
		set_ia32_use_frame(cnst);
365
	} else {
Michael Beck's avatar
Michael Beck committed
366
367
		ir_entity *entity;

368
369
370
		if(get_SymConst_kind(node) != symconst_addr_ent) {
			panic("backend only support symconst_addr_ent (at %+F)", node);
		}
Michael Beck's avatar
Michael Beck committed
371
		entity = get_SymConst_entity(node);
372
		cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
373
374
375
376
377
378
379
380
381
	}

	/* 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));
	}

Michael Beck's avatar
Michael Beck committed
382
	SET_IA32_ORIG_NODE(cnst, ia32_get_old_node_name(env_cg, node));
383
384
385
386

	return cnst;
}

387
/* Generates an entity for a known FP const (used for FP Neg + Abs) */
388
ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
389
390
391
392
	static const struct {
		const char *tp_name;
		const char *ent_name;
		const char *cnst_str;
393
394
		char mode;
		char align;
395
	} names [ia32_known_const_max] = {
396
397
398
399
400
		{ TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN,   0, 16 },	/* ia32_SSIGN */
		{ TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN,   1, 16 },	/* ia32_DSIGN */
		{ TP_SFP_ABS,  ENT_SFP_ABS,  SFP_ABS,    0, 16 },	/* ia32_SABS */
		{ TP_DFP_ABS,  ENT_DFP_ABS,  DFP_ABS,    1, 16 },	/* ia32_DABS */
		{ TP_INT_MAX,  ENT_INT_MAX,  DFP_INTMAX, 2, 4 }		/* ia32_INTMAX */
401
	};
402
	static ir_entity *ent_cache[ia32_known_const_max];
403
404

	const char    *tp_name, *ent_name, *cnst_str;
405
406
407
	ir_type       *tp;
	ir_node       *cnst;
	ir_graph      *rem;
408
	ir_entity     *ent;
409
	tarval        *tv;
Michael Beck's avatar
BugFix:    
Michael Beck committed
410
	ir_mode       *mode;
411

Christian Würdig's avatar
Christian Würdig committed
412
	ent_name = names[kct].ent_name;
413
414
415
	if (! ent_cache[kct]) {
		tp_name  = names[kct].tp_name;
		cnst_str = names[kct].cnst_str;
416

417
418
419
420
421
		switch (names[kct].mode) {
		case 0:  mode = mode_Iu; break;
		case 1:  mode = mode_Lu; break;
		default: mode = mode_F; break;
		}
422
		tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
423
		tp  = new_type_primitive(new_id_from_str(tp_name), mode);
424
425
426
		/* set the specified alignment */
		set_type_alignment_bytes(tp, names[kct].align);

427
428
429
430
431
432
433
434
435
436
437
		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();
438
		cnst = new_Const(mode, tv);
439
440
441
442
		current_ir_graph = rem;

		set_atomic_ent_value(ent, cnst);

443
444
		/* cache the entry */
		ent_cache[kct] = ent;
445
	}
446

447
	return ent_cache[kct];
448
449
}

Christian Würdig's avatar
Christian Würdig committed
450
451
452
453
#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
454
455
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;
456

Christian Würdig's avatar
Christian Würdig committed
457
	lc_eoprintf(firm_get_arg_env(), isa->name_obst, "%+F", irn);
Christian Würdig's avatar
Christian Würdig committed
458
459
460
461
	obstack_1grow(isa->name_obst, 0);
 	return obstack_finish(isa->name_obst);
}
#endif /* NDEBUG */
Christian Würdig's avatar
Christian Würdig committed
462

463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
static int use_source_address_mode(ir_node *block, ir_node *node,
                                   ir_node *other)
{
	ir_mode *mode;
	ir_node *load;
	long     pn;

	if(!is_Proj(node))
		return 0;
	load = get_Proj_pred(node);
	pn   = get_Proj_proj(node);
	if(!is_Load(load) || pn != pn_Load_res)
		return 0;
	if(get_nodes_block(load) != block)
		return 0;
	/* we only use address mode if we're the only user of the load */
	if(get_irn_n_edges(node) > 1)
		return 0;

	mode = get_irn_mode(node);
	if(!mode_needs_gp_reg(mode))
		return 0;
485
486
487
488
489
490
491
	/*
	 * Matze: the unresolved question here is wether 8/16bit operations
	 * are a good idea if they define registers (as writing to an 8/16
	 * bit reg is bad on modern cpu as it confuses the dependency calculation
	 * for the full reg)
	 */
	if(other != NULL && get_Load_mode(load) != get_irn_mode(other))
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
		return 0;

	/* don't do AM if other node inputs depend on the load (via mem-proj) */
	if(other != NULL && get_nodes_block(other) == block
			&& heights_reachable_in_block(heights, other, load))
		return 0;

	return 1;
}

typedef struct ia32_address_mode_t ia32_address_mode_t;
struct ia32_address_mode_t {
	ia32_address_t  addr;
	ir_mode        *ls_mode;
	ir_node        *mem_proj;
	ia32_op_type_t  op_type;
	ir_node        *new_op1;
	ir_node        *new_op2;
	int             commutative;
	int             flipped;
};

static void build_address(ia32_address_mode_t *am, ir_node *node)
{
	ia32_address_t *addr    = &am->addr;
	ir_node        *load    = get_Proj_pred(node);
	ir_node        *ptr     = get_Load_ptr(load);
	ir_node        *mem     = get_Load_mem(load);
	ir_node        *new_mem = be_transform_node(mem);
	ir_node        *base;
	ir_node        *index;

	am->ls_mode  = get_Load_mode(load);
	am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);

	/* construct load address */
	ia32_create_address_mode(addr, ptr, 0);
	base  = addr->base;
	index = addr->index;

	if(base == NULL) {
		base = ia32_new_NoReg_gp(env_cg);
	} else {
		base = be_transform_node(base);
	}

	if(index == NULL) {
		index = ia32_new_NoReg_gp(env_cg);
540
	} else {
541
		index = be_transform_node(index);
542
	}
543
544
545
546

	addr->base  = base;
	addr->index = index;
	addr->mem   = new_mem;
547
548
}

549
550
551
552
553
554
555
556
557
558
static void set_address(ir_node *node, ia32_address_t *addr)
{
	set_ia32_am_scale(node, addr->scale);
	set_ia32_am_sc(node, addr->symconst_ent);
	set_ia32_am_offs_int(node, addr->offset);
	if(addr->symconst_sign)
		set_ia32_am_sc_sign(node);
	if(addr->use_frame)
		set_ia32_use_frame(node);
	set_ia32_frame_ent(node, addr->frame_entity);
559
560
}

561
562
563
static void set_am_attributes(ir_node *node, ia32_address_mode_t *am)
{
	set_address(node, &am->addr);
564

565
566
567
568
569
	set_ia32_op_type(node, am->op_type);
	set_ia32_ls_mode(node, am->ls_mode);
	if(am->commutative)
		set_ia32_commutative(node);
}
570

571
572
static void match_arguments(ia32_address_mode_t *am, ir_node *block,
                            ir_node *op1, ir_node *op2, int commutative,
573
574
                            int use_am_and_immediates, int use_am,
                            int use_8_16_bit_am)
575
576
577
578
579
580
581
582
{
	ia32_address_t *addr     = &am->addr;
	ir_node        *noreg_gp = ia32_new_NoReg_gp(env_cg);
	ir_node        *new_op1;
	ir_node        *new_op2;

	memset(am, 0, sizeof(am[0]));

583
584
585
	if(!use_8_16_bit_am && get_mode_size_bits(get_irn_mode(op1)) < 32)
		use_am = 0;

586
	new_op2 = try_create_Immediate(op2, 0);
587
	if(new_op2 == NULL && use_am && use_source_address_mode(block, op2, op1)) {
588
589
590
591
592
		build_address(am, op2);
		new_op1     = be_transform_node(op1);
		new_op2     = noreg_gp;
		am->op_type = ia32_AddrModeS;
	} else if(commutative && (new_op2 == NULL || use_am_and_immediates) &&
593
		      use_am && use_source_address_mode(block, op1, op2)) {
594
595
596
597
598
599
600
601
602
		build_address(am, op1);
		if(new_op2 != NULL) {
			new_op1 = noreg_gp;
		} else {
			new_op1 = be_transform_node(op2);
			new_op2 = noreg_gp;
			am->flipped = 1;
		}
		am->op_type = ia32_AddrModeS;
603
	} else {
604
605
606
607
		new_op1 = be_transform_node(op1);
		if(new_op2 == NULL)
			new_op2 = be_transform_node(op2);
		am->op_type = ia32_Normal;
608
	}
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
	if(addr->base == NULL)
		addr->base = noreg_gp;
	if(addr->index == NULL)
		addr->index = noreg_gp;
	if(addr->mem == NULL)
		addr->mem = new_NoMem();

	am->new_op1     = new_op1;
	am->new_op2     = new_op2;
	am->commutative = commutative;
}

static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
{
	ir_graph *irg = current_ir_graph;
	ir_mode  *mode;
	ir_node  *load;
626

627
628
629
630
631
632
633
634
635
636
637
638
	if(am->mem_proj == NULL)
		return node;

	/* we have to create a mode_T so the old MemProj can attach to us */
	mode = get_irn_mode(node);
	load = get_Proj_pred(am->mem_proj);

	mark_irn_visited(load);
	be_set_transformed_node(load, node);

	if(mode != mode_T) {
		set_irn_mode(node, mode_T);
639
		return new_rd_Proj(NULL, irg, get_nodes_block(node), node, mode, pn_ia32_res);
640
641
642
	} else {
		return node;
	}
643
}
644
645
646
647
648
649
650
651
652

/**
 * 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.
 */
653
static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
654
                          construct_binop_func *func, int commutative)
655
{
656
657
658
659
	ir_node  *src_block = get_nodes_block(node);
	ir_node  *block     = be_transform_node(src_block);
	ir_graph *irg       = current_ir_graph;
	dbg_info *dbgi      = get_irn_dbg_info(node);
660
	ir_node  *new_node;
661
662
	ia32_address_mode_t  am;
	ia32_address_t      *addr = &am.addr;
663

664
	match_arguments(&am, src_block, op1, op2, commutative, 0, 1, 0);
665

666
667
	new_node = func(dbgi, irg, block, addr->base, addr->index, addr->mem,
	                am.new_op1, am.new_op2);
668
669
670
671
	set_am_attributes(new_node, &am);
	/* we can't use source address mode anymore when using immediates */
	if(is_ia32_Immediate(am.new_op1) || is_ia32_Immediate(am.new_op2))
		set_ia32_am_support(new_node, ia32_am_None, ia32_am_arity_none);
Michael Beck's avatar
Michael Beck committed
672
	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
673
674

	new_node = fix_mem_proj(new_node, &am);
Christian Würdig's avatar
Christian Würdig committed
675

676
	return new_node;
677
678
}

679
680
681
682
683
684
685
686
/**
 * 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
687
688
static ir_node *gen_binop_sse_float(ir_node *node, ir_node *op1, ir_node *op2,
                                    construct_binop_func *func)
689
{
Michael Beck's avatar
Michael Beck committed
690
691
692
	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);
693
	ir_node  *new_node = NULL;
694
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
695
	ir_graph *irg      = current_ir_graph;
696
	ir_mode  *mode     = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
697
	ir_node  *noreg_gp = ia32_new_NoReg_gp(env_cg);
698
699
	ir_node  *nomem    = new_NoMem();

700
701
	new_node = func(dbgi, irg, block, noreg_gp, noreg_gp, nomem, new_op1,
	                new_op2);
702
703
704
	if (is_op_commutative(get_irn_op(node))) {
		set_ia32_commutative(new_node);
	}
705
	set_ia32_ls_mode(new_node, mode);
706

Michael Beck's avatar
Michael Beck committed
707
	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
708
709
710

	return new_node;
}
711

712
713
714
715
716
717
718
719
720
721
722
723
724
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
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
/**
 * 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();

745
746
	new_node = func(dbgi, irg, block, noreg_gp, noreg_gp, nomem, new_op1, new_op2,
	                get_fpcw());
Matthias Braun's avatar
Matthias Braun committed
747
748
749
750
751
752
753
754
	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;
}
755
756
757
758
759
760
761
762
763

/**
 * 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.
 */
764
static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
765
                                construct_shift_func *func)
766
{
767
768
769
770
771
772
773
	dbg_info *dbgi      = get_irn_dbg_info(node);
	ir_graph *irg       = current_ir_graph;
	ir_node  *block     = get_nodes_block(node);
	ir_node  *new_block = be_transform_node(block);
	ir_node  *new_op1   = be_transform_node(op1);
	ir_node  *new_op2   = create_immediate_or_transform(op2, 0);
	ir_node  *res;
774

775
776
	assert(! mode_is_float(get_irn_mode(node))
	         && "Shift/Rotate with float not supported");
777

778
779
	res = func(dbgi, irg, new_block, new_op1, new_op2);
	SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
780

781
782
783
784
	/* 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));
785
		add_irn_dep(res, new_dep);
786
787
	}

788
	return res;
789
790
791
792
793
794
795
796
797
798
}


/**
 * 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.
 */
799
static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func)
800
{
Michael Beck's avatar
Michael Beck committed
801
802
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *new_op   = be_transform_node(op);
803
	ir_node  *new_node = NULL;
Michael Beck's avatar
Michael Beck committed
804
	ir_graph *irg      = current_ir_graph;
805
	dbg_info *dbgi     = get_irn_dbg_info(node);
806

807
	new_node = func(dbgi, irg, block, new_op);
Christian Würdig's avatar
Christian Würdig committed
808

Michael Beck's avatar
Michael Beck committed
809
	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
810

811
	return new_node;
812
813
}

814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
static ir_node *create_lea_from_address(dbg_info *dbgi,	ir_node *block,
                                        ia32_address_t *addr)
{
	ir_graph *irg   = current_ir_graph;
	ir_node  *base  = addr->base;
	ir_node  *index = addr->index;
	ir_node  *res;

	if(base == NULL) {
		base = ia32_new_NoReg_gp(env_cg);
	} else {
		base = be_transform_node(base);
	}

	if(index == NULL) {
		index = ia32_new_NoReg_gp(env_cg);
	} else {
		index = be_transform_node(index);
	}

	res = new_rd_ia32_Lea(dbgi, irg, block, base, index);
	set_address(res, addr);

	return res;
}

static int am_has_immediates(const ia32_address_t *addr)
{
	return addr->offset != 0 || addr->symconst_ent != NULL
		|| addr->frame_entity || addr->use_frame;
}

846
847
848
849
850
/**
 * Creates an ia32 Add.
 *
 * @return the created ia32 Add node
 */
851
static ir_node *gen_Add(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
852
	ir_node  *block   = be_transform_node(get_nodes_block(node));
853
854
	ir_node  *op1     = get_Add_left(node);
	ir_node  *op2     = get_Add_right(node);
855
856
	ir_node  *new_op;
	ir_node  *new_op1;
Michael Beck's avatar
Michael Beck committed
857
	ir_graph *irg     = current_ir_graph;
858
859
	dbg_info *dbgi    = get_irn_dbg_info(node);
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
860
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
861
862
863
864
	ir_node  *src_block = get_nodes_block(node);
	ir_node  *add_immediate_op;
	ia32_address_t       addr;
	ia32_address_mode_t  am;
Christian Würdig's avatar
Christian Würdig committed
865
866

	if (mode_is_float(mode)) {
Michael Beck's avatar
Michael Beck committed
867
		if (USE_SSE2(env_cg))
Matthias Braun's avatar
Matthias Braun committed
868
			return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xAdd);
869
		else
Matthias Braun's avatar
Matthias Braun committed
870
			return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd);
Christian Würdig's avatar
Christian Würdig committed
871
	}
Christian Würdig's avatar
Christian Würdig committed
872

873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
	/**
	 * Rules for an Add:
	 *   0. Immediate Trees (example Add(Symconst, Const) -> Const)
	 *   1. Add with immediate -> Lea
	 *   2. Add with possible source address mode -> Add
	 *   3. Otherwise -> Lea
	 */
	memset(&addr, 0, sizeof(addr));
	ia32_create_address_mode(&addr, node, 1);
	add_immediate_op = NULL;
	/* a constant? */
	if(addr.base == NULL && addr.index == NULL) {
		new_op = new_rd_ia32_Const(dbgi, irg, block, addr.symconst_ent,
								   addr.symconst_sign, addr.offset);
		add_irn_dep(new_op, get_irg_frame(irg));
Michael Beck's avatar
Michael Beck committed
888
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
889
		return new_op;
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
	}
	/* add with immediate? */
	if(addr.index == NULL) {
		add_immediate_op = addr.base;
	} else if(addr.base == NULL && addr.scale == 0) {
		add_immediate_op = addr.index;
	}

	if(add_immediate_op != NULL) {
		if(!am_has_immediates(&addr)) {
#ifdef DEBUG_libfirm
			ir_fprintf(stderr, "Optimisation warning Add x,0 (%+F) found\n",
					   node);
#endif
			return be_transform_node(add_immediate_op);
		}

		new_op = create_lea_from_address(dbgi, block, &addr);
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
		return new_op;
Christian Würdig's avatar
Christian Würdig committed
910
911
	}

912
913
914
915
916
917
918
919
920
921
922
923
924
	/* test if we can use source address mode */
	memset(&am, 0, sizeof(am));
	new_op1 = NULL;
	if(use_source_address_mode(src_block, op2, op1)) {
		build_address(&am, op2);
		new_op1 = be_transform_node(op1);
	} else if(use_source_address_mode(src_block, op1, op2)) {
		build_address(&am, op1);
		new_op1 = be_transform_node(op2);
	}
	/* construct an Add with source address mode */
	if(new_op1 != NULL) {
		ia32_address_t *am_addr = &am.addr;
925
926
		new_op = new_rd_ia32_Add(dbgi, irg, block, am_addr->base, am_addr->index,
		                         am_addr->mem, new_op1, noreg);
927
928
929
930
931
		set_address(new_op, am_addr);
		set_ia32_op_type(new_op, ia32_AddrModeS);
		set_ia32_ls_mode(new_op, am.ls_mode);
		set_ia32_commutative(new_op);
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
932

933
		new_op = fix_mem_proj(new_op, &am);
934

935
936
		return new_op;
	}
937

938
939
	/* otherwise construct a lea */
	new_op = create_lea_from_address(dbgi, block, &addr);
Michael Beck's avatar
Michael Beck committed
940
	SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
941
	return new_op;
Christian Würdig's avatar
Christian Würdig committed
942
943
}

944
945
946
947
948
/**
 * Creates an ia32 Mul.
 *
 * @return the created ia32 Mul node
 */
949
static ir_node *gen_Mul(ir_node *node) {
950
951
	ir_node *op1  = get_Mul_left(node);
	ir_node *op2  = get_Mul_right(node);
952
	ir_mode *mode = get_irn_mode(node);
953

954
	if (mode_is_float(mode)) {
Michael Beck's avatar
Michael Beck committed
955
		if (USE_SSE2(env_cg))
Matthias Braun's avatar
Matthias Braun committed
956
			return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xMul);
957
		else
Matthias Braun's avatar
Matthias Braun committed
958
			return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul);
Christian Würdig's avatar
Christian Würdig committed
959
	}
960

961
962
963
964
965
	/*
		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
	*/
966
	return gen_binop(node, op1, op2, new_rd_ia32_IMul, 1);
967
}
968
969
970
971
972
973
974
975

/**
 * 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
 */
976
static ir_node *gen_Mulh(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
977
	ir_node  *block   = be_transform_node(get_nodes_block(node));
978
	ir_node  *op1     = get_irn_n(node, 0);
Michael Beck's avatar
Michael Beck committed
979
	ir_node  *new_op1 = be_transform_node(op1);
980
	ir_node  *op2     = get_irn_n(node, 1);
Michael Beck's avatar
Michael Beck committed
981
982
	ir_node  *new_op2 = be_transform_node(op2);
	ir_graph *irg     = current_ir_graph;
983
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
984
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
985
	ir_mode  *mode    = get_irn_mode(node);
Matthias Braun's avatar
Matthias Braun committed
986
	ir_node  *proj_EDX, *res;
987

988
	assert(!mode_is_float(mode) && "Mulh with float not supported");
989
	if (mode_is_signed(mode)) {
990
991
		res = new_rd_ia32_IMul1OP(dbgi, irg, block, noreg, noreg, new_NoMem(),
		                          new_op1, new_op2);
Matthias Braun's avatar
Matthias Braun committed
992
	} else {
993
994
		res = new_rd_ia32_Mul(dbgi, irg, block, noreg, noreg, new_NoMem(), new_op1,
		                      new_op2);
Matthias Braun's avatar
Matthias Braun committed
995
	}
996

Matthias Braun's avatar
Matthias Braun committed
997
998
	set_ia32_commutative(res);

999
	proj_EDX = new_rd_Proj(dbgi, irg, block, res, mode_Iu, pn_EDX);
1000
1001

	return proj_EDX;
1002
1003
}

1004
1005


1006
1007
1008
/**
 * Creates an ia32 And.
 *
1009
 * @return The created ia32 And node
1010
 */
1011
static ir_node *gen_And(ir_node *node) {
1012
1013
	ir_node *op1 = get_And_left(node);
	ir_node *op2 = get_And_right(node);
1014
1015
	assert(! mode_is_float(get_irn_mode(node)));

1016
	/* is it a zero extension? */
Michael Beck's avatar
Michael Beck committed
1017
	if (is_Const(op2)) {
1018
1019
1020
1021
1022
		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);
1023
			ir_node  *block  = get_nodes_block(node);
1024
1025
1026
1027
1028
			ir_mode  *src_mode;
			ir_node  *res;

			if(v == 0xFF) {
				src_mode = mode_Bu;
Michael Beck's avatar
Michael Beck committed
1029
			} else {
1030
1031
				assert(v == 0xFFFF);
				src_mode = mode_Hu;
Michael Beck's avatar
Michael Beck committed
1032
			}
1033
			res = create_I2I_Conv(src_mode, mode_Iu, dbgi, block, op1, node);
Michael Beck's avatar
Michael Beck committed
1034

1035
			return res;
1036
1037
		}
	}
1038

1039
	return gen_binop(node, op1, op2, new_rd_ia32_And, 1);
1040
1041
1042
1043
1044
1045
1046
}



/**
 * Creates an ia32 Or.
 *
1047
 * @return The created ia32 Or node
1048
 */
1049
static ir_node *gen_Or(ir_node *node) {
1050
1051
	ir_node *op1 = get_Or_left(node);
	ir_node *op2 = get_Or_right(node);
1052

1053
	assert (! mode_is_float(get_irn_mode(node)));
1054
	return gen_binop(node, op1, op2, new_rd_ia32_Or, 1);
1055
1056
1057
1058
1059
1060
1061
}



/**
 * Creates an ia32 Eor.
 *
1062
 * @return The created ia32 Eor node
1063
 */
1064
static ir_node *gen_Eor(ir_node *node) {
1065
1066
	ir_node *op1 = get_Eor_left(node);
	ir_node *op2 = get_Eor_right(node);
1067

1068
	assert(! mode_is_float(get_irn_mode(node)));
1069
	return gen_binop(node, op1, op2, new_rd_ia32_Xor, 1);
1070
1071
1072
1073
1074
1075
}


/**
 * Creates an ia32 Sub.
 *
1076
 * @return The created ia32 Sub node
1077
 */
1078
static ir_node *gen_Sub(ir_node *node) {
1079
1080
1081
	ir_node  *op1  = get_Sub_left(node);
	ir_node  *op2  = get_Sub_right(node);
	ir_mode  *mode = get_irn_mode(node);
1082
1083

	if (mode_is_float(mode)) {
Michael Beck's avatar
Michael Beck committed
1084
		if (USE_SSE2(env_cg))
Matthias Braun's avatar
Matthias Braun committed
1085
			return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xSub);