ia32_transform.c 172 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
 */
12
#include "config.h"
13

Christian Würdig's avatar
Christian Würdig committed
14
#include <limits.h>
15
#include <stdbool.h>
Christian Würdig's avatar
Christian Würdig committed
16

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

36
37
38
39
40
41
#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
42

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

Christian Würdig's avatar
Christian Würdig committed
53
54
#include "gen_ia32_regalloc_if.h"

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

58
#define mode_fp     (ia32_reg_classes[CLASS_ia32_fp].mode)
59
60
#define mode_xmm    (ia32_reg_classes[CLASS_ia32_xmm].mode)

61
62
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)

63
static ir_node         *old_initial_fpcw = NULL;
64
static ir_node         *initial_fpcw = NULL;
65
int                     ia32_no_pic_adjust;
66

67
68
69
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
70

71
72
73
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);
74

75
76
typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
        ir_node *op1, ir_node *op2);
77

78
79
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);
80

81
82
typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
        ir_node *base, ir_node *index, ir_node *mem);
83

84
85
86
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
87

88
typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op);
89

90
static ir_node *create_immediate_or_transform(ir_node *node);
91

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

96
97
98
/* its enough to have those once */
static ir_node *nomem, *noreg_GP;

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

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

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

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

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

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

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

142
	if (mode == mode_F)
143
		return true;
144

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

166
167
168
169
170
171
/**
 * 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)
{
172
173
	ir_graph *irg = current_ir_graph;

174
	if (be_options.pic) {
175
176
		const arch_env_t *arch_env = be_get_irg_arch_env(irg);
		return arch_env->impl->get_pic_base(irg);
177
178
179
180
181
	}

	return noreg_GP;
}

182
183
184
/**
 * Transforms a Const.
 */
Christoph Mallon's avatar
Christoph Mallon committed
185
186
static ir_node *gen_Const(ir_node *node)
{
187
188
189
190
191
	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);
192
193

	if (mode_is_float(mode)) {
194
195
196
197
198
199
		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;
		ir_entity        *floatent;
200

201
		if (ia32_cg_config.use_sse2) {
202
			if (tarval_is_null(tv)) {
203
				load = new_bd_ia32_xZero(dbgi, block);
204
205
				set_ia32_ls_mode(load, mode);
				res  = load;
206
#ifdef CONSTRUCT_SSE_CONST
207
208
			} else if (tarval_is_one(tv)) {
				int     cnst  = mode == mode_F ? 26 : 55;
209
210
				ir_node *imm1 = ia32_create_Immediate(irg, NULL, 0, cnst);
				ir_node *imm2 = ia32_create_Immediate(irg, NULL, 0, 2);
211
212
				ir_node *pslld, *psrld;

213
				load = new_bd_ia32_xAllOnes(dbgi, block);
214
				set_ia32_ls_mode(load, mode);
215
				pslld = new_bd_ia32_xPslld(dbgi, block, load, imm1);
216
				set_ia32_ls_mode(pslld, mode);
217
				psrld = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2);
218
219
				set_ia32_ls_mode(psrld, mode);
				res = psrld;
220
#endif /* CONSTRUCT_SSE_CONST */
221
222
223
224
225
226
			} 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);
227
				ir_node *cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
228
				load = new_bd_ia32_xMovd(dbgi, block, cnst);
229
230
				set_ia32_ls_mode(load, mode);
				res = load;
231
			} else {
232
				ir_node *base;
233
#ifdef CONSTRUCT_SSE_CONST
234
235
236
237
238
239
				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) {
240
						ir_node *imm32 = ia32_create_Immediate(irg, NULL, 0, 32);
241
242
243
244
245
246
247
						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);
248
						cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
249
						load = new_bd_ia32_xMovd(dbgi, block, cnst);
250
						set_ia32_ls_mode(load, mode);
251
						psllq = new_bd_ia32_xPsllq(dbgi, block, load, imm32);
252
253
254
255
256
						set_ia32_ls_mode(psllq, mode);
						res = psllq;
						goto end;
					}
				}
257
#endif /* CONSTRUCT_SSE_CONST */
258
				floatent = ia32_create_float_const_entity(isa, tv, NULL);
