ia32_transform.c 131 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
76
77
78
79
80
81
82
83
84
85
#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"

86
87
88
#define mode_vfp	(ia32_reg_classes[CLASS_ia32_vfp].mode)
#define mode_xmm    (ia32_reg_classes[CLASS_ia32_xmm].mode)

89
90
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)

91
/** hold the current code generator during transformation */
92
93
static ia32_code_gen_t *env_cg       = NULL;
static ir_node         *initial_fpcw = NULL;
94
static heights_t       *heights      = NULL;
95

96
97
extern ir_op *get_op_Mulh(void);

98
99
100
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
101

102
103
104
105
106
107
108
109
110
111
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,
        ir_node *block, ir_node *base, ir_node *index, ir_node *op,
        ir_node *mem);

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
112
113
114
115
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);

116
typedef ir_node *construct_unop_func(dbg_info *db, ir_graph *irg,
117
        ir_node *block, ir_node *op);
118

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

129
130
static ir_node *try_create_Immediate(ir_node *node,
                                     char immediate_constraint_type);
131

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

135
136
137
138
static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
                                dbg_info *dbgi, ir_node *new_block,
                                ir_node *new_op);

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

148
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
/**
 * 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);
175
		set_type_alignment_bytes(res, 16);
176
177
178
179
180
181
182
183
		pmap_insert(types, mode, res);
	}
	else
		res = e->value;
	return res;
}

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

		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;

213
		pmap_insert(isa->tv_ent, tv, res);
214
	} else {
215
		res = e->value;
216
217
	}

218
219
220
	return res;
}

221
222
223
224
225
226
227
228
229
230
231
232
233
234
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;
}

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

Matthias Braun's avatar
Matthias Braun committed
241
242
243
244
	mode = get_irn_mode(node);
	if(!mode_is_signed(mode))
		return 0;

245
246
247
248
249
250
	tv = get_Const_tarval(node);
	tv = tarval_neg(tv);

	return classify_tarval(tv) == CNST_ONE;
}

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

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

269
270
271
272
273
274
275
		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);
276

277
278
279
280
281
282
283
284
				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 {
285
			if (clss == CNST_NULL) {
286
				load = new_rd_ia32_vfldz(dbgi, irg, block);
287
				res  = load;
288
			} else if (clss == CNST_ONE) {
289
				load = new_rd_ia32_vfld1(dbgi, irg, block);
290
				res  = load;
291
			} else {
292
				floatent = ia32_get_entity_for_tv(env_cg->isa, node);
293

Matthias Braun's avatar
Matthias Braun committed
294
				load     = new_rd_ia32_vfld(dbgi, irg, block, noreg, noreg, nomem, mode);
295
				set_ia32_op_type(load, ia32_AddrModeS);
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
302
		}

Michael Beck's avatar
Michael Beck committed
303
		SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
304
305

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

Michael Beck's avatar
Michael Beck committed
314
		SET_IA32_ORIG_NODE(load, ia32_get_old_node_name(env_cg, node));
315
316
		return res;
	} else {
317
318
319
320
321
322
323
324
325
326
327
328
329
330
		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));
331
332
333
334
335
336
337
338
339
340
341
342
343

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

		return cnst;
	}
}

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

	if (mode_is_float(mode)) {
353
354
355
		ir_node *noreg = ia32_new_NoReg_gp(env_cg);
		ir_node *nomem = new_NoMem();

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

365
366
367
		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
368
		entity = get_SymConst_entity(node);
369
		cnst = new_rd_ia32_Const(dbgi, irg, block, entity, 0, 0);
370
371
372
373
374
375
376
377
378
	}

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

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

	return cnst;
}

384
/* Generates an entity for a known FP const (used for FP Neg + Abs) */
385
ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct) {
386
387
388
389
390
391
392
393
394
395
	static const struct {
		const char *tp_name;
		const char *ent_name;
		const char *cnst_str;
	} names [ia32_known_const_max] = {
		{ TP_SFP_SIGN, ENT_SFP_SIGN, SFP_SIGN },	/* ia32_SSIGN */
		{ TP_DFP_SIGN, ENT_DFP_SIGN, DFP_SIGN },	/* ia32_DSIGN */
		{ TP_SFP_ABS,  ENT_SFP_ABS,  SFP_ABS },		/* ia32_SABS */
		{ TP_DFP_ABS,  ENT_DFP_ABS,  DFP_ABS }		/* ia32_DABS */
	};
396
	static ir_entity *ent_cache[ia32_known_const_max];
397
398

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

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

411
412
		mode = kct == ia32_SSIGN || kct == ia32_SABS ? mode_Iu : mode_Lu;
		//mode = mode_xmm;
413
		tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
414
		tp  = new_type_primitive(new_id_from_str(tp_name), mode);
415
416
417
		/* these constants are loaded as part of an instruction, so they must be aligned
		   to 128 bit. */
		set_type_alignment_bytes(tp, 16);
418
419
420
421
422
423
424
425
426
427
428
		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();
429
		cnst = new_Const(mode, tv);
430
431
432
433
		current_ir_graph = rem;

		set_atomic_ent_value(ent, cnst);

434
435
		/* cache the entry */
		ent_cache[kct] = ent;
436
	}
