ia32_transform.c 168 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
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_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
#include "ia32_architecture.h"
69

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

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


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

83
84
85
86
87
#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"
88

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

197
198
199
200
201
202
/**
 * 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)
{
203
	if (be_get_irg_options(env_cg->irg)->pic) {
204
205
206
207
208
209
		return arch_code_generator_get_pic_base(env_cg);
	}

	return noreg_GP;
}

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

220
221
	assert(is_Const(node));

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

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

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

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

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

		be_dep_on_frame(load);
327
		return res;
328
	} else { /* non-float mode */
329
330
331
332
333
334
		ir_node *cnst;
		tarval  *tv = get_Const_tarval(node);
		long     val;

		tv = tarval_convert_to(tv, mode_Iu);

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

341
		cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
342
		SET_IA32_ORIG_NODE(cnst, node);
343

344
		be_dep_on_frame(cnst);
345
346
347
348
349
350
351
		return cnst;
	}
}

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

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

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

377
	SET_IA32_ORIG_NODE(cnst, node);
378

379
	be_dep_on_frame(cnst);
380
381
382
	return cnst;
}

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

	assert(align <= 16);

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

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

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

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

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

Michael Beck's avatar
Michael Beck committed
498
	const char    *ent_name, *cnst_str;
499
	ir_type       *tp;
500
	ir_entity     *ent;
501
	tarval        *tv;
Michael Beck's avatar
BugFix:    
Michael Beck committed
502
	ir_mode       *mode;
503

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

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

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

		set_entity_ld_ident(ent, get_entity_ident(ent));
521
		add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
522
		set_entity_visibility(ent, ir_visibility_private);
523

524
525
526
527
		if (kct == ia32_ULLBIAS) {
			ir_initializer_t *initializer = create_initializer_compound(2);

			set_initializer_compound_value(initializer, 0,
528
				create_initializer_tarval(get_mode_null(mode)));
529
530
			set_initializer_compound_value(initializer, 1,
				create_initializer_tarval(tv));
531

532
533
534
535
			set_entity_initializer(ent, initializer);
		} else {
			set_entity_initializer(ent, create_initializer_tarval(tv));
		}
536

537
538
		/* cache the entry */
		ent_cache[kct] = ent;
539
	}
540

541
	return ent_cache[kct];
542
543
}

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

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

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

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

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

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

Matthias Braun's avatar
Matthias Braun committed
614
615
616
617
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
618
	ia32_create_address_mode(addr, ptr, 0);
Matthias Braun's avatar
Matthias Braun committed
619

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

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

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

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

	/* construct load address */
657
	ia32_create_address_mode(addr, ptr, flags);
658

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

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

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

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

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

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

	/* we only want to skip the conv when we're the only user
711
712
	 * (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
713
	if (get_irn_n_edges(node) > 1)
714
715
716
717
		return 0;

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

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

	return node;
}

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

	if (!is_Conv(node))
		return 0;

741
742
743
744
745
746
	/* 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;

747
748
749
750
751
752
753
754
755
756
757
	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
758
	while (is_sameconv(node))
759
760
761
762
763
		node = get_Conv_op(node);

	return node;
}

764
765
766
767
768
769
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;
770

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

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

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

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

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

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

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

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

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

861
		if (mode_is_float(mode)) {
862
863
			noreg = ia32_new_NoReg_vfp(env_cg);
		} else {
864
			noreg = noreg_GP;
865
866
		}

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

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

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