ia32_transform.c 173 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
/*
 * This file is part of libFirm.
3
 * Copyright (C) 2012 University of Karlsruhe.
Christian Würdig's avatar
Christian Würdig committed
4
5
 */

Christian Würdig's avatar
Christian Würdig committed
6
/**
Christian Würdig's avatar
Christian Würdig committed
7
 * @file
8
9
 * @brief       This file implements the IR transformation from firm into
 *              ia32-Firm.
Christian Würdig's avatar
Christian Würdig committed
10
 * @author      Christian Wuerdig, Matthias Braun
Christian Würdig's avatar
Christian Würdig committed
11
 */
Christian Würdig's avatar
Christian Würdig committed
12
#include <limits.h>
13
#include <stdbool.h>
Christian Würdig's avatar
Christian Würdig committed
14

Christian Würdig's avatar
Christian Würdig committed
15
#include "irargs_t.h"
16
17
18
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
Christian Würdig's avatar
Christian Würdig committed
19
20
21
#include "iropt_t.h"
#include "irop_t.h"
#include "irprog_t.h"
Christian Würdig's avatar
Christian Würdig committed
22
#include "iredges_t.h"
23
24
#include "irgmod.h"
#include "ircons.h"
25
#include "irgwalk.h"
26
#include "irprintf.h"
27
#include "debug.h"
28
#include "irdom.h"
29
#include "iropt.h"
30
#include "error.h"
31
#include "array.h"
32
#include "heights.h"
33

34
35
36
37
38
39
#include "benode.h"
#include "besched.h"
#include "beabi.h"
#include "beutil.h"
#include "betranshlp.h"
#include "be_t.h"
Christian Würdig's avatar
Christian Würdig committed
40

41
#include "bearch_ia32_t.h"
42
#include "ia32_common_transform.h"
43
44
45
#include "ia32_nodes_attr.h"
#include "ia32_transform.h"
#include "ia32_new_nodes.h"
Christian Würdig's avatar
Christian Würdig committed
46
#include "ia32_dbg_stat.h"
47
#include "ia32_optimize.h"
48
#include "ia32_architecture.h"
49
#include "x86_address_mode.h"
50

Christian Würdig's avatar
Christian Würdig committed
51
52
#include "gen_ia32_regalloc_if.h"

53
54
55
/* define this to construct SSE constants instead of load them */
#undef CONSTRUCT_SSE_CONST

56
#define mode_fp     (ia32_reg_classes[CLASS_ia32_fp].mode)
57
58
#define mode_xmm    (ia32_reg_classes[CLASS_ia32_xmm].mode)

59
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
60

61
62
63
static ir_node *old_initial_fpcw;
static ir_node *initial_fpcw;
bool            ia32_no_pic_adjust;
64

65
66
67
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
68

69
70
71
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);
72

73
74
typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
        ir_node *op1, ir_node *op2);
75

76
77
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);
78

79
80
typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
        ir_node *base, ir_node *index, ir_node *mem);
81

82
83
84
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
85

86
typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
87

88
static ir_node *create_immediate_or_transform(ir_node *node);
89

90
static ir_node *create_I2I_Conv(ir_mode *src_mode, ir_mode *tgt_mode,
91
92
                                dbg_info *dbgi, ir_node *block,
                                ir_node *op, ir_node *orig_node);
93

94
/* its enough to have those once */
95
96
static ir_node *nomem;
static ir_node *noreg_GP;
97

98
99
100
101
/** a list to postprocess all calls */
static ir_node **call_list;
static ir_type **call_types;

Michael Beck's avatar
Michael Beck committed
102
/** Return non-zero is a node represents the 0 constant. */
Christoph Mallon's avatar
Christoph Mallon committed
103
104
static bool is_Const_0(ir_node *node)
{
105
	return is_Const(node) && is_Const_null(node);
106
107
}

Michael Beck's avatar
Michael Beck committed
108
/** Return non-zero is a node represents the 1 constant. */
Christoph Mallon's avatar
Christoph Mallon committed
109
110
static bool is_Const_1(ir_node *node)
{
111
	return is_Const(node) && is_Const_one(node);
112
113
}

