ia32_transform.c 162 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * 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
#include "config.h"
28

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

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 "error.h"
48
#include "array_t.h"
49
#include "height.h"
50

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

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

Christian Würdig's avatar
Christian Würdig committed
71
72
#include "gen_ia32_regalloc_if.h"

73
74
75
76
/* define this to construct SSE constants instead of load them */
#undef CONSTRUCT_SSE_CONST


77
78
79
80
81
#define SFP_SIGN   "0x80000000"
#define DFP_SIGN   "0x8000000000000000"
#define SFP_ABS    "0x7FFFFFFF"
#define DFP_ABS    "0x7FFFFFFFFFFFFFFF"
#define DFP_INTMAX "9223372036854775807"
82
#define ULL_BIAS   "18446744073709551616"
83

84
85
86
87
88
#define ENT_SFP_SIGN ".LC_ia32_sfp_sign"
#define ENT_DFP_SIGN ".LC_ia32_dfp_sign"
#define ENT_SFP_ABS  ".LC_ia32_sfp_abs"
#define ENT_DFP_ABS  ".LC_ia32_dfp_abs"
#define ENT_ULL_BIAS ".LC_ia32_ull_bias"
89

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

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

95
static ir_node         *initial_fpcw = NULL;
96
int                     no_pic_adjust;
97

98
99
100
typedef ir_node *construct_binop_func(dbg_info *db, 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
101

102
103
104
typedef ir_node *construct_binop_flags_func(dbg_info *db, ir_node *block,
        ir_node *base, ir_node *index, ir_node *mem, ir_node *op1, ir_node *op2,
        ir_node *flags);
105

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

109
110
typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
        ir_node *base, ir_node *index, ir_node *mem, ir_node *op);
111

112
113
typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
        ir_node *base, ir_node *index, ir_node *mem);
114

115
116
117
typedef ir_node *construct_binop_float_func(dbg_info *db, 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_node *block, ir_node *op);
120

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

124
static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
125
126
                                dbg_info *dbgi, ir_node *block,
                                ir_node *op, ir_node *orig_node);
127

128
129
130
/* its enough to have those once */
static ir_node *nomem, *noreg_GP;

131
132
133
134
/** a list to postprocess all calls */
static ir_node **call_list;
static ir_type **call_types;

Michael Beck's avatar
Michael Beck committed
135
/** Return non-zero is a node represents the 0 constant. */
Christoph Mallon's avatar
Christoph Mallon committed
136
137
static bool is_Const_0(ir_node *node)
{
138
	return is_Const(node) && is_Const_null(node);
139
140
}

Michael Beck's avatar
Michael Beck committed
141
/** Return non-zero is a node represents the 1 constant. */
Christoph Mallon's avatar
Christoph Mallon committed
142
143
static bool is_Const_1(ir_node *node)
{
144
	return is_Const(node) && is_Const_one(node);
145
146
}

Michael Beck's avatar
Michael Beck committed
147
/** Return non-zero is a node represents the -1 constant. */
Christoph Mallon's avatar
Christoph Mallon committed
148
149
static bool is_Const_Minus_1(ir_node *node)
{
150
	return is_Const(node) && is_Const_all_one(node);
151
152
}

153
154
155
/**
 * returns true if constant can be created with a simple float command
 */
156
static bool is_simple_x87_Const(ir_node *node)
157
158
{
	tarval *tv = get_Const_tarval(node);
159
	if (tarval_is_null(tv) || tarval_is_one(tv))
160
		return true;
161
162

	/* TODO: match all the other float constants */
163
	return false;
164
165
166
167
168
}

/**
 * returns true if constant can be created with a simple float command
 */
