ia32_transform.c 168 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
2
 * Copyright (C) 1995-2011 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
41
#include "irgmod.h"
#include "ircons.h"
42
#include "irgwalk.h"
43
#include "irprintf.h"
44
#include "debug.h"
45
#include "irdom.h"
46
#include "error.h"
47
#include "array_t.h"
48
#include "heights.h"
49

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

58
#include "bearch_ia32_t.h"
59
#include "ia32_common_transform.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_dbg_stat.h"
64
#include "ia32_optimize.h"
65
#include "ia32_util.h"
66
#include "ia32_address_mode.h"
67
#include "ia32_architecture.h"
68

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

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


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

82
83
84
85
86
#define ENT_SFP_SIGN "C_ia32_sfp_sign"
#define ENT_DFP_SIGN "C_ia32_dfp_sign"
#define ENT_SFP_ABS  "C_ia32_sfp_abs"
#define ENT_DFP_ABS  "C_ia32_dfp_abs"
#define ENT_ULL_BIAS "C_ia32_ull_bias"
87

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

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

93
static ir_node         *initial_fpcw = NULL;
94
int                     ia32_no_pic_adjust;
95

96
97
98
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
99

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

104
105
typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
        ir_node *op1, ir_node *op2);
106

107
108
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);
109

110
111
typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
        ir_node *base, ir_node *index, ir_node *mem);
112

113
114
115
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
116

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

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

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

126
127
128
/* its enough to have those once */
static ir_node *nomem, *noreg_GP;

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

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

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

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

151
152
153
/**
 * returns true if constant can be created with a simple float command
 */
154
static bool is_simple_x87_Const(ir_node *node)
155
{
Matthias Braun's avatar
Matthias Braun committed
156
	ir_tarval *tv = get_Const_tarval(node);
157
	if (tarval_is_null(tv) || tarval_is_one(tv))
158
		return true;
159
160

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

/**
 * returns true if constant can be created with a simple float command
 */
167
static bool is_simple_sse_Const(ir_node *node)
168
{
Matthias Braun's avatar
Matthias Braun committed
169
170
	ir_tarval *tv   = get_Const_tarval(node);
	ir_mode   *mode = get_tarval_mode(tv);
171

172
	if (mode == mode_F)
173
		return true;
174

175
176
177
178
179
	if (tarval_is_null(tv)
#ifdef CONSTRUCT_SSE_CONST
	    || tarval_is_one(tv)
#endif
	   )
180
		return true;
181
#ifdef CONSTRUCT_SSE_CONST
182
183
184
185
186
187
	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)
188
			/* lower 32bit are zero, really a 32bit constant */
189
			return true;
190
	}
191
#endif /* CONSTRUCT_SSE_CONST */
192
	/* TODO: match all the other float constants */
193
	return false;
194
195
}

196
197
198
199
200
201
/**
 * return NoREG or pic_base in case of PIC.
 * This is necessary as base address for newly created symbols
 */
static ir_node *get_symconst_base(void)
{
202
203
204
205
206
	ir_graph *irg = current_ir_graph;

	if (be_get_irg_options(irg)->pic) {
		const arch_env_t *arch_env = be_get_irg_arch_env(irg);
		return arch_env->impl->get_pic_base(irg);
207
208
209
210
211
	}

	return noreg_GP;
}

212
213
214
/**
 * Transforms a Const.
 */
Christoph Mallon's avatar
Christoph Mallon committed
215
216
static ir_node *gen_Const(ir_node *node)
{
217
218
219
220
	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);
221

222
223
	assert(is_Const(node));