Michael Beck's avatar
Michael Beck committed
114
/** Return non-zero is a node represents the -1 constant. */
Christoph Mallon's avatar
Christoph Mallon committed
115
116
static bool is_Const_Minus_1(ir_node *node)
{
117
	return is_Const(node) && is_Const_all_one(node);
118
119
}

120
121
122
/**
 * returns true if constant can be created with a simple float command
 */
123
static bool is_simple_x87_Const(ir_node *node)
124
{
Matthias Braun's avatar
Matthias Braun committed
125
	ir_tarval *tv = get_Const_tarval(node);
126
	if (tarval_is_null(tv) || tarval_is_one(tv))
127
		return true;
128
129

	/* TODO: match all the other float constants */
130
	return false;
131
132
133
134
135
}

/**
 * returns true if constant can be created with a simple float command
 */
136
static bool is_simple_sse_Const(ir_node *node)
137
{
Matthias Braun's avatar
Matthias Braun committed
138
139
	ir_tarval *tv   = get_Const_tarval(node);
	ir_mode   *mode = get_tarval_mode(tv);
140

141
	if (mode == ia32_mode_float32)
142
		return true;
143

144
145
146
147
148
	if (tarval_is_null(tv)
#ifdef CONSTRUCT_SSE_CONST
	    || tarval_is_one(tv)
#endif
	   )
149
		return true;
150
#ifdef CONSTRUCT_SSE_CONST
151
	if (mode == ia32_mode_float64) {
152
153
154
155
156
		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)
157
			/* lower 32bit are zero, really a 32bit constant */
158
			return true;
159
	}
160
#endif /* CONSTRUCT_SSE_CONST */
161
	/* TODO: match all the other float constants */
162
	return false;
163
164
}

165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
ir_node *ia32_get_pic_base(ir_graph *irg)
{
	ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
	ir_node         *block;
	ir_node         *get_eip = irg_data->get_eip;
	if (get_eip != NULL)
		return get_eip;

	block             = get_irg_start_block(irg);
	get_eip           = new_bd_ia32_GetEIP(NULL, block);
	irg_data->get_eip = get_eip;

	return get_eip;
}

180
181
182
183
/**
 * return NoREG or pic_base in case of PIC.
 * This is necessary as base address for newly created symbols
 */
184
static ir_node *get_global_base(void)
185
{
186
187
	ir_graph *irg = current_ir_graph;

188
	if (be_options.pic) {
189
		return ia32_get_pic_base(irg);
190
191
192
193
194
	}

	return noreg_GP;
}

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

	if (mode_is_float(mode)) {
207
208
209
210
211
		ir_graph         *irg      = get_irn_irg(node);
		const arch_env_t *arch_env = be_get_irg_arch_env(irg);
		ia32_isa_t       *isa      = (ia32_isa_t*) arch_env;
		ir_node          *res      = NULL;
		ir_node          *load;
212

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

225
				load = new_bd_ia32_xAllOnes(dbgi, block);
226
				set_ia32_ls_mode(load, mode);
227
				pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
228
				set_ia32_ls_mode(pslld, mode);
229
				psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
230
231
				set_ia32_ls_mode(psrld, mode);
				res = psrld;
232
#endif /* CONSTRUCT_SSE_CONST */
233
			} else if (mode == ia32_mode_float32) {
234
235
236
237
238
				/* 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);
239
				ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
240
				load = new_bd_ia32_xMovd(dbgi, block, cnst);
241
242
				set_ia32_ls_mode(load, mode);
				res = load;
243
			} else {
244
#ifdef CONSTRUCT_SSE_CONST
245
				if (mode == ia32_mode_float64) {
246
247
248
249
250
					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) {
251
						ir_node *imm32 = ia32_create_Immediate(irg, NULL, 0, 32);
252
253
254
255
256
257
258
						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);
259
						cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
260
						load = new_bd_ia32_xMovd(dbgi, block, cnst);
261
						set_ia32_ls_mode(load, mode);
262
						psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
263
264
265
266
267
						set_ia32_ls_mode(psllq, mode);
						res = psllq;
						goto end;
					}
				}
268
#endif /* CONSTRUCT_SSE_CONST */
269
270
				ir_entity *floatent
					= ia32_create_float_const_entity(isa, tv, NULL);
271

272
				ir_node *base = get_global_base();
273
274
				load = new_bd_ia32_xLoad(dbgi, block, base, noreg_GP, nomem,
				                         mode);
275
				set_ia32_op_type(load, ia32_AddrModeS);
276
				set_ia32_am_ent(load, floatent);
277
				arch_add_irn_flags(load, arch_irn_flag_rematerializable);
278
				res = new_r_Proj(load, mode_xmm, pn_ia32_xLoad_res);
279
280
			}
		} else {
281
			if (tarval_is_null(tv)) {
282
				load = new_bd_ia32_fldz(dbgi, block);
283
				res  = load;
284
			} else if (tarval_is_one(tv)) {
285
				load = new_bd_ia32_fld1(dbgi, block);
286
				res  = load;
287
			} else {
288
289
				ir_entity *floatent
					= ia32_create_float_const_entity(isa, tv, NULL);
290
291
				/* create_float_const_ent is smart and sometimes creates
				   smaller entities */
292
				ir_mode *ls_mode  = get_type_mode(get_entity_type(floatent));
293
				ir_node *base     = get_global_base();
294
295
				load = new_bd_ia32_fld(dbgi, block, base, noreg_GP, nomem,
				                       ls_mode);
296
				set_ia32_op_type(load, ia32_AddrModeS);
297
				set_ia32_am_ent(load, floatent);
298
				arch_add_irn_flags(load, arch_irn_flag_rematerializable);
299
				res = new_r_Proj(load, mode_fp, pn_ia32_fld_res);
300
301
			}
		}