169
static bool is_simple_sse_Const(ir_node *node)
170
{
Michael Beck's avatar
Michael Beck committed
171
	tarval  *tv   = get_Const_tarval(node);
172
	ir_mode *mode = get_tarval_mode(tv);
173

174
	if (mode == mode_F)
175
		return true;
176

177
178
179
180
181
	if (tarval_is_null(tv)
#ifdef CONSTRUCT_SSE_CONST
	    || tarval_is_one(tv)
#endif
	   )
182
		return true;
183
#ifdef CONSTRUCT_SSE_CONST
184
185
186
187
188
189
	if (mode == mode_D) {
		unsigned val = get_tarval_sub_bits(tv, 0) |
			(get_tarval_sub_bits(tv, 1) << 8) |
			(get_tarval_sub_bits(tv, 2) << 16) |
			(get_tarval_sub_bits(tv, 3) << 24);
		if (val == 0)
190
			/* lower 32bit are zero, really a 32bit constant */
191
			return true;
192
	}
193
#endif /* CONSTRUCT_SSE_CONST */
194
	/* TODO: match all the other float constants */
195
	return false;
196
197
}

198
199
200
/**
 * Transforms a Const.
 */
Christoph Mallon's avatar
Christoph Mallon committed
201
202
static ir_node *gen_Const(ir_node *node)
{
203
204
205
206
	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);
207

208
209
	assert(is_Const(node));

210
	if (mode_is_float(mode)) {
211
212
		ir_node   *res   = NULL;
		ir_node   *load;
213
214
		ir_entity *floatent;

215
		if (ia32_cg_config.use_sse2) {
216
217
			tarval *tv = get_Const_tarval(node);
			if (tarval_is_null(tv)) {
218
				load = new_bd_ia32_xZero(dbgi, block);
219
220
				set_ia32_ls_mode(load, mode);
				res  = load;
221
#ifdef CONSTRUCT_SSE_CONST
222
223
			} else if (tarval_is_one(tv)) {
				int     cnst  = mode == mode_F ? 26 : 55;
224
225
				ir_node *imm1 = ia32_create_Immediate(NULL, 0, cnst);
				ir_node *imm2 = ia32_create_Immediate(NULL, 0, 2);
226
227
				ir_node *pslld, *psrld;

228
				load = new_bd_ia32_xAllOnes(dbgi, block);
229
				set_ia32_ls_mode(load, mode);
230
				pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
231
				set_ia32_ls_mode(pslld, mode);
232
				psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
233
234
				set_ia32_ls_mode(psrld, mode);
				res = psrld;
235
#endif /* CONSTRUCT_SSE_CONST */
236
237
238
239
240
241
			} else if (mode == mode_F) {
				/* we can place any 32bit constant by using a movd gp, sse */
				unsigned val = get_tarval_sub_bits(tv, 0) |
				               (get_tarval_sub_bits(tv, 1) << 8) |
				               (get_tarval_sub_bits(tv, 2) << 16) |
				               (get_tarval_sub_bits(tv, 3) << 24);
242
				ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
243
				load = new_bd_ia32_xMovd(dbgi, block, cnst);
244
245
				set_ia32_ls_mode(load, mode);
				res = load;
246
			} else {
247
#ifdef CONSTRUCT_SSE_CONST
248
249
250
251
252
253
				if (mode == mode_D) {
					unsigned val = get_tarval_sub_bits(tv, 0) |
						(get_tarval_sub_bits(tv, 1) << 8) |
						(get_tarval_sub_bits(tv, 2) << 16) |
						(get_tarval_sub_bits(tv, 3) << 24);
					if (val == 0) {
254
						ir_node *imm32 = ia32_create_Immediate(NULL, 0, 32);
255
256
257
258
259
260
261
						ir_node *cnst, *psllq;

						/* fine, lower 32bit are zero, produce 32bit value */
						val = get_tarval_sub_bits(tv, 4) |
							(get_tarval_sub_bits(tv, 5) << 8) |
							(get_tarval_sub_bits(tv, 6) << 16) |
							(get_tarval_sub_bits(tv, 7) << 24);
262
						cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
263
						load = new_bd_ia32_xMovd(dbgi, block, cnst);
264
						set_ia32_ls_mode(load, mode);
265
						psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
266
267
268
269
270
						set_ia32_ls_mode(psllq, mode);
						res = psllq;
						goto end;
					}
				}
271
#endif /* CONSTRUCT_SSE_CONST */
272
				floatent = create_float_const_entity(node);
273

274
				load     = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode);
275
276
				set_ia32_op_type(load, ia32_AddrModeS);
				set_ia32_am_sc(load, floatent);
277
				arch_irn_add_flags(load, arch_irn_flags_rematerializable);
278
				res = new_r_Proj(block, load, mode_xmm, pn_ia32_xLoad_res);
279
280
			}
		} else {
281
			if (is_Const_null(node)) {
282
				load = new_bd_ia32_vfldz(dbgi, block);
283
				res  = load;
284
				set_ia32_ls_mode(load, mode);
285
			} else if (is_Const_one(node)) {
286
				load = new_bd_ia32_vfld1(dbgi, block);
287
				res  = load;
288
				set_ia32_ls_mode(load, mode);
289
			} else {
290
291
				ir_mode *ls_mode;

292
				floatent = create_float_const_entity(node);
293
294
295
				/* create_float_const_ent is smart and sometimes creates
				   smaller entities */
				ls_mode  = get_type_mode(get_entity_type(floatent));
296

297
				load     = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem,
298
				                            ls_mode);
299
				set_ia32_op_type(load, ia32_AddrModeS);
300
				set_ia32_am_sc(load, floatent);
301
				arch_irn_add_flags(load, arch_irn_flags_rematerializable);
302
				res = new_r_Proj(block, load, mode_vfp, pn_ia32_vfld_res);
303
304
			}
		}