224
	if (mode_is_float(mode)) {
225
226
		ir_node   *res   = NULL;
		ir_node   *load;
227
		ir_node   *base;
228
229
		ir_entity *floatent;

230
		if (ia32_cg_config.use_sse2) {
Matthias Braun's avatar
Matthias Braun committed
231
			ir_tarval *tv = get_Const_tarval(node);
232
			if (tarval_is_null(tv)) {
233
				load = new_bd_ia32_xZero(dbgi, block);
234
235
				set_ia32_ls_mode(load, mode);
				res  = load;
236
#ifdef CONSTRUCT_SSE_CONST
237
238
			} else if (tarval_is_one(tv)) {
				int     cnst  = mode == mode_F ? 26 : 55;
239
240
				ir_node *imm1 = ia32_create_Immediate(NULL, 0, cnst);
				ir_node *imm2 = ia32_create_Immediate(NULL, 0, 2);
241
242
				ir_node *pslld, *psrld;

243
				load = new_bd_ia32_xAllOnes(dbgi, block);
244
				set_ia32_ls_mode(load, mode);
245
				pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
246
				set_ia32_ls_mode(pslld, mode);
247
				psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
248
249
				set_ia32_ls_mode(psrld, mode);
				res = psrld;
250
#endif /* CONSTRUCT_SSE_CONST */
251
252
253
254
255
256
			} 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);
257
				ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
258
				load = new_bd_ia32_xMovd(dbgi, block, cnst);
259
260
				set_ia32_ls_mode(load, mode);
				res = load;
261
			} else {
262
#ifdef CONSTRUCT_SSE_CONST
263
264
265
266
267
268
				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) {
269
						ir_node *imm32 = ia32_create_Immediate(NULL, 0, 32);
270
271
272
273
274
275
276
						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);
277
						cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
278
						load = new_bd_ia32_xMovd(dbgi, block, cnst);
279
						set_ia32_ls_mode(load, mode);
280
						psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
281
282
283
284
285
						set_ia32_ls_mode(psllq, mode);
						res = psllq;
						goto end;
					}
				}
286
#endif /* CONSTRUCT_SSE_CONST */
287
				floatent = ia32_create_float_const_entity(node);
288

289
290
291
				base     = get_symconst_base();
				load     = new_bd_ia32_xLoad(dbgi, block, base, noreg_GP, nomem,
				                             mode);
292
293
				set_ia32_op_type(load, ia32_AddrModeS);
				set_ia32_am_sc(load, floatent);
294
				arch_irn_add_flags(load, arch_irn_flags_rematerializable);
295
				res = new_r_Proj(load, mode_xmm, pn_ia32_xLoad_res);
296
297
			}
		} else {
298
			if (is_Const_null(node)) {
299
				load = new_bd_ia32_vfldz(dbgi, block);
300
				res  = load;
301
				set_ia32_ls_mode(load, mode);
302
			} else if (is_Const_one(node)) {
303
				load = new_bd_ia32_vfld1(dbgi, block);
304
				res  = load;
305
				set_ia32_ls_mode(load, mode);
306
			} else {
307
				ir_mode *ls_mode;
308
				ir_node *base;
309

310
				floatent = ia32_create_float_const_entity(node);
311
312
313
				/* create_float_const_ent is smart and sometimes creates
				   smaller entities */
				ls_mode  = get_type_mode(get_entity_type(floatent));
314
				base     = get_symconst_base();
315
				load     = new_bd_ia32_vfld(dbgi, block, base, noreg_GP, nomem,
316
				                            ls_mode);
317
				set_ia32_op_type(load, ia32_AddrModeS);
318
				set_ia32_am_sc(load, floatent);
319
				arch_irn_add_flags(load, arch_irn_flags_rematerializable);
320
				res = new_r_Proj(load, mode_vfp, pn_ia32_vfld_res);
321
322
			}
		}
323
#ifdef CONSTRUCT_SSE_CONST
324
end:
325
#endif /* CONSTRUCT_SSE_CONST */
326
		SET_IA32_ORIG_NODE(load, node);
327
328

		be_dep_on_frame(load);
329
		return res;
330
	} else { /* non-float mode */
Matthias Braun's avatar
Matthias Braun committed
331
332
333
		ir_node   *cnst;
		ir_tarval *tv = get_Const_tarval(node);
		long       val;
334
335
336

		tv = tarval_convert_to(tv, mode_Iu);

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

343
		cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
344
		SET_IA32_ORIG_NODE(cnst, node);
345

346
		be_dep_on_frame(cnst);
347
348
349
350
351
352
353
		return cnst;
	}
}

/**
 * Transforms a SymConst.
 */