302
#ifdef CONSTRUCT_SSE_CONST
303
end:
304
#endif /* CONSTRUCT_SSE_CONST */
305
		SET_IA32_ORIG_NODE(load, node);
306
		return res;
307
	} else { /* non-float mode */
308
		tv = tarval_convert_to(tv, ia32_mode_gp);
309

310
		if (tv == get_tarval_bad() || tv == get_tarval_unknown() ||
311
		    tv == NULL) {
312
313
			panic("couldn't convert constant tarval (%+F)", node);
		}
314
		long val = get_tarval_long(tv);
315

316
		ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, val);
317
		SET_IA32_ORIG_NODE(cnst, node);
318
319
320
321
322
323

		return cnst;
	}
}

/**
324
 * Transforms an Address.
325
 */
326
static ir_node *gen_Address(ir_node *node)
Christoph Mallon's avatar
Christoph Mallon committed
327
{
328
	ir_node  *old_block = get_nodes_block(node);
329
330
331
	ir_node  *block     = be_transform_node(old_block);
	dbg_info *dbgi      = get_irn_dbg_info(node);
	ir_mode  *mode      = get_irn_mode(node);
332

333
	if (!ia32_mode_needs_gp_reg(mode))
334
		panic("unexpected mode for Address");
335

336
	ir_entity *entity = get_Address_entity(node);
337
	ir_node   *cnst;
338
	if (is_tls_entity(entity)) {
339
340
		ir_node *tls_base = new_bd_ia32_LdTls(NULL, block);
		ir_node *lea      = new_bd_ia32_Lea(dbgi, block, tls_base, noreg_GP);
341
		set_ia32_am_ent(lea, entity);
342
		cnst = lea;
343
	} else {
344
		cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0);
345
	}
346
	SET_IA32_ORIG_NODE(cnst, node);
347
348
349
	return cnst;
}

350
static ir_type *make_array_type(ir_type *tp)
351
{
352
353
	unsigned alignment = get_type_alignment_bytes(tp);
	unsigned size      = get_type_size_bytes(tp);
354
	ir_type *res       = new_type_array(1, tp);
355
356
357
358
359
360
361
	set_type_alignment_bytes(res, alignment);
	set_array_bounds_int(res, 0, 0, 2);
	if (alignment > size)
		size = alignment;
	set_type_size_bytes(res, 2 * size);
	set_type_state(res, layout_fixed);
	return res;
Michael Beck's avatar
Michael Beck committed
362
363
364
365
366
367
368
}