305
#ifdef CONSTRUCT_SSE_CONST
306
end:
307
#endif /* CONSTRUCT_SSE_CONST */
308
		SET_IA32_ORIG_NODE(load, node);
309
310

		be_dep_on_frame(load);
311
		return res;
312
	} else { /* non-float mode */
313
314
315
316
317
318
		ir_node *cnst;
		tarval  *tv = get_Const_tarval(node);
		long     val;

		tv = tarval_convert_to(tv, mode_Iu);

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

325
		cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
326
		SET_IA32_ORIG_NODE(cnst, node);
327

328
		be_dep_on_frame(cnst);
329
330
331
332
333
334
335
		return cnst;
	}
}

/**
 * Transforms a SymConst.
 */
Christoph Mallon's avatar
Christoph Mallon committed
336
337
static ir_node *gen_SymConst(ir_node *node)
{
338
339
	ir_node  *old_block = get_nodes_block(node);
	ir_node  *block = be_transform_node(old_block);
340
341
	dbg_info *dbgi  = get_irn_dbg_info(node);
	ir_mode  *mode  = get_irn_mode(node);
342
343
344
	ir_node  *cnst;

	if (mode_is_float(mode)) {
345
		if (ia32_cg_config.use_sse2)
346
			cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
347
		else
348
			cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
349
		set_ia32_am_sc(cnst, get_SymConst_entity(node));
350
		set_ia32_use_frame(cnst);
351
	} else {
Michael Beck's avatar
Michael Beck committed
352
353
		ir_entity *entity;

Christoph Mallon's avatar
Christoph Mallon committed
354
		if (get_SymConst_kind(node) != symconst_addr_ent) {
355
356
			panic("backend only support symconst_addr_ent (at %+F)", node);
		}
Michael Beck's avatar
Michael Beck committed
357
		entity = get_SymConst_entity(node);
358
		cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0, 0);
359
360
	}

361
	SET_IA32_ORIG_NODE(cnst, node);
362

363
	be_dep_on_frame(cnst);
364
365
366
	return cnst;
}

Michael Beck's avatar
Michael Beck committed
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
/**
 * Create a float type for the given mode and cache it.
 *
 * @param mode   the mode for the float type (might be integer mode for SSE2 types)
 * @param align  alignment
 */