259

260
261
262
				base     = get_symconst_base();
				load     = new_bd_ia32_xLoad(dbgi, block, base, noreg_GP, nomem,
				                             mode);
263
264
				set_ia32_op_type(load, ia32_AddrModeS);
				set_ia32_am_sc(load, floatent);
265
				arch_add_irn_flags(load, arch_irn_flags_rematerializable);
266
				res = new_r_Proj(load, mode_xmm, pn_ia32_xLoad_res);
267
268
			}
		} else {
269
			if (tarval_is_null(tv)) {
270
				load = new_bd_ia32_fldz(dbgi, block);
271
				res  = load;
272
				set_ia32_ls_mode(load, mode);
273
			} else if (tarval_is_one(tv)) {
274
				load = new_bd_ia32_fld1(dbgi, block);
275
				res  = load;
276
				set_ia32_ls_mode(load, mode);
277
			} else {
278
				ir_mode *ls_mode;
279
				ir_node *base;
280

281
				floatent = ia32_create_float_const_entity(isa, tv, NULL);
282
283
284
				/* create_float_const_ent is smart and sometimes creates
				   smaller entities */
				ls_mode  = get_type_mode(get_entity_type(floatent));
285
				base     = get_symconst_base();
286
287
				load     = new_bd_ia32_fld(dbgi, block, base, noreg_GP, nomem,
				                           ls_mode);
288
				set_ia32_op_type(load, ia32_AddrModeS);
289
				set_ia32_am_sc(load, floatent);
290
				arch_add_irn_flags(load, arch_irn_flags_rematerializable);
291
				res = new_r_Proj(load, mode_fp, pn_ia32_fld_res);
292
293
			}
		}
294
#ifdef CONSTRUCT_SSE_CONST
295
end:
296
#endif /* CONSTRUCT_SSE_CONST */
297
		SET_IA32_ORIG_NODE(load, node);
298
		return res;
299
	} else { /* non-float mode */
300
301
		ir_node *cnst;
		long     val;
302
303
304

		tv = tarval_convert_to(tv, mode_Iu);

305
306
		if (tv == get_tarval_bad() || tv == get_tarval_undefined() ||
		    tv == NULL) {
307
308
309
310
			panic("couldn't convert constant tarval (%+F)", node);
		}
		val = get_tarval_long(tv);

311
		cnst = new_bd_ia32_Const(dbgi, block, NULL, 0, 0, val);
312
		SET_IA32_ORIG_NODE(cnst, node);
313
314
315
316
317
318
319
320

		return cnst;
	}
}

/**
 * Transforms a SymConst.
 */
Christoph Mallon's avatar
Christoph Mallon committed
321
322
static ir_node *gen_SymConst(ir_node *node)
{
323
324
	ir_node  *old_block = get_nodes_block(node);
	ir_node  *block = be_transform_node(old_block);
325
326
	dbg_info *dbgi  = get_irn_dbg_info(node);
	ir_mode  *mode  = get_irn_mode(node);
327
328
329
	ir_node  *cnst;

	if (mode_is_float(mode)) {
330
		if (ia32_cg_config.use_sse2)
331
			cnst = new_bd_ia32_xLoad(dbgi, block, noreg_GP, noreg_GP, nomem, mode_D);
332
		else
333
			cnst = new_bd_ia32_fld(dbgi, block, noreg_GP, noreg_GP, nomem, ia32_mode_E);
334
		set_ia32_am_sc(cnst, get_SymConst_entity(node));
335
		set_ia32_use_frame(cnst);
336
	} else {
Michael Beck's avatar
Michael Beck committed
337
338
		ir_entity *entity;

Christoph Mallon's avatar
Christoph Mallon committed
339
		if (get_SymConst_kind(node) != symconst_addr_ent) {
340
341
			panic("backend only support symconst_addr_ent (at %+F)", node);
		}
Michael Beck's avatar
Michael Beck committed
342
		entity = get_SymConst_entity(node);
343
344
345
346
347
348
349
350
		if (get_entity_owner(entity) == get_tls_type()) {
			ir_node *tls_base = new_bd_ia32_LdTls(NULL, block);
			ir_node *lea     = new_bd_ia32_Lea(dbgi, block, tls_base, noreg_GP);
			set_ia32_am_sc(lea, entity);
			cnst = lea;
		} else {
			cnst = new_bd_ia32_Const(dbgi, block, entity, 0, 0, 0);
		}
351
352
	}

353
	SET_IA32_ORIG_NODE(cnst, node);
354
355
356
357

	return cnst;
}