/**
 * Create a float[2] array type for the given atomic type.
 *
 * @param tp  the atomic type
 */
369
370
static ir_type *ia32_create_float_array(ir_type *tp)
{
371
372
	ir_mode *mode = get_type_mode(tp);
	ir_type *arr;
Michael Beck's avatar
Michael Beck committed
373

374
	if (mode == ia32_mode_float32) {
375
		static ir_type *float_F;
Michael Beck's avatar
Michael Beck committed
376

377
378
379
		arr = float_F;
		if (arr == NULL)
			arr = float_F = make_array_type(tp);
380
	} else if (mode == ia32_mode_float64) {
381
		static ir_type *float_D;
Michael Beck's avatar
Michael Beck committed
382

383
384
385
		arr = float_D;
		if (arr == NULL)
			arr = float_D = make_array_type(tp);
Michael Beck's avatar
Michael Beck committed
386
	} else {
387
		static ir_type *float_E;
Michael Beck's avatar
Michael Beck committed
388

389
390
391
		arr = float_E;
		if (arr == NULL)
			arr = float_E = make_array_type(tp);
Michael Beck's avatar
Michael Beck committed
392
393
394
395
	}
	return arr;
}

396
/* Generates an entity for a known FP const (used for FP Neg + Abs) */
Christoph Mallon's avatar
Christoph Mallon committed
397
398
ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
{
399
	static const struct {
400
		const char *name;
401
		const char *cnst_str;
402
		char        mode;
403
	} names [ia32_known_const_max] = {
404
405
406
407
408
		{ "C_sfp_sign", "0x80000000",          0 },
		{ "C_dfp_sign", "0x8000000000000000",  1 },
		{ "C_sfp_abs",  "0x7FFFFFFF",          0 },
		{ "C_dfp_abs",  "0x7FFFFFFFFFFFFFFF",  1 },
		{ "C_ull_bias", "0x10000000000000000", 2 }
409
	};
410
	static ir_entity *ent_cache[ia32_known_const_max];
411

412
	ir_entity *ent = ent_cache[kct];
413

414
415
416
417
418
419
420
	if (ent == NULL) {
		ir_graph         *irg      = current_ir_graph;
		const arch_env_t *arch_env = be_get_irg_arch_env(irg);
		ia32_isa_t       *isa      = (ia32_isa_t*) arch_env;
		const char       *cnst_str = names[kct].cnst_str;
		ident            *name     = new_id_from_str(names[kct].name);
		ir_mode          *mode;
421
		switch (names[kct].mode) {
422
		case 0:  mode = ia32_mode_gp; break;
423
		case 1:  mode = mode_Lu; break;
424
		case 2:  mode = ia32_mode_float32;  break;
425
		default: panic("internal compiler error");
426
		}
427
		ir_tarval *tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
428

429
		if (kct == ia32_ULLBIAS) {
430
			ir_type *type  = ia32_get_prim_type(ia32_mode_float32);
431
			ir_type *atype = ia32_create_float_array(type);
432

433
			ent = new_entity(get_glob_type(), name, atype);
434

435
436
437
			set_entity_ld_ident(ent, name);
			set_entity_visibility(ent, ir_visibility_private);
			add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
438

439
			ir_initializer_t *initializer = create_initializer_compound(2);
440
			set_initializer_compound_value(initializer, 0,
441
				create_initializer_tarval(get_mode_null(mode)));
442
443
444
445
			set_initializer_compound_value(initializer, 1,
				create_initializer_tarval(tv));
			set_entity_initializer(ent, initializer);
		} else {
446
			ent = ia32_create_float_const_entity(isa, tv, name);
447
		}
448
449
		/* cache the entry */
		ent_cache[kct] = ent;
450
	}
451

452
	return ent_cache[kct];
453
454
}

455
456
457
458
459
460
/**
 * 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).
 */
461
462
463
static bool ia32_use_source_address_mode(ir_node *block, ir_node *node,
                                         ir_node *other, ir_node *other2,
                                         match_flags_t flags)