static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align) {
	char    buf[32];
	ir_type *tp;

	assert(align <= 16);

	if (mode == mode_Iu) {
		static ir_type *int_Iu[16] = {NULL, };

		if (int_Iu[align] == NULL) {
			snprintf(buf, sizeof(buf), "int_Iu_%u", align);
			int_Iu[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
			/* set the specified alignment */
			set_type_alignment_bytes(tp, align);
		}
		return int_Iu[align];
	} else if (mode == mode_Lu) {
		static ir_type *int_Lu[16] = {NULL, };

		if (int_Lu[align] == NULL) {
			snprintf(buf, sizeof(buf), "int_Lu_%u", align);
			int_Lu[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
			/* set the specified alignment */
			set_type_alignment_bytes(tp, align);
		}
		return int_Lu[align];
	} else if (mode == mode_F) {
		static ir_type *float_F[16] = {NULL, };

		if (float_F[align] == NULL) {
			snprintf(buf, sizeof(buf), "float_F_%u", align);
			float_F[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
			/* set the specified alignment */
			set_type_alignment_bytes(tp, align);
		}
		return float_F[align];
	} else if (mode == mode_D) {
		static ir_type *float_D[16] = {NULL, };

		if (float_D[align] == NULL) {
			snprintf(buf, sizeof(buf), "float_D_%u", align);
			float_D[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
			/* set the specified alignment */
			set_type_alignment_bytes(tp, align);
		}
		return float_D[align];
	} else {
		static ir_type *float_E[16] = {NULL, };

		if (float_E[align] == NULL) {
			snprintf(buf, sizeof(buf), "float_E_%u", align);
			float_E[align] = tp = new_type_primitive(new_id_from_str(buf), mode);
			/* set the specified alignment */
			set_type_alignment_bytes(tp, align);
		}
		return float_E[align];
	}
}

/**
 * Create a float[2] array type for the given atomic type.
 *
 * @param tp  the atomic type
 */
static ir_type *ia32_create_float_array(ir_type *tp) {
	char     buf[32];
	ir_mode  *mode = get_type_mode(tp);
	unsigned align = get_type_alignment_bytes(tp);
	ir_type  *arr;

	assert(align <= 16);

	if (mode == mode_F) {
		static ir_type *float_F[16] = {NULL, };

		if (float_F[align] != NULL)
			return float_F[align];
		snprintf(buf, sizeof(buf), "arr_float_F_%u", align);
		arr = float_F[align] = new_type_array(new_id_from_str(buf), 1, tp);
	} else if (mode == mode_D) {
		static ir_type *float_D[16] = {NULL, };

		if (float_D[align] != NULL)
			return float_D[align];
		snprintf(buf, sizeof(buf), "arr_float_D_%u", align);
		arr = float_D[align] = new_type_array(new_id_from_str(buf), 1, tp);
	} else {
		static ir_type *float_E[16] = {NULL, };

		if (float_E[align] != NULL)
			return float_E[align];
		snprintf(buf, sizeof(buf), "arr_float_E_%u", align);
		arr = float_E[align] = new_type_array(new_id_from_str(buf), 1, tp);
	}
	set_type_alignment_bytes(arr, align);
	set_type_size_bytes(arr, 2 * get_type_size_bytes(tp));
	set_type_state(arr, layout_fixed);
	return arr;
}

473
/* Generates an entity for a known FP const (used for FP Neg + Abs) */
Christoph Mallon's avatar
Christoph Mallon committed
474
475
ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
{
476
477
478
	static const struct {
		const char *ent_name;
		const char *cnst_str;
479
		char mode;
Michael Beck's avatar
Michael Beck committed
480
		unsigned char align;
481
	} names [ia32_known_const_max] = {
Michael Beck's avatar
Michael Beck committed
482
483
484
485
486
		{ ENT_SFP_SIGN, SFP_SIGN,   0, 16 }, /* ia32_SSIGN */
		{ ENT_DFP_SIGN, DFP_SIGN,   1, 16 }, /* ia32_DSIGN */
		{ ENT_SFP_ABS,  SFP_ABS,    0, 16 }, /* ia32_SABS */
		{ ENT_DFP_ABS,  DFP_ABS,    1, 16 }, /* ia32_DABS */
		{ ENT_ULL_BIAS, ULL_BIAS,   2, 4 }   /* ia32_ULLBIAS */
487
	};
488
	static ir_entity *ent_cache[ia32_known_const_max];
489

Michael Beck's avatar
Michael Beck committed
490
	const char    *ent_name, *cnst_str;
491
	ir_type       *tp;
492
	ir_entity     *ent;
493
	tarval        *tv;
Michael Beck's avatar
BugFix:    
Michael Beck committed
494
	ir_mode       *mode;
495

Christian Würdig's avatar
Christian Würdig committed
496
	ent_name = names[kct].ent_name;
497
498
	if (! ent_cache[kct]) {
		cnst_str = names[kct].cnst_str;
499

500
501
502
		switch (names[kct].mode) {
		case 0:  mode = mode_Iu; break;
		case 1:  mode = mode_Lu; break;
Michael Beck's avatar
Michael Beck committed
503
		default: mode = mode_F;  break;
504
		}
505
		tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
Michael Beck's avatar
Michael Beck committed
506
		tp  = ia32_create_float_type(mode, names[kct].align);
507

Michael Beck's avatar
Michael Beck committed
508
509
		if (kct == ia32_ULLBIAS)
			tp = ia32_create_float_array(tp);
510
511
512
513
514
515
516
		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);

517
518
519
520
521
522
523
		if (kct == ia32_ULLBIAS) {
			ir_initializer_t *initializer = create_initializer_compound(2);

			set_initializer_compound_value(initializer, 0,
				create_initializer_tarval(get_tarval_null(mode)));
			set_initializer_compound_value(initializer, 1,
				create_initializer_tarval(tv));
524

525
526
527
528
			set_entity_initializer(ent, initializer);
		} else {
			set_entity_initializer(ent, create_initializer_tarval(tv));
		}
529

530
531
		/* cache the entry */
		ent_cache[kct] = ent;
532
	}
533

534
	return ent_cache[kct];
535
536
}

537
538
539
540
541
542
543
/**
 * return true if the node is a Proj(Load) and could be used in source address
 * mode for another node. Will return only true if the @p other node is not
 * dependent on the memory of the Load (for binary operations use the other
 * input here, for unary operations use NULL).
 */
static int ia32_use_source_address_mode(ir_node *block, ir_node *node,
544
                                        ir_node *other, ir_node *other2, match_flags_t flags)
545
546
547
548
{
	ir_node *load;
	long     pn;

549
	/* float constants are always available */
Michael Beck's avatar
Michael Beck committed
550
551
552
553
554
555
556
557
558
559
560
	if (is_Const(node)) {
		ir_mode *mode = get_irn_mode(node);
		if (mode_is_float(mode)) {
			if (ia32_cg_config.use_sse2) {
				if (is_simple_sse_Const(node))
					return 0;
			} else {
				if (is_simple_x87_Const(node))
					return 0;
			}
			if (get_irn_n_edges(node) > 1)
561
				return 0;
Michael Beck's avatar
Michael Beck committed
562
			return 1;
563
		}
564
565
	}

Michael Beck's avatar
Michael Beck committed
566
	if (!is_Proj(node))
567
568
569
		return 0;
	load = get_Proj_pred(node);
	pn   = get_Proj_proj(node);
Michael Beck's avatar
Michael Beck committed
570
	if (!is_Load(load) || pn != pn_Load_res)
571
		return 0;
Michael Beck's avatar
Michael Beck committed
572
	if (get_nodes_block(load) != block)
573
574
		return 0;
	/* we only use address mode if we're the only user of the load */
575
	if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
576
		return 0;
577
578
579
	/* in some edge cases with address mode we might reach the load normally
	 * and through some AM sequence, if it is already materialized then we
	 * can't create an AM node from it */
Michael Beck's avatar
Michael Beck committed
580
	if (be_is_transformed(node))
581
		return 0;
582
583

	/* don't do AM if other node inputs depend on the load (via mem-proj) */
584
	if (other != NULL && prevents_AM(block, load, other))
585
		return 0;
586
587

	if (other2 != NULL && prevents_AM(block, load, other2))
588
		return 0;
589
590
591
592
593
594
595
596
597

	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;
598
	ir_node        *am_node;
599
600
601
	ia32_op_type_t  op_type;
	ir_node        *new_op1;
	ir_node        *new_op2;
602
	op_pin_state    pinned;
Matthias Braun's avatar
Matthias Braun committed
603
604
	unsigned        commutative  : 1;
	unsigned        ins_permuted : 1;
605
606
};

Matthias Braun's avatar
Matthias Braun committed
607
608
609
610
static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
{
	/* construct load address */
	memset(addr, 0, sizeof(addr[0]));
Christoph Mallon's avatar
Christoph Mallon committed
611
	ia32_create_address_mode(addr, ptr, 0);
Matthias Braun's avatar
Matthias Braun committed
612

613
614
	addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_GP;
	addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
Matthias Braun's avatar
Matthias Braun committed
615
616
617
	addr->mem   = be_transform_node(mem);
}

618
619
static void build_address(ia32_address_mode_t *am, ir_node *node,
                          ia32_create_am_flags_t flags)
620
{
621
	ia32_address_t *addr = &am->addr;
622
623
624
625
	ir_node        *load;
	ir_node        *ptr;
	ir_node        *mem;
	ir_node        *new_mem;
626

627
	if (is_Const(node)) {
628
		ir_entity *entity  = create_float_const_entity(node);
629
630
631
		addr->base         = noreg_GP;
		addr->index        = noreg_GP;
		addr->mem          = nomem;
632
633
		addr->symconst_ent = entity;
		addr->use_frame    = 1;
634
		am->ls_mode        = get_type_mode(get_entity_type(entity));
635
		am->pinned         = op_pin_state_floats;
636
637
638
639
640
641
642
		return;
	}

	load         = get_Proj_pred(node);
	ptr          = get_Load_ptr(load);
	mem          = get_Load_mem(load);
	new_mem      = be_transform_node(mem);
643
	am->pinned   = get_irn_pinned(load);
644
645
	am->ls_mode  = get_Load_mode(load);
	am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
646
	am->am_node  = node;
647
648

	/* construct load address */
649
	ia32_create_address_mode(addr, ptr, flags);
650

651
652
	addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_GP;
	addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
653
	addr->mem   = new_mem;
654
655
}

656
static void set_address(ir_node *node, const ia32_address_t *addr)
657
658
659
660
{
	set_ia32_am_scale(node, addr->scale);
	set_ia32_am_sc(node, addr->symconst_ent);
	set_ia32_am_offs_int(node, addr->offset);
Christoph Mallon's avatar
Christoph Mallon committed
661
	if (addr->symconst_sign)
662
		set_ia32_am_sc_sign(node);
Christoph Mallon's avatar
Christoph Mallon committed
663
	if (addr->use_frame)
664
665
		set_ia32_use_frame(node);
	set_ia32_frame_ent(node, addr->frame_entity);
666
667
}

Michael Beck's avatar
Michael Beck committed
668
669
670
/**
 * Apply attributes of a given address mode to a node.
 */
671
static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
672
673
{
	set_address(node, &am->addr);
674

675
676
	set_ia32_op_type(node, am->op_type);
	set_ia32_ls_mode(node, am->ls_mode);
Michael Beck's avatar
Michael Beck committed
677
	if (am->pinned == op_pin_state_pinned) {
678
679
680
		/* beware: some nodes are already pinned and did not allow to change the state */
		if (get_irn_pinned(node) != op_pin_state_pinned)
			set_irn_pinned(node, op_pin_state_pinned);
681
	}
Michael Beck's avatar
Michael Beck committed
682
	if (am->commutative)
683
684
		set_ia32_commutative(node);
}
685

686
687
688
689
690
691
692
693
/**
 * Check, if a given node is a Down-Conv, ie. a integer Conv
 * from a mode with a mode with more bits to a mode with lesser bits.
 * Moreover, we return only true if the node has not more than 1 user.
 *
 * @param node   the node
 * @return non-zero if node is a Down-Conv
 */
694
695
696
697
698
static int is_downconv(const ir_node *node)
{
	ir_mode *src_mode;
	ir_mode *dest_mode;

Christoph Mallon's avatar
Christoph Mallon committed
699
	if (!is_Conv(node))
700
701
702
703
704
		return 0;

	/* we only want to skip the conv when we're the only user
	 * (not optimal but for now...)
	 */
Christoph Mallon's avatar
Christoph Mallon committed
705
	if (get_irn_n_edges(node) > 1)
706
707
708
709
		return 0;

	src_mode  = get_irn_mode(get_Conv_op(node));
	dest_mode = get_irn_mode(node);
710
711
712
713
	return
		ia32_mode_needs_gp_reg(src_mode)  &&
		ia32_mode_needs_gp_reg(dest_mode) &&
		get_mode_size_bits(dest_mode) <= get_mode_size_bits(src_mode);
714
715
}

716
/* Skip all Down-Conv's on a given node and return the resulting node. */
Christoph Mallon's avatar
Christoph Mallon committed
717
718
ir_node *ia32_skip_downconv(ir_node *node)
{
719
720
721
722
723
724
	while (is_downconv(node))
		node = get_Conv_op(node);

	return node;
}

725
726
727
728
729
730
static ir_node *create_upconv(ir_node *node, ir_node *orig_node)
{
	ir_mode  *mode = get_irn_mode(node);
	ir_node  *block;
	ir_mode  *tgt_mode;
	dbg_info *dbgi;
731

Christoph Mallon's avatar
Christoph Mallon committed
732
	if (mode_is_signed(mode)) {
733
734
735
736
737
738
739
740
741
		tgt_mode = mode_Is;
	} else {
		tgt_mode = mode_Iu;
	}
	block = get_nodes_block(node);
	dbgi  = get_irn_dbg_info(node);

	return create_I2I_Conv(mode, tgt_mode, dbgi, block, node, orig_node);
}
742

743
744
745
746
747
748
749
750
751
752
753
/**
 * matches operands of a node into ia32 addressing/operand modes. This covers
 * usage of source address mode, immediates, operations with non 32-bit modes,
 * ...
 * The resulting data is filled into the @p am struct. block is the block
 * of the node whose arguments are matched. op1, op2 are the first and second
 * input that are matched (op1 may be NULL). other_op is another unrelated
 * input that is not matched! but which is needed sometimes to check if AM
 * for op1/op2 is legal.
 * @p flags describes the supported modes of the operation in detail.
 */
754
static void match_arguments(ia32_address_mode_t *am, ir_node *block,
755
756
                            ir_node *op1, ir_node *op2, ir_node *other_op,
                            match_flags_t flags)
757
{
Michael Beck's avatar
Michael Beck committed
758
759
760
	ia32_address_t *addr      = &am->addr;
	ir_mode        *mode      = get_irn_mode(op2);
	int             mode_bits = get_mode_size_bits(mode);
761
	ir_node        *new_op1, *new_op2;
762
	int             use_am;
Michael Beck's avatar
Michael Beck committed
763
	unsigned        commutative;
764
	int             use_am_and_immediates;
765
	int             use_immediate;
766
767
768

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

769
770
	commutative           = (flags & match_commutative) != 0;
	use_am_and_immediates = (flags & match_am_and_immediates) != 0;
771
772
773
	use_am                = (flags & match_am) != 0;
	use_immediate         = (flags & match_immediate) != 0;
	assert(!use_am_and_immediates || use_immediate);
774
775
776

	assert(op2 != NULL);
	assert(!commutative || op1 != NULL);
777
778
	assert(use_am || !(flags & match_8bit_am));
	assert(use_am || !(flags & match_16bit_am));
779

780
	if ((mode_bits ==  8 && !(flags & match_8bit_am)) ||
781
	    (mode_bits == 16 && !(flags & match_16bit_am))) {
782
		use_am = 0;
783
	}
784

785
786
	/* we can simply skip downconvs for mode neutral nodes: the upper bits
	 * can be random for these operations */
787
	if (flags & match_mode_neutral) {
788
		op2 = ia32_skip_downconv(op2);
789
		if (op1 != NULL) {
790
791
792
793
			op1 = ia32_skip_downconv(op1);
		}
	}

794
795
796
	/* match immediates. firm nodes are normalized: constants are always on the
	 * op2 input */
	new_op2 = NULL;
797
	if (!(flags & match_try_am) && use_immediate) {
798
		new_op2 = try_create_Immediate(op2, 0);
799
	}
800

801
	if (new_op2 == NULL &&
802
	    use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
803
		build_address(am, op2, 0);
804
		new_op1     = (op1 == NULL ? NULL : be_transform_node(op1));
Michael Beck's avatar
Michael Beck committed
805
		if (mode_is_float(mode)) {
806
807
			new_op2 = ia32_new_NoReg_vfp(env_cg);
		} else {
808
			new_op2 = noreg_GP;
809
		}
810
		am->op_type = ia32_AddrModeS;
811
812
	} else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
		       use_am &&
813
		       ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
814
		ir_node *noreg;
815
		build_address(am, op1, 0);
816

817
		if (mode_is_float(mode)) {
818
819
			noreg = ia32_new_NoReg_vfp(env_cg);
		} else {
820
			noreg = noreg_GP;
821
822
		}

Michael Beck's avatar
Michael Beck committed
823
		if (new_op2 != NULL) {
824
			new_op1 = noreg;
825
826
		} else {
			new_op1 = be_transform_node(op2);
827
			new_op2 = noreg;
828
			am->ins_permuted = 1;
829
830
		}
		am->op_type = ia32_AddrModeS;
831
	} else {
Christoph Mallon's avatar
Christoph Mallon committed
832
833
		am->op_type = ia32_Normal;

Michael Beck's avatar
Michael Beck committed
834
		if (flags & match_try_am) {
835
836
837
838
839
			am->new_op1 = NULL;
			am->new_op2 = NULL;
			return;
		}

840
		new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
Michael Beck's avatar
Michael Beck committed
841
		if (new_op2 == NULL)
842
			new_op2 = be_transform_node(op2);
Christoph Mallon's avatar
Christoph Mallon committed
843
844
		am->ls_mode =
			(flags & match_mode_neutral ? mode_Iu : get_irn_mode(op2));
845
	}
Michael Beck's avatar
Michael Beck committed
846
	if (addr->base == NULL)
847
		addr->base = noreg_GP;
Michael Beck's avatar
Michael Beck committed
848
	if (addr->index == NULL)
849
		addr->index = noreg_GP;
Michael Beck's avatar
Michael Beck committed
850
	if (addr->mem == NULL)
851
		addr->mem = nomem;
852
853
854
855
856
857

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

858
859
860
861
862
863
864
865
866
867
/**
 * "Fixes" a node that uses address mode by turning it into mode_T
 * and returning a pn_ia32_res Proj.
 *
 * @param node  the node
 * @param am    its address mode
 *
 * @return a Proj(pn_ia32_res) if a memory address mode is used,
 *         node else
 */
868
869
870
871
static ir_node *fix_mem_proj(ir_node *node, ia32_address_mode_t *am)
{
	ir_mode  *mode;
	ir_node  *load;
872

Michael Beck's avatar
Michael Beck committed
873
	if (am->mem_proj == NULL)
874
875
876
877
878
879
		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);

880
	be_set_transformed_node(load, node);
881

Michael Beck's avatar
Michael Beck committed
882
	if (mode != mode_T) {
883
		set_irn_mode(node, mode_T);
884
		return new_rd_Proj(NULL, get_nodes_block(node), node, mode, pn_ia32_res);
885
886
887
	} else {
		return node;
	}
888
}
889
890
891
892

/**
 * Construct a standard binary operation, set AM and immediate if required.
 *
893
 * @param node  The original node for which the binop is created
894
895
896
897
898
 * @param op1   The first operand
 * @param op2   The second operand
 * @param func  The node constructor function
 * @return The constructed ia32 node.
 */
899
static ir_node *gen_binop(ir_node *node, ir_node *op1, ir_node *op2,
900
                          construct_binop_func *func, match_flags_t flags)
901
{
Michael Beck's avatar
Michael Beck committed
902
903
	dbg_info            *dbgi;
	ir_node             *block, *new_block, *new_node;
904
905
	ia32_address_mode_t  am;
	ia32_address_t      *addr = &am.addr;
906

Michael Beck's avatar
Michael Beck committed
907
	block = get_nodes_block(node);
908
	match_arguments(&am, block, op1, op2, NULL, flags);
909