437

438
	return ent_cache[kct];
439
440
}

Christian Würdig's avatar
Christian Würdig committed
441
442
443
444
#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
445
446
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;
447

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

454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
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
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;
	if(get_mode_size_bits(mode) != 32)
		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);
525
	} else {
526
		index = be_transform_node(index);
527
	}
528
529
530
531

	addr->base  = base;
	addr->index = index;
	addr->mem   = new_mem;
532
533
}

534
535
536
537
538
539
540
541
542
543
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);
544
545
}

546
547
548
static void set_am_attributes(ir_node *node, ia32_address_mode_t *am)
{
	set_address(node, &am->addr);
549

550
551
552
553
554
	set_ia32_op_type(node, am->op_type);
	set_ia32_ls_mode(node, am->ls_mode);
	if(am->commutative)
		set_ia32_commutative(node);
}
555

556
557
static void match_arguments(ia32_address_mode_t *am, ir_node *block,
                            ir_node *op1, ir_node *op2, int commutative,
558
                            int use_am_and_immediates, int use_am)
559
560
561
562
563
564
565
566
567
{
	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]));

	new_op2 = try_create_Immediate(op2, 0);
568
	if(new_op2 == NULL && use_am && use_source_address_mode(block, op2, op1)) {
569
570
571
572
573
		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) &&
574
		      use_am && use_source_address_mode(block, op1, op2)) {
575
576
577
578
579
580
581
582
583
		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;
584
	} else {
585
586
587
588
		new_op1 = be_transform_node(op1);
		if(new_op2 == NULL)
			new_op2 = be_transform_node(op2);
		am->op_type = ia32_Normal;
589
	}
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
	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;
607

608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
	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);
		return new_rd_Proj(NULL, irg, get_nodes_block(node), node, mode, 0);
	} else {
		return node;
	}
624
}
625
626
627
628
629
630
631
632
633

/**
 * 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.
 */
634
static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
635
                          construct_binop_func *func, int commutative)
636
{
637
638
639
640
	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);
641
	ir_node  *new_node;
642
643
	ia32_address_mode_t  am;
	ia32_address_t      *addr = &am.addr;
644

645
	match_arguments(&am, src_block, op1, op2, commutative, 0, 1);
646

647
648
649
650
651
652
	new_node = func(dbgi, irg, block, addr->base, addr->index, am.new_op1,
	                am.new_op2, addr->mem);
	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
653
	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
654
655

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

657
	return new_node;
658
659
}