358
static ir_type *make_array_type(ir_type *tp)
359
{
360
361
362
363
364
365
366
367
368
369
	unsigned alignment = get_type_alignment_bytes(tp);
	unsigned size      = get_type_size_bytes(tp);
	ir_type *res = new_type_array(1, tp);
	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
370
371
372
373
374
375
376
}

/**
 * Create a float[2] array type for the given atomic type.
 *
 * @param tp  the atomic type
 */
377
378
static ir_type *ia32_create_float_array(ir_type *tp)
{
Michael Beck's avatar
Michael Beck committed
379
380
381
382
	ir_mode  *mode = get_type_mode(tp);
	ir_type  *arr;

	if (mode == mode_F) {
383
		static ir_type *float_F;
Michael Beck's avatar
Michael Beck committed
384

385
386
387
		arr = float_F;
		if (arr == NULL)
			arr = float_F = make_array_type(tp);
Michael Beck's avatar
Michael Beck committed
388
	} else if (mode == mode_D) {
389
		static ir_type *float_D;
Michael Beck's avatar
Michael Beck committed
390

391
392
393
		arr = float_D;
		if (arr == NULL)
			arr = float_D = make_array_type(tp);
Michael Beck's avatar
Michael Beck committed
394
	} else {
395
		static ir_type *float_E;
Michael Beck's avatar
Michael Beck committed
396

397
398
399
		arr = float_E;
		if (arr == NULL)
			arr = float_E = make_array_type(tp);
Michael Beck's avatar
Michael Beck committed
400
401
402
403
	}
	return arr;
}

404
/* Generates an entity for a known FP const (used for FP Neg + Abs) */
Christoph Mallon's avatar
Christoph Mallon committed
405
406
ir_entity *ia32_gen_fp_known_const(ia32_known_const_t kct)
{
407
	static const struct {
408
		const char *name;
409
		const char *cnst_str;
410
		char        mode;
411
	} names [ia32_known_const_max] = {
412
413
414
415
416
		{ "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 }
417
	};
418
	static ir_entity *ent_cache[ia32_known_const_max];
419

420
	ir_entity *ent = ent_cache[kct];
421

422
423
424
425
426
427
428
429
	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;
		ir_tarval        *tv;
430
431
432
		switch (names[kct].mode) {
		case 0:  mode = mode_Iu; break;
		case 1:  mode = mode_Lu; break;
433
		case 2:  mode = mode_F;  break;
434
		default: panic("internal compiler error");
435
		}
436
		tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
437

438
439
440
441
		if (kct == ia32_ULLBIAS) {
			ir_type          *type  = ia32_get_prim_type(mode_F);
			ir_type          *atype = ia32_create_float_array(type);
			ir_initializer_t *initializer;
442

443
			ent = new_entity(get_glob_type(), name, atype);
444

445
446
447
			set_entity_ld_ident(ent, name);
			set_entity_visibility(ent, ir_visibility_private);
			add_entity_linkage(ent, IR_LINKAGE_CONSTANT);
448

449
			initializer = create_initializer_compound(2);
450
			set_initializer_compound_value(initializer, 0,
451
				create_initializer_tarval(get_mode_null(mode)));
452
453
454
455
			set_initializer_compound_value(initializer, 1,
				create_initializer_tarval(tv));
			set_entity_initializer(ent, initializer);
		} else {
456
			ent = ia32_create_float_const_entity(isa, tv, name);
457
		}
458
459
		/* cache the entry */
		ent_cache[kct] = ent;
460
	}
461

462
	return ent_cache[kct];
463
464
}

465
466
467
468
469
470
471
/**
 * 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,
472
473
                                        ir_node *other, ir_node *other2,
                                        match_flags_t flags)
474
475
{
	ir_node *load;
476
	ir_mode *mode;
477
478
	long     pn;

479
	/* float constants are always available */