Christoph Mallon's avatar
Christoph Mallon committed
354
355
static ir_node *gen_SymConst(ir_node *node)
{
356
357
	ir_node  *old_block = get_nodes_block(node);
	ir_node  *block = be_transform_node(old_block);
358
359
	dbg_info *dbgi  = get_irn_dbg_info(node);
	ir_mode  *mode  = get_irn_mode(node);
360
361
362
	ir_node  *cnst;

	if (mode_is_float(mode)) {
363
		if (ia32_cg_config.use_sse2)
364
			cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
365
		else
366
			cnst = new_bd_ia32_vfld(dbgi, block, noreg_GP, noreg_GP, nomem, mode_E);
367
		set_ia32_am_sc(cnst, get_SymConst_entity(node));
368
		set_ia32_use_frame(cnst);
369
	} else {
Michael Beck's avatar
Michael Beck committed
370
371
		ir_entity *entity;

Christoph Mallon's avatar
Christoph Mallon committed
372
		if (get_SymConst_kind(node) != symconst_addr_ent) {
373
374
			panic("backend only support symconst_addr_ent (at %+F)", node);
		}
Michael Beck's avatar
Michael Beck committed
375
		entity = get_SymConst_entity(node);
376
		cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0, 0);
377
378
	}

379
	SET_IA32_ORIG_NODE(cnst, node);
380

381
	be_dep_on_frame(cnst);
382
383
384
	return cnst;
}

Michael Beck's avatar
Michael Beck committed
385
386
387
388
389
390
/**
 * 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
 */
391
392
static ir_type *ia32_create_float_type(ir_mode *mode, unsigned align)
{
Michael Beck's avatar
Michael Beck committed
393
394
395
396
397
398
399
400
	ir_type *tp;

	assert(align <= 16);

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

		if (int_Iu[align] == NULL) {
401
			int_Iu[align] = tp = new_type_primitive(mode);
Michael Beck's avatar
Michael Beck committed
402
403
404
405
406
407
408
409
			/* 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) {
410
			int_Lu[align] = tp = new_type_primitive(mode);
Michael Beck's avatar
Michael Beck committed
411
412
413
414
415
416
417
418
			/* 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) {
419
			float_F[align] = tp = new_type_primitive(mode);
Michael Beck's avatar
Michael Beck committed
420
421
422
423
424
425
426
427
			/* 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) {
428
			float_D[align] = tp = new_type_primitive(mode);
Michael Beck's avatar
Michael Beck committed
429
430
431
432
433
434
435
436
			/* 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) {
437
			float_E[align] = tp = new_type_primitive(mode);
Michael Beck's avatar
Michael Beck committed
438
439
440
441
442
443
444
445
446
447
448
449
			/* 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
 */
450
451
static ir_type *ia32_create_float_array(ir_type *tp)
{
Michael Beck's avatar
Michael Beck committed
452
453
454
455
456
457
458
459
460
461
462
	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];
463
		arr = float_F[align] = new_type_array(1, tp);
Michael Beck's avatar
Michael Beck committed
464
465
466
467
468
	} else if (mode == mode_D) {
		static ir_type *float_D[16] = {NULL, };

		if (float_D[align] != NULL)
			return float_D[align];
469
		arr = float_D[align] = new_type_array(1, tp);
Michael Beck's avatar
Michael Beck committed
470
471
472
473
474
	} else {
		static ir_type *float_E[16] = {NULL, };

		if (float_E[align] != NULL)
			return float_E[align];
475
		arr = float_E[align] = new_type_array(1, tp);
Michael Beck's avatar
Michael Beck committed
476
477
478
479
480
481
482
	}
	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;
}