660
661
662
663
664
665
666
667
/**
 * 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
668
669
static ir_node *gen_binop_sse_float(ir_node *node, ir_node *op1, ir_node *op2,
                                    construct_binop_func *func)
670
{
Michael Beck's avatar
Michael Beck committed
671
672
673
	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);
674
	ir_node  *new_node = NULL;
675
	dbg_info *dbgi     = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
676
	ir_graph *irg      = current_ir_graph;
677
	ir_mode  *mode     = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
678
	ir_node  *noreg_gp = ia32_new_NoReg_gp(env_cg);
679
680
	ir_node  *nomem    = new_NoMem();

Matthias Braun's avatar
Matthias Braun committed
681
682
	new_node = func(dbgi, irg, block, noreg_gp, noreg_gp, new_op1, new_op2,
	                nomem);
683
684
685
	if (is_op_commutative(get_irn_op(node))) {
		set_ia32_commutative(new_node);
	}
686
	set_ia32_ls_mode(new_node, mode);
687

Michael Beck's avatar
Michael Beck committed
688
	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
689
690
691

	return new_node;
}
692

693
694
695
696
697
698
699
700
701
702
703
704
705
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
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
/**
 * 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,
727
	                nomem, get_fpcw());
Matthias Braun's avatar
Matthias Braun committed
728
729
730
731
732
733
734
735
	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;
}
736
737
738
739
740
741
742
743
744

/**
 * 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.
 */
745
static ir_node *gen_shift_binop(ir_node *node, ir_node *op1, ir_node *op2,
746
                                construct_shift_func *func)
747
{
748
749
750
751
752
753
754
	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;
755

756
757
	assert(! mode_is_float(get_irn_mode(node))
	         && "Shift/Rotate with float not supported");
758

759
760
	res = func(dbgi, irg, new_block, new_op1, new_op2);
	SET_IA32_ORIG_NODE(res, ia32_get_old_node_name(env_cg, node));
761

762
763
764
765
	/* 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));
766
		add_irn_dep(res, new_dep);
767
768
	}

769
	return res;
770
771
772
773
774
775
776
777
778
779
}


/**
 * 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.
 */
780
static ir_node *gen_unop(ir_node *node, ir_node *op, construct_unop_func *func)
781
{
Michael Beck's avatar
Michael Beck committed
782
783
	ir_node  *block    = be_transform_node(get_nodes_block(node));
	ir_node  *new_op   = be_transform_node(op);
784
	ir_node  *new_node = NULL;
Michael Beck's avatar
Michael Beck committed
785
	ir_graph *irg      = current_ir_graph;
786
	dbg_info *dbgi     = get_irn_dbg_info(node);
787

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

Michael Beck's avatar
Michael Beck committed
790
	SET_IA32_ORIG_NODE(new_node, ia32_get_old_node_name(env_cg, node));
791

792
	return new_node;
793
794
}

795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
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;
}

827
828
829
830
831
/**
 * Creates an ia32 Add.
 *
 * @return the created ia32 Add node
 */
832
static ir_node *gen_Add(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
833
	ir_node  *block   = be_transform_node(get_nodes_block(node));
834
835
	ir_node  *op1     = get_Add_left(node);
	ir_node  *op2     = get_Add_right(node);
836
837
	ir_node  *new_op;
	ir_node  *new_op1;
Michael Beck's avatar
Michael Beck committed
838
	ir_graph *irg     = current_ir_graph;
839
840
	dbg_info *dbgi    = get_irn_dbg_info(node);
	ir_mode  *mode    = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
841
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
842
843
844
845
	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
846
847

	if (mode_is_float(mode)) {
Michael Beck's avatar
Michael Beck committed
848
		if (USE_SSE2(env_cg))
Matthias Braun's avatar
Matthias Braun committed
849
			return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xAdd);
850
		else
Matthias Braun's avatar
Matthias Braun committed
851
			return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfadd);
Christian Würdig's avatar
Christian Würdig committed
852
	}
Christian Würdig's avatar
Christian Würdig committed
853

854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
	/**
	 * 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
869
		SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
870
		return new_op;
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
	}
	/* 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
891
892
	}

893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
	/* 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;
		new_op = new_rd_ia32_Add(dbgi, irg, block, am_addr->base,
		                         am_addr->index, new_op1, noreg, am_addr->mem);
		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));
913

914
		new_op = fix_mem_proj(new_op, &am);
915

916
917
		return new_op;
	}
918

919
920
	/* otherwise construct a lea */
	new_op = create_lea_from_address(dbgi, block, &addr);