Michael Beck's avatar
Michael Beck committed
480
	if (is_Const(node)) {
481
		mode = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
482
		if (mode_is_float(mode)) {
483
484
485
			ir_tarval *tv = get_Const_tarval(node);
			if (!tarval_ieee754_can_conv_lossless(tv, mode_D))
				return 0;
Michael Beck's avatar
Michael Beck committed
486
487
488
489
490
491
492
493
			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)
494
				return 0;
Michael Beck's avatar
Michael Beck committed
495
			return 1;
496
		}
497
		return 0;
498
499
	}

Michael Beck's avatar
Michael Beck committed
500
	if (!is_Proj(node))
501
502
503
		return 0;
	load = get_Proj_pred(node);
	pn   = get_Proj_proj(node);
Michael Beck's avatar
Michael Beck committed
504
	if (!is_Load(load) || pn != pn_Load_res)
505
		return 0;
Michael Beck's avatar
Michael Beck committed
506
	if (get_nodes_block(load) != block)
507
		return 0;
508
509
510
511
	mode = get_irn_mode(node);
	/* we can't fold mode_E AM */
	if (mode == ia32_mode_E)
		return 0;
512
	/* we only use address mode if we're the only user of the load */
513
	if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1))
514
		return 0;
515
516
517
	/* 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
518
	if (be_is_transformed(node))
519
		return 0;
520
521

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

525
	if (other2 != NULL && ia32_prevents_AM(block, load, other2))
526
		return 0;
527
528
529
530
531
532
533
534
535

	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;
536
	ir_node        *am_node;
537
538
539
	ia32_op_type_t  op_type;
	ir_node        *new_op1;
	ir_node        *new_op2;
540
	op_pin_state    pinned;
Matthias Braun's avatar
Matthias Braun committed
541
542
	unsigned        commutative  : 1;
	unsigned        ins_permuted : 1;
543
544
};

Matthias Braun's avatar
Matthias Braun committed
545
546
547
548
static void build_address_ptr(ia32_address_t *addr, ir_node *ptr, ir_node *mem)
{
	/* construct load address */
	memset(addr, 0, sizeof(addr[0]));
549
	ia32_create_address_mode(addr, ptr, ia32_create_am_normal);
Matthias Braun's avatar
Matthias Braun committed
550

551
552
	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
553
554
555
	addr->mem   = be_transform_node(mem);
}

556
557
static void build_address(ia32_address_mode_t *am, ir_node *node,
                          ia32_create_am_flags_t flags)
558
{
559
	ia32_address_t *addr = &am->addr;
560
561
562
563
	ir_node        *load;
	ir_node        *ptr;
	ir_node        *mem;
	ir_node        *new_mem;
564

565
	/* floating point immediates */
566
	if (is_Const(node)) {
567
568
569
570
571
		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);
		ir_entity *entity  = ia32_create_float_const_entity(isa, tv, NULL);
572
		addr->base         = get_symconst_base();
573
574
		addr->index        = noreg_GP;
		addr->mem          = nomem;
575
		addr->symconst_ent = entity;
576
		addr->tls_segment  = false;
577
		addr->use_frame    = 1;
578
		am->ls_mode        = get_type_mode(get_entity_type(entity));
579
		am->pinned         = op_pin_state_floats;
580
581
582
583
584
585
586
		return;
	}

	load         = get_Proj_pred(node);
	ptr          = get_Load_ptr(load);
	mem          = get_Load_mem(load);
	new_mem      = be_transform_node(mem);
587
	am->pinned   = get_irn_pinned(load);
588
589
	am->ls_mode  = get_Load_mode(load);
	am->mem_proj = be_get_Proj_for_pn(load, pn_Load_M);
590
	am->am_node  = node;
591
592

	/* construct load address */
593
	ia32_create_address_mode(addr, ptr, flags);
594

595
596
	addr->base  = addr->base  ? be_transform_node(addr->base)  : noreg_GP;
	addr->index = addr->index ? be_transform_node(addr->index) : noreg_GP;
597
	addr->mem   = new_mem;
598
599
}