464
{
465
	/* float constants are always available */
Michael Beck's avatar
Michael Beck committed
466
	if (is_Const(node)) {
467
		ir_mode *mode = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
468
		if (mode_is_float(mode)) {
469
			ir_tarval *tv = get_Const_tarval(node);
470
			if (!tarval_ieee754_can_conv_lossless(tv, ia32_mode_float64))
471
				return false;
Michael Beck's avatar
Michael Beck committed
472
473
			if (ia32_cg_config.use_sse2) {
				if (is_simple_sse_Const(node))
474
					return false;
Michael Beck's avatar
Michael Beck committed
475
476
			} else {
				if (is_simple_x87_Const(node))
477
					return false;
Michael Beck's avatar
Michael Beck committed
478
479
			}
			if (get_irn_n_edges(node) > 1)
480
481
				return false;
			return true;
482
		}
483
		return false;
484
485
	}

Michael Beck's avatar
Michael Beck committed
486
	if (!is_Proj(node))
487
488
		return false;
	ir_node *load = get_Proj_pred(node);
489
	if (!is_Load(load))
490
		return false;
491
	assert(get_Proj_proj(node) == pn_Load_res);
Michael Beck's avatar
Michael Beck committed
492
	if (get_nodes_block(load) != block)
493
494
		return false;
	ir_mode *mode = get_irn_mode(node);
495
496
	/* we can't fold mode_E AM */
	if (mode == ia32_mode_E)
497
		return false;
498
	/* we only use address mode if we're the only user of the load */
499
	if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
500
		return false;
501
502
503
	/* 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
504
	if (be_is_transformed(node))
505
		return false;
506
507

	/* don't do AM if other node inputs depend on the load (via mem-proj) */
508
	if (other != NULL && ia32_prevents_AM(block, load, other))
509
		return false;
510

511
	if (other2 != NULL && ia32_prevents_AM(block, load, other2))
512
		return false;
513

514
	return true;
515
516
517
518
}

typedef struct ia32_address_mode_t ia32_address_mode_t;
struct ia32_address_mode_t {
519
	x86_address_t   addr;
520
521
	ir_mode        *ls_mode;
	ir_node        *mem_proj;
522
	ir_node        *am_node;
523
524
525
	ia32_op_type_t  op_type;
	ir_node        *new_op1;
	ir_node        *new_op2;
526
	op_pin_state    pinned;
Matthias Braun's avatar
Matthias Braun committed
527
528
	unsigned        commutative  : 1;
	unsigned        ins_permuted : 1;
529
530
};

531
static void build_address_ptr(x86_address_t *addr, ir_node *ptr, ir_node *mem)
Matthias Braun's avatar
Matthias Braun committed
532
533
534
{
	/* construct load address */
	memset(addr, 0, sizeof(addr[0]));
535
	x86_create_address_mode(addr, ptr, x86_create_am_normal);
Matthias Braun's avatar
Matthias Braun committed
536

537
538
	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
539
540
541
	addr->mem   = be_transform_node(mem);
}

542
static void build_address(ia32_address_mode_t *am, ir_node *node,
543
                          x86_create_am_flags_t flags)
544
{
545
	x86_address_t *addr = &am->addr;
546

547
	/* floating point immediates */
548
	if (is_Const(node)) {
549
550
551
552
		ir_graph         *irg      = get_irn_irg(node);
		const arch_env_t *arch_env = be_get_irg_arch_env(irg);
		ia32_isa_t       *isa      = (ia32_isa_t*) arch_env;
		ir_tarval        *tv       = get_Const_tarval(node);
553
554
555
556
557
558
559
560
561
		ir_entity *entity = ia32_create_float_const_entity(isa, tv, NULL);
		addr->base        = get_global_base();
		addr->index       = noreg_GP;
		addr->mem         = nomem;
		addr->entity      = entity;
		addr->tls_segment = false;
		addr->use_frame   = 1;
		am->ls_mode       = get_type_mode(get_entity_type(entity));
		am->pinned        = op_pin_state_floats;
562
563
564
		return;
	}

565
566
567
568
569
570
571
572
	ir_node *load    = get_Proj_pred(node);
	ir_node *ptr     = get_Load_ptr(load);
	ir_node *mem     = get_Load_mem(load);
	ir_node *new_mem = be_transform_node(mem);
	am->pinned       = get_irn_pinned(load);
	am->ls_mode      = get_Load_mode(load);
	am->mem_proj     = be_get_Proj_for_pn(load, pn_Load_M);
	am->am_node      = node;
573
574

	/* construct load address */
575
	x86_create_address_mode(addr, ptr, flags);
576

577
578
	addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_GP;
	addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
579
	addr->mem   = new_mem;
580
581
}