483
/* Generates an entity for a known FP const (used for FP Neg + Abs) */
Christoph Mallon's avatar
Christoph Mallon committed
484
485
ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
{
486
487
488
	static const struct {
		const char *ent_name;
		const char *cnst_str;
489
		char mode;
Michael Beck's avatar
Michael Beck committed
490
		unsigned char align;
491
	} names [ia32_known_const_max] = {
Michael Beck's avatar
Michael Beck committed
492
493
494
495
496
		{ 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 */
497
	};
498
	static ir_entity *ent_cache[ia32_known_const_max];
499

Matthias Braun's avatar
Matthias Braun committed
500
501
502
503
504
	const char *ent_name, *cnst_str;
	ir_type    *tp;
	ir_entity  *ent;
	ir_tarval  *tv;
	ir_mode    *mode;
505

Christian Würdig's avatar
Christian Würdig committed
506
	ent_name = names[kct].ent_name;
507
508
	if (! ent_cache[kct]) {
		cnst_str = names[kct].cnst_str;
509

510
511
512
		switch (names[kct].mode) {
		case 0:  mode = mode_Iu; break;
		case 1:  mode = mode_Lu; break;
Michael Beck's avatar
Michael Beck committed
513
		default: mode = mode_F;  break;
514
		}
515
		tv  = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
Michael Beck's avatar
Michael Beck committed
516
		tp  = ia32_create_float_type(mode, names[kct].align);
517

Michael Beck's avatar
Michael Beck committed
518
519
		if (kct == ia32_ULLBIAS)
			tp = ia32_create_float_array(tp);
520
521
522
		ent = new_entity(get_glob_type(), new_id_from_str(ent_name), tp);

		set_entity_ld_ident(ent, get_entity_ident(ent));
523
		add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
524
		set_entity_visibility(ent, ir_visibility_private);
525

526
527
528
529
		if (kct == ia32_ULLBIAS) {
			ir_initializer_t *initializer = create_initializer_compound(2);

			set_initializer_compound_value(initializer, 0,
530
				create_initializer_tarval(get_mode_null(mode)));
531
532
			set_initializer_compound_value(initializer, 1,
				create_initializer_tarval(tv));
533

534
535
536
537
			set_entity_initializer(ent, initializer);
		} else {
			set_entity_initializer(ent, create_initializer_tarval(tv));
		}
538

539
540
		/* cache the entry */
		ent_cache[kct] = ent;
541
	}
542

543
	return ent_cache[kct];
544
545
}

546
547
548
549
550
551
552
/**
 * 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,
553
                                        ir_node *other, ir_node *other2, match_flags_t flags)
554
555
556
557
{
	ir_node *load;
	long     pn;

558
	/* float constants are always available */
Michael Beck's avatar
Michael Beck committed
559
560
561
562
563
564
565
566
567
568
569
	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)
570
				return 0;
Michael Beck's avatar
Michael Beck committed
571
			return 1;
572
		}
573
574
	}

Michael Beck's avatar
Michael Beck committed
575
	if (!is_Proj(node))
576
577
578
		return 0;
	load = get_Proj_pred(node);
	pn   = get_Proj_proj(node);
Michael Beck's avatar
Michael Beck committed
579
	if (!is_Load(load) || pn != pn_Load_res)
580
		return 0;
Michael Beck's avatar
Michael Beck committed
581
	if (get_nodes_block(load) != block)
582
583
		return 0;
	/* we only use address mode if we're the only user of the load */
584
	if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
585
		return 0;
586
587
588
	/* 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
589
	if (be_is_transformed(node))
590
		return 0;
591
592

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

596
	if (other2 != NULL && ia32_prevents_AM(block, load, other2))
597
		return 0;
598
599
600
601
602
603
604
605
606

	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;
607
	ir_node        *am_node;
608
609
610
	ia32_op_type_t  op_type;
	ir_node        *new_op1;
	ir_node        *new_op2;
611
	op_pin_state    pinned;
Matthias Braun's avatar
Matthias Braun committed
612
613
	unsigned        commutative  : 1;
	unsigned        ins_permuted : 1;
614
615
};

Matthias Braun's avatar
Matthias Braun committed
616
617
618
619
static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
{
	/* construct load address */
	memset(addr, 0, sizeof(addr[0]));
620
	ia32_create_address_mode(addr, ptr, ia32_create_am_normal);
Matthias Braun's avatar
Matthias Braun committed
621

622
623
	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
624
625
626
	addr->mem   = be_transform_node(mem);
}

627
628
static void build_address(ia32_address_mode_t *am, ir_node *node,
                          ia32_create_am_flags_t flags)