600
static void set_address(ir_node *node, const ia32_address_t *addr)
601
602
603
604
{
	set_ia32_am_scale(node, addr->scale);
	set_ia32_am_sc(node, addr->symconst_ent);
	set_ia32_am_offs_int(node, addr->offset);
605
	set_ia32_am_tls_segment(node, addr->tls_segment);
Christoph Mallon's avatar
Christoph Mallon committed
606
	if (addr->symconst_sign)
607
		set_ia32_am_sc_sign(node);
Christoph Mallon's avatar
Christoph Mallon committed
608
	if (addr->use_frame)
609
610
		set_ia32_use_frame(node);
	set_ia32_frame_ent(node, addr->frame_entity);
611
612
}

Michael Beck's avatar
Michael Beck committed
613
614
615
/**
 * Apply attributes of a given address mode to a node.
 */
616
static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
617
618
{
	set_address(node, &am->addr);
619

620
621
	set_ia32_op_type(node, am->op_type);
	set_ia32_ls_mode(node, am->ls_mode);
Michael Beck's avatar
Michael Beck committed
622
	if (am->pinned == op_pin_state_pinned) {
623
624
625
		/* 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);
626
	}
Michael Beck's avatar
Michael Beck committed
627
	if (am->commutative)
628
629
		set_ia32_commutative(node);
}
630

631
/**
yb9976's avatar
yb9976 committed
632
 * Check, if a given node is a Down-Conv, i.e. a integer Conv
633
634
635
636
637
638
 * 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
 */
639
640
641
642
643
static int is_downconv(const ir_node *node)
{
	ir_mode *src_mode;
	ir_mode *dest_mode;

Christoph Mallon's avatar
Christoph Mallon committed
644
	if (!is_Conv(node))
645
646
647
648
		return 0;

	src_mode  = get_irn_mode(get_Conv_op(node));
	dest_mode = get_irn_mode(node);
649
650
651
652
	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);
653
654
}

655
/** Skip all Down-Conv's on a given node and return the resulting node. */
Christoph Mallon's avatar
Christoph Mallon committed
656
657
ir_node *ia32_skip_downconv(ir_node *node)
{
658
659
660
661
662
663
664
	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;

665
		node = get_Conv_op(node);
666
	}
667
668
669
670

	return node;
}

671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
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;
}