Michael Beck's avatar
Michael Beck committed
921
	SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));
922
	return new_op;
Christian Würdig's avatar
Christian Würdig committed
923
924
}

925
926
927
928
929
/**
 * Creates an ia32 Mul.
 *
 * @return the created ia32 Mul node
 */
930
static ir_node *gen_Mul(ir_node *node) {
931
932
	ir_node *op1  = get_Mul_left(node);
	ir_node *op2  = get_Mul_right(node);
933
	ir_mode *mode = get_irn_mode(node);
934

935
	if (mode_is_float(mode)) {
Michael Beck's avatar
Michael Beck committed
936
		if (USE_SSE2(env_cg))
Matthias Braun's avatar
Matthias Braun committed
937
			return gen_binop_sse_float(node, op1, op2, new_rd_ia32_xMul);
938
		else
Matthias Braun's avatar
Matthias Braun committed
939
			return gen_binop_x87_float(node, op1, op2, new_rd_ia32_vfmul);
Christian Würdig's avatar
Christian Würdig committed
940
	}
941

942
943
944
945
946
	/*
		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
	*/
947
	return gen_binop(node, op1, op2, new_rd_ia32_IMul, 1);
948
}
949
950
951
952
953
954
955
956

/**
 * 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
 */
957
static ir_node *gen_Mulh(ir_node *node) {
Michael Beck's avatar
Michael Beck committed
958
	ir_node  *block   = be_transform_node(get_nodes_block(node));
959
	ir_node  *op1     = get_irn_n(node, 0);
Michael Beck's avatar
Michael Beck committed
960
	ir_node  *new_op1 = be_transform_node(op1);
961
	ir_node  *op2     = get_irn_n(node, 1);
Michael Beck's avatar
Michael Beck committed
962
963
	ir_node  *new_op2 = be_transform_node(op2);
	ir_graph *irg     = current_ir_graph;
964
	dbg_info *dbgi    = get_irn_dbg_info(node);
Michael Beck's avatar
Michael Beck committed
965
	ir_node  *noreg   = ia32_new_NoReg_gp(env_cg);
966
	ir_mode  *mode    = get_irn_mode(node);
Matthias Braun's avatar
Matthias Braun committed
967
	ir_node  *proj_EDX, *res;
968

969
	assert(!mode_is_float(mode) && "Mulh with float not supported");
970
	if (mode_is_signed(mode)) {
Matthias Braun's avatar
Matthias Braun committed
971
972
		res = new_rd_ia32_IMul1OP(dbgi, irg, block, noreg, noreg, new_op1,
		                          new_op2, new_NoMem());
Matthias Braun's avatar
Matthias Braun committed
973
	} else {
Matthias Braun's avatar
Matthias Braun committed
974
975
		res = new_rd_ia32_Mul(dbgi, irg, block, noreg, noreg, new_op1, new_op2,
		                      new_NoMem());
Matthias Braun's avatar
Matthias Braun committed
976
	}
977

Matthias Braun's avatar
Matthias Braun committed
978
979
	set_ia32_commutative(res);

980
	proj_EDX = new_rd_Proj(dbgi, irg, block, res, mode_Iu, pn_EDX);
981
982

	return proj_EDX;
983
984
}

985
986


987
988
989
/**
 * Creates an ia32 And.
 *
990
 * @return The created ia32 And node
991
 */
992
static ir_node *gen_And(ir_node *node) {
993
994
	ir_node *op1 = get_And_left(node);
	ir_node *op2 = get_And_right(node);
995
996
	assert(! mode_is_float(get_irn_mode(node)));

997
	/* is it a zero extension? */
Michael Beck's avatar
Michael Beck committed
998
	if (is_Const(op2)) {
999
1000
		tarval   *tv    = get_Const_tarval(op2);
		long      v     = get_tarval_long(tv);
For faster browsing, not all history is shown. View entire blame