629
{
630
	ia32_address_t *addr = &am->addr;
631
632
633
634
	ir_node        *load;
	ir_node        *ptr;
	ir_node        *mem;
	ir_node        *new_mem;
635

636
	/* floating point immediates */
637
	if (is_Const(node)) {
638
		ir_entity *entity  = ia32_create_float_const_entity(node);
639
		addr->base         = get_symconst_base();
640
641
		addr->index        = noreg_GP;
		addr->mem          = nomem;
642
643
		addr->symconst_ent = entity;
		addr->use_frame    = 1;
644
		am->ls_mode        = get_type_mode(get_entity_type(entity));
645
		am->pinned         = op_pin_state_floats;
646
647
648
649
650
651
652
		return;
	}

	load         = get_Proj_pred(node);
	ptr          = get_Load_ptr(load);
	mem          = get_Load_mem(load);
	new_mem      = be_transform_node(mem);
653
	am->pinned   = get_irn_pinned(load);
654
655
	am->ls_mode  = get_Load_mode(load);
	am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
656
	am->am_node  = node;
657
658

	/* construct load address */
659
	ia32_create_address_mode(addr, ptr, flags);
660

661
662
	addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_GP;
	addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
663
	addr->mem   = new_mem;
664
665
}

666
static void set_address(ir_node *node, const ia32_address_t *addr)
667
668
669
670
{
	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
671
	if (addr->symconst_sign)
672
		set_ia32_am_sc_sign(node);
Christoph Mallon's avatar
Christoph Mallon committed
673
	if (addr->use_frame)
674
675
		set_ia32_use_frame(node);
	set_ia32_frame_ent(node, addr->frame_entity);
676
677
}

Michael Beck's avatar
Michael Beck committed
678
679
680
/**
 * Apply attributes of a given address mode to a node.
 */
681
static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
682
683
{
	set_address(node, &am->addr);
684

685
686
	set_ia32_op_type(node, am->op_type);
	set_ia32_ls_mode(node, am->ls_mode);
Michael Beck's avatar
Michael Beck committed
687
	if (am->pinned == op_pin_state_pinned) {
688
689
690
		/* 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);
691
	}
Michael Beck's avatar
Michael Beck committed
692
	if (am->commutative)
693
694
		set_ia32_commutative(node);
}
695

696
697
698
699
700
701
702
703
/**
 * 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
 */
704
705
706
707
708
static int is_downconv(const ir_node *node)
{
	ir_mode *src_mode;
	ir_mode *dest_mode;

Christoph Mallon's avatar
Christoph Mallon committed
709
	if (!is_Conv(node))
710
711
712
		return 0;

	/* we only want to skip the conv when we're the only user
713
714
	 * (because this test is used in the context of address-mode selection
	 *  and we don't want to use address mode for multiple users) */
Christoph Mallon's avatar
Christoph Mallon committed
715
	if (get_irn_n_edges(node) > 1)
716
717
718
719
		return 0;

	src_mode  = get_irn_mode(get_Conv_op(node));
	dest_mode = get_irn_mode(node);
720
721
722
723
	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);
724
725
}

726
/** Skip all Down-Conv's on a given node and return the resulting node. */
Christoph Mallon's avatar
Christoph Mallon committed
727
728
ir_node *ia32_skip_downconv(ir_node *node)
{
729
730
731
732
733
734
	while (is_downconv(node))
		node = get_Conv_op(node);

	return node;
}

735
736
737
738
739
740
741
742
static bool is_sameconv(ir_node *node)
{
	ir_mode *src_mode;
	ir_mode *dest_mode;

	if (!is_Conv(node))
		return 0;

743
744
745
746
747
748
	/* we only want to skip the conv when we're the only user
	 * (because this test is used in the context of address-mode selection
	 *  and we don't want to use address mode for multiple users) */
	if (get_irn_n_edges(node) > 1)
		return 0;

749
750
751
752
753
754
755
756
757
758
759
	src_mode  = get_irn_mode(get_Conv_op(node));
	dest_mode = get_irn_mode(node);
	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);
}

/** Skip all signedness convs */
static ir_node *ia32_skip_sameconv(ir_node *node)
{
Matthias Braun's avatar
Matthias Braun committed
760
	while (is_sameconv(node))
761
762
763
764
765
		node = get_Conv_op(node);

	return node;
}

766
767
768
769
770
771
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;
772

Christoph Mallon's avatar
Christoph Mallon committed
773
	if (mode_is_signed(mode)) {
774
775
776
777
778
779
780
781
782
		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);
}
783