690
691
692
693
694
695
696
697
static bool is_sameconv(ir_node *node)
{
	ir_mode *src_mode;
	ir_mode *dest_mode;

	if (!is_Conv(node))
		return 0;

698
699
700
701
702
703
	/* 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;

704
705
706
707
708
709
710
711
712
713
714
	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)
{
715
	while (is_sameconv(node)) {
716
		node = get_Conv_op(node);
717
	}
718
719
720
721

	return node;
}

722
static ir_node *transform_sext(ir_node *node, ir_node *orig_node)
723
{
724
725
726
727
728
	ir_mode  *mode  = get_irn_mode(node);
	ir_node  *block = get_nodes_block(node);
	dbg_info *dbgi  = get_irn_dbg_info(node);
	return create_I2I_Conv(mode, mode_Is, dbgi, block, node, orig_node);
}
729

730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
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);
	}
	return create_I2I_Conv(mode, mode_Iu, dbgi, block, node, orig_node);
}

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
748
	if (mode_is_signed(mode)) {
749
		return transform_sext(node, orig_node);
750
	} else {
751
		return transform_zext(node, orig_node);
752
753
	}
}
754

755
756
757
758
759
760
761
762
763
764
765
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);
	}
}

766
767
768
769
770
771
772
773
774
775
776
/**
 * 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.
 */
777
static void match_arguments(ia32_address_mode_t *am, ir_node *block,
778
779
                            ir_node *op1, ir_node *op2, ir_node *other_op,
                            match_flags_t flags)
780
{
Michael Beck's avatar
Michael Beck committed
781
782
783
	ia32_address_t *addr      = &am->addr;
	ir_mode        *mode      = get_irn_mode(op2);
	int             mode_bits = get_mode_size_bits(mode);
784
	ir_node        *new_op1, *new_op2;
785
	int             use_am;
Michael Beck's avatar
Michael Beck committed
786
	unsigned        commutative;
787
	int             use_am_and_immediates;
788
	int             use_immediate;
789
790
791

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

792
793
	commutative           = (flags & match_commutative) != 0;
	use_am_and_immediates = (flags & match_am_and_immediates) != 0;
794
795
796
	use_am                = (flags & match_am) != 0;
	use_immediate         = (flags & match_immediate) != 0;
	assert(!use_am_and_immediates || use_immediate);
797
798
799

	assert(op2 != NULL);
	assert(!commutative || op1 != NULL);
800
801
	assert(use_am || !(flags & match_8bit_am));
	assert(use_am || !(flags & match_16bit_am));
802

803
	if ((mode_bits ==  8 && !(flags & match_8bit_am)) ||
804
	    (mode_bits == 16 && !(flags & match_16bit_am))) {
805
		use_am = 0;
806
	}
807

808
809
	/* we can simply skip downconvs for mode neutral nodes: the upper bits
	 * can be random for these operations */
810
	if (flags & match_mode_neutral) {
811
		op2 = ia32_skip_downconv(op2);
812
		if (op1 != NULL) {
813
814
			op1 = ia32_skip_downconv(op1);
		}
815
816
817
818
819
	} else {
		op2 = ia32_skip_sameconv(op2);
		if (op1 != NULL) {
			op1 = ia32_skip_sameconv(op1);
		}
820
821
	}

822
823
824
	/* match immediates. firm nodes are normalized: constants are always on the
	 * op2 input */
	new_op2 = NULL;
825
	if (!(flags & match_try_am) && use_immediate) {
826
		new_op2 = ia32_try_create_Immediate(op2, 'i');
827
	}
828

829
	if (new_op2 == NULL &&
830
	    use_am && ia32_use_source_address_mode(block, op2, op1, other_op, flags)) {
831
		build_address(am, op2, ia32_create_am_normal);
832
		new_op1     = (op1 == NULL ? NULL : be_transform_node(op1));
833
		new_op2     = get_noreg(mode);
834
		am->op_type = ia32_AddrModeS;
835
836
	} else if (commutative && (new_op2 == NULL || use_am_and_immediates) &&
		       use_am &&
837
		       ia32_use_source_address_mode(block, op1, op2, other_op, flags)) {
838
		build_address(am, op1, ia32_create_am_normal);
839

840
		ir_node *const noreg = get_noreg(mode);
Michael Beck's avatar
Michael Beck committed
841
		if (new_op2 != NULL) {
842
			new_op1 = noreg;
843
844
		} else {
			new_op1 = be_transform_node(op2);
845
			new_op2 = noreg;
846
			am->ins_permuted = true;
847
848
		}
		am->op_type = ia32_AddrModeS;
849
	} else {
Christoph Mallon's avatar
Christoph Mallon committed
850
851
		am->op_type = ia32_Normal;

Michael Beck's avatar
Michael Beck committed
852
		if (flags & match_try_am) {
853
854
855
856
857
			am->new_op1 = NULL;
			am->new_op2 = NULL;
			return;
		}

858
		mode = get_irn_mode(op2);
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
		if (get_mode_size_bits(mode) != 32
			&& (flags & (match_mode_neutral | match_upconv | match_zero_ext))) {
			if (flags & match_upconv) {
				new_op1 = (op1 == NULL ? NULL : transform_upconv(op1, op1));
				if (new_op2 == NULL)
					new_op2 = transform_upconv(op2, op2);
			} else if (flags & match_zero_ext) {
				new_op1 = (op1 == NULL ? NULL : transform_zext(op1, op1));
				if (new_op2 == NULL)
					new_op2 = transform_zext(op2, op2);
			} else {
				new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
				if (new_op2 == NULL)
					new_op2 = be_transform_node(op2);
				assert(flags & match_mode_neutral);
			}
			mode = mode_Iu;
876
877
878
879
880
		} else {
			new_op1 = (op1 == NULL ? NULL : be_transform_node(op1));
			if (new_op2 == NULL)
				new_op2 = be_transform_node(op2);
		}
881
		am->ls_mode = mode;
882
	}
Michael Beck's avatar
Michael Beck committed