582
static void set_address(ir_node *node, const x86_address_t *addr)
583
584
{
	set_ia32_am_scale(node, addr->scale);
585
	set_ia32_am_ent(node, addr->entity);
586
	set_ia32_am_offs_int(node, addr->offset);
587
	set_ia32_am_tls_segment(node, addr->tls_segment);
Christoph Mallon's avatar
Christoph Mallon committed
588
	if (addr->use_frame)
589
590
		set_ia32_use_frame(node);
	set_ia32_frame_ent(node, addr->frame_entity);
591
592
}

Michael Beck's avatar
Michael Beck committed
593
594
595
/**
 * Apply attributes of a given address mode to a node.
 */
596
static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
597
598
{
	set_address(node, &am->addr);
599

600
601
	set_ia32_op_type(node, am->op_type);
	set_ia32_ls_mode(node, am->ls_mode);
Michael Beck's avatar
Michael Beck committed
602
	if (am->pinned == op_pin_state_pinned) {
603
604
605
		/* 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);
606
	}
Michael Beck's avatar
Michael Beck committed
607
	if (am->commutative)
608
609
		set_ia32_commutative(node);
}
610

611
/**
yb9976's avatar
yb9976 committed
612
 * Check, if a given node is a Down-Conv, i.e. a integer Conv
613
 * from a mode with a mode with more bits to a mode with fewer bits.
614
615
616
617
618
 * 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
 */
619
static bool is_downconv(const ir_node *node)
620
{
Christoph Mallon's avatar
Christoph Mallon committed
621
	if (!is_Conv(node))
622
		return false;
623

624
625
	ir_mode *src_mode  = get_irn_mode(get_Conv_op(node));
	ir_mode *dest_mode = get_irn_mode(node);
626
627
628
629
	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);
630
631
}

632
/** Skip all Down-Conv's on a given node and return the resulting node. */
Christoph Mallon's avatar
Christoph Mallon committed
633
634
ir_node *ia32_skip_downconv(ir_node *node)
{
635
636
637
638
639
640
641
	while (is_downconv(node)) {
		/* 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)
			break;

642
		node = get_Conv_op(node);
643
	}
644
645
646
647

	return node;
}

648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
static bool is_float_downconv(const ir_node *node)
{
	if (!is_Conv(node))
		return false;
	ir_node *pred      = get_Conv_op(node);
	ir_mode *pred_mode = get_irn_mode(pred);
	ir_mode *mode      = get_irn_mode(node);
	return mode_is_float(pred_mode)
	    && get_mode_size_bits(mode) <= get_mode_size_bits(pred_mode);
}

static ir_node *ia32_skip_float_downconv(ir_node *node)
{
	while (is_float_downconv(node)) {
		node = get_Conv_op(node);
	}
	return node;
}

667
668
669
static bool is_sameconv(ir_node *node)
{
	if (!is_Conv(node))
670
		return false;
671

672
673
674
675
	/* 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)
676
		return false;
677

678
679
	ir_mode *src_mode  = get_irn_mode(get_Conv_op(node));
	ir_mode *dest_mode = get_irn_mode(node);
680
681
682
683
684
685
686
687
688
	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)
{
689
	while (is_sameconv(node)) {
690
		node = get_Conv_op(node);
691
	}
692
693
694
695

	return node;
}

696
static ir_node *transform_sext(ir_node *node, ir_node *orig_node)
697
{
698
699
700
	ir_mode  *mode  = get_irn_mode(node);
	ir_node  *block = get_nodes_block(node);
	dbg_info *dbgi  = get_irn_dbg_info(node);
Christoph Mallon's avatar
Christoph Mallon committed
701
	/* normalize to a signed mode */
702
703
704
705
706
707
	switch (get_mode_size_bits(mode)) {
	case 8:  mode = mode_Bs; break;
	case 16: mode = mode_Hs; break;
	default:
		panic("ia32: invalid mode in sest: %+F", node);
	}
708
	return create_I2I_Conv(mode, ia32_mode_gp, dbgi, block, node, orig_node);
709
}
710

711
712
713
714
715
716
717
718
719
720
721
722
static ir_node *transform_zext(ir_node *node, ir_node *orig_node)
{
	ir_mode  *mode  = get_irn_mode(node);
	ir_node  *block = get_nodes_block(node);
	dbg_info *dbgi  = get_irn_dbg_info(node);
	/* normalize to an unsigned mode */
	switch (get_mode_size_bits(mode)) {
	case 8:  mode = mode_Bu; break;
	case 16: mode = mode_Hu; break;
	default:
		panic("ia32: invalid mode in zest: %+F", node);
	}
723
	return create_I2I_Conv(mode, ia32_mode_gp, dbgi, block, node, orig_node);
724
725
726
727
728
}

static ir_node *transform_upconv(ir_node *node, ir_node *orig_node)
{
	ir_mode *mode = get_irn_mode(node);
Christoph Mallon's avatar
Christoph Mallon committed
729
	if (mode_is_signed(mode)) {
730
		return transform_sext(node, orig_node);
731
	} else {
732
		return transform_zext(node, orig_node);
733
734
	}
}
735

736
737
738
739
740
741
742
743
744
745
746
static ir_node *get_noreg(ir_mode *const mode)
{
	if (!mode_is_float(mode)) {
		return noreg_GP;
	} else if (ia32_cg_config.use_sse2) {
		return ia32_new_NoReg_xmm(current_ir_graph);
	} else {
		return ia32_new_NoReg_fp(current_ir_graph);
	}
}

747
748
749
750
751
752
753
754
755
756
757
/**
 * 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.
 */
758
static void match_arguments(ia32_address_mode_t *am, ir_node *block,
759
760
                            ir_node *op1, ir_node *op2, ir_node *other_op,
                            match_flags_t flags)
761
762
763
{
	memset(am, 0, sizeof(am[0]));

764
765
766
767
	bool commutative           = (flags & match_commutative) != 0;
	bool use_am_and_immediates = (flags & match_am_and_immediates) != 0;
	bool use_am                = (flags & match_am) != 0;
	bool use_immediate         = (flags & match_immediate) != 0;
768
	assert(!use_am_and_immediates || use_immediate);
769
770
771

	assert(op2 != NULL);
	assert(!commutative || op1 != NULL);
772
773
	assert(use_am || !(flags & match_8bit_am));
	assert(use_am || !(flags & match_16bit_am));
774

775
776
	ir_mode *mode      = get_irn_mode(op2);
	int      mode_bits = get_mode_size_bits(mode);
777
	if ((mode_bits ==  8 && !(flags & match_8bit_am)) ||
778
	    (mode_bits == 16 && !(flags & match_16bit_am))) {
779
		use_am = false;
780
	}
781

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

796
797
	/* match immediates. firm nodes are normalized: constants are always on the
	 * op2 input */
798
	ir_node *new_op2 = NULL;
799
	if (!(flags & match_try_am) && use_immediate) {
800
		new_op2 = ia32_try_create_Immediate(op2, 'i');
801
	}
802

803
	ir_node *new_op1;
804
	if (new_op2 == NULL &&
805
	    use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
806
		build_address(am, op2, x86_create_am_normal);
807
		new_op1     = (op1 == NULL ? NULL : be_transform_node(op1));
808
		new_op2     = get_noreg(mode);
809
		am->op_type = ia32_AddrModeS;
810
811
	} else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
		       use_am &&
812
		       ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
813
		build_address(am, op1, x86_create_am_normal);
814

815
		ir_node *const noreg = get_noreg(mode);