784
785
786
787
788
789
790
791
792
793
794
/**
 * 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.
 */
795
static void match_arguments(ia32_address_mode_t *am, ir_node *block,
796
797
                            ir_node *op1, ir_node *op2, ir_node *other_op,
                            match_flags_t flags)
798
{
Michael Beck's avatar
Michael Beck committed
799
800
801
	ia32_address_t *addr      = &am->addr;
	ir_mode        *mode      = get_irn_mode(op2);
	int             mode_bits = get_mode_size_bits(mode);
802
	ir_node        *new_op1, *new_op2;
803
	int             use_am;
Michael Beck's avatar
Michael Beck committed
804
	unsigned        commutative;
805
	int             use_am_and_immediates;
806
	int             use_immediate;
807
808
809

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

810
811
	commutative           = (flags & match_commutative) != 0;
	use_am_and_immediates = (flags & match_am_and_immediates) != 0;
812
813
814
	use_am                = (flags & match_am) != 0;
	use_immediate         = (flags & match_immediate) != 0;
	assert(!use_am_and_immediates || use_immediate);
815
816
817

	assert(op2 != NULL);
	assert(!commutative || op1 != NULL);
818
819
	assert(use_am || !(flags & match_8bit_am));
	assert(use_am || !(flags & match_16bit_am));
820

821
	if ((mode_bits ==  8 && !(flags & match_8bit_am)) ||
822
	    (mode_bits == 16 && !(flags & match_16bit_am))) {
823
		use_am = 0;
824
	}
825

826
827
	/* we can simply skip downconvs for mode neutral nodes: the upper bits
	 * can be random for these operations */
828
	if (flags & match_mode_neutral) {
829
		op2 = ia32_skip_downconv(op2);
830
		if (op1 != NULL) {
831
832
			op1 = ia32_skip_downconv(op1);
		}
833
834
835
836
837
	} else {
		op2 = ia32_skip_sameconv(op2);
		if (op1 != NULL) {
			op1 = ia32_skip_sameconv(op1);
		}
838
839
	}

840
841
842
	/* match immediates. firm nodes are normalized: constants are always on the
	 * op2 input */
	new_op2 = NULL;
843
	if (!(flags & match_try_am) && use_immediate) {
844
		new_op2 = ia32_try_create_Immediate(op2, 0);
845
	}
846

847
	if (new_op2 == NULL &&
848
	    use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
849
		build_address(am, op2, ia32_create_am_normal);
850
		new_op1     = (op1 == NULL ? NULL : be_transform_node(op1));
Michael Beck's avatar
Michael Beck committed
851
		if (mode_is_float(mode)) {
852
			new_op2 = ia32_new_NoReg_vfp(current_ir_graph);
853
		} else {
854
			new_op2 = noreg_GP;
855
		}
856
		am->op_type = ia32_AddrModeS;
857
858
	} else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
		       use_am &&
859
		       ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
860
		ir_node *noreg;
861
		build_address(am, op1, ia32_create_am_normal);
862

863
		if (mode_is_float(mode)) {
864
			noreg = ia32_new_NoReg_vfp(current_ir_graph);
865
		} else {
866
			noreg = noreg_GP;
867
868
		}

Michael Beck's avatar
Michael Beck committed
869
		if (new_op2 != NULL) {
870
			new_op1 = noreg;
871
872
		} else {
			new_op1 = be_transform_node(op2);
873
			new_op2 = noreg;
874
			am->ins_permuted = 1;
875
876
		}
		am->op_type = ia32_AddrModeS;
877
	} else {
878
		ir_mode *mode;
Christoph Mallon's avatar
Christoph Mallon committed
879
880
		am->op_type = ia32_Normal;

Michael Beck's avatar
Michael Beck committed
881
		if (flags & match_try_am) {
882
883
884
885
886
			am->new_op1 = NULL;
			am->new_op2 = NULL;
			return;
		}

887
888
889
890
891
892
893
894
895
896
897
898
		mode = get_irn_mode(op2);
		if (flags & match_upconv_32 && get_mode_size_bits(mode) != 32) {
			new_op1 = (op1 == NULL ? NULL :