ia32_transform.c 182 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 <stdbool.h>
Christian Würdig's avatar
Christian Würdig committed
13

Christian Würdig's avatar
Christian Würdig committed
14
#include "irargs_t.h"
15
16
17
#include "irnode_t.h"
#include "irgraph_t.h"
#include "irmode_t.h"
Christian Würdig's avatar
Christian Würdig committed
18
19
20
#include "iropt_t.h"
#include "irop_t.h"
#include "irprog_t.h"
Christian Würdig's avatar
Christian Würdig committed
21
#include "iredges_t.h"
22
#include "irouts.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"
Matthias Braun's avatar
Matthias Braun committed
30
#include "panic.h"
31
#include "array.h"
32
#include "heights.h"
33
#include "tv_t.h"
34

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

41
42
#include "gen_ia32_regalloc_if.h"
#include "ia32_architecture.h"
43
#include "ia32_bearch_t.h"
44
45
46
#include "ia32_new_nodes.h"
#include "ia32_nodes_attr.h"
#include "ia32_transform.h"
47
#include "util.h"
48
#include "x86_address_mode.h"
49
#include "x86_cconv.h"
50
#include "x86_x87.h"
51

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

55
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
56

57
static x86_cconv_t          *current_cconv;
58
static be_stack_env_t        stack_env;
59
60
static ir_heights_t         *heights;
static x86_immediate_kind_t  lconst_imm_kind;
61
static x86_addr_variant_t    lconst_variant;
62
static ir_node              *initial_va_list;
63

64
65
66
67
68
69
70
71
72
73
74
75
76
/** we don't have a concept of aliasing registers, so enumerate them
 * manually for the asm nodes. */
const x86_clobber_name_t ia32_additional_clobber_names[] = {
	{ "al", REG_EAX }, { "ah", REG_EAX }, { "ax", REG_EAX },
	{ "bl", REG_EBX }, { "bh", REG_EBX }, { "bx", REG_EBX },
	{ "cl", REG_ECX }, { "ch", REG_ECX }, { "cx", REG_ECX },
	{ "dl", REG_EDX }, { "dh", REG_EDX }, { "dx", REG_EDX },
	{ "si", REG_ESI }, { "di", REG_EDI }, { "sp", REG_ESP },
	{ "bp", REG_EBP }, { NULL, ~0u }
};

#define GP &ia32_reg_classes[CLASS_ia32_gp]
#define FP &ia32_reg_classes[CLASS_ia32_fp]
77
const x86_asm_constraint_list_t ia32_asm_constraints = {
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
	['A'] = { MATCH_REG, GP, 1 << REG_GP_EAX | 1 << REG_GP_EDX },
	['D'] = { MATCH_REG, GP, 1 << REG_GP_EDI },
	['I'] = { MATCH_IMM, GP, 0 },
	['J'] = { MATCH_IMM, GP, 0 },
	['K'] = { MATCH_IMM, GP, 0 },
	['L'] = { MATCH_IMM, GP, 0 },
	['M'] = { MATCH_IMM, GP, 0 },
	['N'] = { MATCH_IMM, GP, 0 },
	['O'] = { MATCH_IMM, GP, 0 },
	['R'] = { MATCH_REG, GP, 0 },
	['S'] = { MATCH_REG, GP, 1 << REG_GP_ESI },
	['Q'] = { MATCH_REG, GP, 1 << REG_GP_EAX | 1 << REG_GP_EBX
		| 1 << REG_GP_ECX | 1 << REG_GP_EDX },
	['V'] = { MATCH_MEM, GP, 0 },
	['X'] = { MATCH_ANY, GP, 0 },
	['a'] = { MATCH_REG, GP, 1 << REG_GP_EAX },
	['b'] = { MATCH_REG, GP, 1 << REG_GP_EBX },
	['c'] = { MATCH_REG, GP, 1 << REG_GP_ECX },
	['d'] = { MATCH_REG, GP, 1 << REG_GP_EDX },
97
	['e'] = { MATCH_IMM, GP, 0 },
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
	['f'] = { MATCH_REG, FP, 0 },
	['g'] = { MATCH_ANY, GP, 0 },
	['i'] = { MATCH_IMM, GP, 0 },
	['l'] = { MATCH_REG, GP, 1 << REG_GP_EAX | 1 << REG_GP_EBX
		| 1 << REG_GP_ECX | 1 << REG_GP_EDX | 1 << REG_GP_ESI
		| 1 << REG_GP_EDI | 1 << REG_GP_EBP },
	['m'] = { MATCH_MEM, GP, 0 },
	['n'] = { MATCH_IMM, GP, 0 },
	['o'] = { MATCH_MEM, GP, 0 },
	['p'] = { MATCH_REG, GP, 0 },
	['q'] = { MATCH_REG, GP, 1 << REG_GP_EAX | 1 << REG_GP_EBX
		| 1 << REG_GP_ECX | 1 << REG_GP_EDX },
	['r'] = { MATCH_REG, GP, 0 },
	['t'] = { MATCH_REG, FP, 1 << REG_FP_ST0 },
	['u'] = { MATCH_REG, FP, 1 << REG_FP_ST1 },
	['x'] = { MATCH_REG, &ia32_reg_classes[CLASS_ia32_xmm], 0 },

	// There are more constraints and in general there is alot of internal gcc
116
	// logic at play not everything is documented in the manual. In the gcc
117
118
119
120
121
122
	// source you can look at reload.c, stmt.c and constraints.md. I am not sure
	// how much we want/need to understand and reimplement here.
};
#undef GP
#undef FP

123
124
typedef ir_node *construct_binop_func(dbg_info *db, ir_node *block,
        ir_node *base, ir_node *index, ir_node *mem, ir_node *op1,
125
        ir_node *op2, x86_insn_size_t size);
Christian Würdig's avatar
Christian Würdig committed
126

127
128
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,
129
        ir_node *flags, x86_insn_size_t size);
130

131
typedef ir_node *construct_shift_func(dbg_info *db, ir_node *block,
132
        ir_node *op1, ir_node *op2, x86_insn_size_t size);
133

134
typedef ir_node *construct_binop_dest_func(dbg_info *db, ir_node *block,
135
136
        ir_node *base, ir_node *index, ir_node *mem, ir_node *op,
        x86_insn_size_t size);
137

138
typedef ir_node *construct_unop_dest_func(dbg_info *db, ir_node *block,
139
        ir_node *base, ir_node *index, ir_node *mem, x86_insn_size_t size);
140

141
142
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,
143
        ir_node *fpcw, x86_insn_size_t size);
Matthias Braun's avatar
Matthias Braun committed
144

145
146
typedef ir_node *construct_unop_func(dbg_info *db, ir_node *block, ir_node *op,
                                     x86_insn_size_t size);
147

148
149
static ir_node *create_immediate_or_transform(ir_node *node,
                                              const char immediate_mode);
150

151
static ir_node *create_I2I_Conv(ir_mode *src_mode, dbg_info *dbgi, ir_node *block, ir_node *op);
152

153
/* its enough to have those once */
154
155
static ir_node *nomem;
static ir_node *noreg_GP;
156

157
158
159
160
161
static bool mode_needs_gp_reg(ir_mode *mode)
{
	return get_mode_arithmetic(mode) == irma_twos_complement;
}

Michael Beck's avatar
Michael Beck committed
162
/** Return non-zero is a node represents the 0 constant. */
Christoph Mallon's avatar
Christoph Mallon committed
163
164
static bool is_Const_0(ir_node *node)
{
165
	return is_Const(node) && is_Const_null(node);
166
167
}

Michael Beck's avatar
Michael Beck committed
168
/** Return non-zero is a node represents the 1 constant. */
Christoph Mallon's avatar
Christoph Mallon committed
169
170
static bool is_Const_1(ir_node *node)
{
171
	return is_Const(node) && is_Const_one(node);
172
173
}

Michael Beck's avatar
Michael Beck committed
174
/** Return non-zero is a node represents the -1 constant. */
Christoph Mallon's avatar
Christoph Mallon committed
175
176
static bool is_Const_Minus_1(ir_node *node)
{
177
	return is_Const(node) && is_Const_all_one(node);
178
179
}

180
181
182
/**
 * returns true if constant can be created with a simple float command
 */
183
static bool is_simple_x87_Const(ir_node *node)
184
{
Matthias Braun's avatar
Matthias Braun committed
185
	ir_tarval *tv = get_Const_tarval(node);
186
	if (tarval_is_null(tv) || tarval_is_one(tv))
187
		return true;
188
189

	/* TODO: match all the other float constants */
190
	return false;
191
192
193
194
195
}

/**
 * returns true if constant can be created with a simple float command
 */
196
static bool is_simple_sse_Const(ir_node *node)
197
{
Matthias Braun's avatar
Matthias Braun committed
198
199
	ir_tarval *tv   = get_Const_tarval(node);
	ir_mode   *mode = get_tarval_mode(tv);
200

201
	if (get_mode_size_bits(mode) == 32)
202
		return true;
203

204
205
206
207
208
	if (tarval_is_null(tv)
#ifdef CONSTRUCT_SSE_CONST
	    || tarval_is_one(tv)
#endif
	   )
209
		return true;
210
#ifdef CONSTRUCT_SSE_CONST
211
	if (mode == ia32_mode_float64) {
212
		unsigned const val = be_get_tv_bits32(tv, 0);
213
		if (val == 0)
214
			/* lower 32bit are zero, really a 32bit constant */
215
			return true;
216
	}
217
#endif /* CONSTRUCT_SSE_CONST */
218
	/* TODO: match all the other float constants */
219
	return false;
220
221
}

222
223
ir_node *ia32_get_pic_base(ir_graph *irg)
{
224
225
226
227
228
229
	ir_node **const get_eip = &ia32_get_irg_data(irg)->get_eip;
	if (!*get_eip) {
		ir_node *const block = get_irg_start_block(irg);
		*get_eip = new_bd_ia32_GetEIP(NULL, block);
	}
	return *get_eip;
230
231
}

232
233
234
235
/**
 * return NoREG or pic_base in case of PIC.
 * This is necessary as base address for newly created symbols
 */
236
static ir_node *get_global_base(ir_graph *const irg)
237
{
238
	if (be_options.pic_style != BE_PIC_NONE)
239
		return ia32_get_pic_base(irg);
240
241
242
	return noreg_GP;
}

243
244
static ir_node *get_initial_sp(ir_graph *irg)
{
Christoph Mallon's avatar
Christoph Mallon committed
245
	return be_get_Start_proj(irg, &ia32_registers[REG_ESP]);
246
247
248
249
}

static ir_node *get_initial_fp(ir_graph *irg)
{
Christoph Mallon's avatar
Christoph Mallon committed
250
	return be_get_Start_proj(irg, &ia32_registers[REG_EBP]);
251
252
253
254
}

static ir_node *get_initial_fpcw(ir_graph *irg)
{
Christoph Mallon's avatar
Christoph Mallon committed
255
	return be_get_Start_proj(irg, &ia32_registers[REG_FPCW]);
256
257
}

258
ir_node *ia32_create_Immediate_full(ir_graph *const irg,
259
                                    x86_imm32_t const *const imm)
260
261
262
{
	ir_node *const start_block = get_irg_start_block(irg);
	ir_node *const immediate
263
		= new_bd_ia32_Immediate(NULL, start_block, imm);
264
265
266
267
	arch_set_irn_register(immediate, &ia32_registers[REG_GP_NOREG]);
	return immediate;
}

268
static void adjust_relocation(x86_imm32_t *imm)
269
{
270
271
272
	if (imm->kind != X86_IMM_ADDR)
		return;
	ir_entity *entity = imm->entity;
273
	if (is_tls_entity(entity)) {
274
275
		imm->kind = entity_has_definition(entity) ? X86_IMM_TLS_LE
		                                          : X86_IMM_TLS_IE;
276
		return;
277
	}
278
279
}

280
static ir_node *try_create_Immediate(const ir_node *node, char const constraint)
281
{
282
283
	x86_imm32_t immediate;
	if (!x86_match_immediate(&immediate, node, constraint))
284
		return NULL;
285
	adjust_relocation(&immediate);
286
287

	ir_graph *const irg = get_irn_irg(node);
288
	return ia32_create_Immediate_full(irg, &immediate);
289
290
}

291
static ir_entity *create_float_const_entity(ir_tarval *tv, ident *name)
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
{
	ir_mode *mode = get_tarval_mode(tv);
	if (!ia32_cg_config.use_sse2) {
		/* try to reduce the mode to produce smaller sized entities */
		ir_mode *const modes[] = { mode_F, mode_D, NULL };
		for (ir_mode *const *i = modes;; ++i) {
			ir_mode *const to = *i;
			if (!to || to == mode)
				break;
			if (tarval_ieee754_can_conv_lossless(tv, to)) {
				tv   = tarval_convert_to(tv, to);
				mode = to;
				break;
			}
		}
	}

309
	ir_entity *res = pmap_get(ir_entity, ia32_tv_ent, tv);
310
311
	if (!res) {
		if (!name)
312
			name = id_unique("C");
313

314
		ir_type *const tp = get_type_for_mode(mode);
315
316
317
		res = new_global_entity(get_glob_type(), name, tp,
		                        ir_visibility_private,
		                        IR_LINKAGE_CONSTANT | IR_LINKAGE_NO_IDENTITY);
318
319
320
321

		ir_initializer_t *const initializer = create_initializer_tarval(tv);
		set_entity_initializer(res, initializer);

322
		pmap_insert(ia32_tv_ent, tv, res);
323
324
325
326
	}
	return res;
}

327
328
329
static void set_am_const_entity(ir_node *node, ir_entity *entity)
{
	ia32_attr_t *const attr = get_ia32_attr(node);
330
	attr->addr.immediate = (x86_imm32_t) {
331
		.kind   = lconst_imm_kind,
332
333
		.entity = entity,
	};
334
	attr->addr.variant = lconst_variant;
335
336
}

337
338
339
/**
 * Transforms a Const.
 */
Christoph Mallon's avatar
Christoph Mallon committed
340
341
static ir_node *gen_Const(ir_node *node)
{
342
343
344
345
346
	ir_node        *const block = be_transform_nodes_block(node);
	dbg_info       *const dbgi  = get_irn_dbg_info(node);
	ir_mode        *const mode  = get_irn_mode(node);
	ir_tarval      *const tv    = get_Const_tarval(node);
	x86_insn_size_t const size  = x86_size_from_mode(mode);
347
348

	if (mode_is_float(mode)) {
349
		ir_graph *const irg = get_irn_irg(node);
350
		ir_node        *res;
351
		if (ia32_cg_config.use_sse2) {
352
			if (tarval_is_null(tv)) {
353
				res = new_bd_ia32_xZero(dbgi, block, size);
354
#ifdef CONSTRUCT_SSE_CONST
355
			} else if (tarval_is_one(tv)) {
356
357
358
359
360
361
362
				int      cnst    = mode == ia32_mode_float32 ? 26 : 55;
				ir_node *imm1    = ia32_create_Immediate(irg, cnst);
				ir_node *imm2    = ia32_create_Immediate(irg, 2);
				ir_node *allones = new_bd_ia32_xAllOnes(dbgi, block, size);
				ir_node *pslld   = new_bd_ia32_xPslld(dbgi, block, allones,
				                                      imm1, size);
				res = new_bd_ia32_xPsrld(dbgi, block, pslld, imm2, size);
363
#endif /* CONSTRUCT_SSE_CONST */
364
			} else if (mode == ia32_mode_float32) {
365
				/* we can place any 32bit constant by using a movd gp, sse */
366
367
368
				x86_imm32_t imm = {
					.offset = be_get_tv_bits32(tv, 0),
				};
369
				ir_node *cnst = new_bd_ia32_Const(dbgi, block, &imm);
370
				res = new_bd_ia32_xMovd(dbgi, block, cnst);
371
			} else {
372
#ifdef CONSTRUCT_SSE_CONST
373
374
375
376
				if (mode == ia32_mode_float64 && be_get_tv_bits32(tv, 0) == 0) {
					ir_node *imm32 = ia32_create_Immediate(irg, 32);

					/* fine, lower 32bit are zero, produce 32bit value */
377
378
379
380
381
382
					x86_imm32_t const imm = {
						.offset = be_get_tv_bits32(tv, 4),
					};
					ir_node *const cnst = new_bd_ia32_Const(dbgi, block, &imm);
					ir_node *const movd = new_bd_ia32_xMovd(dbgi, block, cnst);
					res = new_bd_ia32_xPsllq(dbgi, block, movd, imm32, size);
383
					goto end;
384
				}
385
#endif /* CONSTRUCT_SSE_CONST */
386
				ir_entity *const floatent = create_float_const_entity(tv, NULL);
387

388
				ir_node *base = get_global_base(irg);
389
390
				ir_node *load = new_bd_ia32_xLoad(dbgi, block, base, noreg_GP,
				                                  nomem, size);
Matthias Braun's avatar
Matthias Braun committed
391
				set_irn_pinned(load, false);
392
				set_ia32_op_type(load, ia32_AddrModeS);
393
				set_am_const_entity(load, floatent);
394
				arch_add_irn_flags(load, arch_irn_flag_rematerializable);
395
				res = be_new_Proj(load, pn_ia32_xLoad_res);
396
397
			}
		} else {
398
			if (tarval_is_null(tv)) {
399
				res = new_bd_ia32_fldz(dbgi, block);
400
			} else if (tarval_is_one(tv)) {
401
				res = new_bd_ia32_fld1(dbgi, block);
402
			} else if (tarval_is_minus_null(tv)) {
403
				res = new_bd_ia32_fldz(dbgi, block);
404
405
				goto negate;
			} else if (tarval_is_minus_one(tv)) {
406
				res = new_bd_ia32_fld1(dbgi, block);
407
negate:
408
				res = new_bd_ia32_fchs(dbgi, block, res);
409
			} else {
410
				ir_entity *const floatent = create_float_const_entity(tv, NULL);
411
412
				/* create_float_const_ent is smart and sometimes creates
				   smaller entities */
413
414
415
416
417
				ir_mode *ent_mode = get_type_mode(get_entity_type(floatent));
				x86_insn_size_t const size = x86_size_from_mode(ent_mode);
				ir_node *base = get_global_base(irg);
				ir_node *load = new_bd_ia32_fld(dbgi, block, base, noreg_GP,
				                                nomem, size);
Matthias Braun's avatar
Matthias Braun committed
418
				set_irn_pinned(load, false);
419
420
421
422
423
424
				ia32_attr_t *const attr = get_ia32_attr(load);
				attr->addr = (x86_addr_t) {
					.immediate = {
						.kind   = lconst_imm_kind,
						.entity = floatent,
					},
425
					.variant = lconst_variant,
426
				};
427
				set_ia32_op_type(load, ia32_AddrModeS);
428
				arch_add_irn_flags(load, arch_irn_flag_rematerializable);
429
				res = be_new_Proj(load, pn_ia32_fld_res);
430
431
			}
		}
432
#ifdef CONSTRUCT_SSE_CONST
433
end:
434
#endif
435
		return res;
436
	} else { /* non-float mode */
437
438
		ir_tarval *conv_tv = tarval_convert_to(tv, ia32_mode_gp);
		if (conv_tv == get_tarval_bad())
439
440
			panic("couldn't convert constant tarval (%+F)", node);

441
		x86_imm32_t imm = { .offset = get_tarval_long(conv_tv) };
442
		return new_bd_ia32_Const(dbgi, block, &imm);
443
444
445
446
	}
}

/**
447
 * Transforms an Address.
448
 */
449
static ir_node *gen_Address(ir_node *node)
Christoph Mallon's avatar
Christoph Mallon committed
450
{
451
452
453
	ir_node  *block = be_transform_nodes_block(node);
	dbg_info *dbgi  = get_irn_dbg_info(node);
	ir_mode  *mode  = get_irn_mode(node);
454

455
	if (!mode_needs_gp_reg(mode))
456
		panic("unexpected mode for Address");
457

458
	ir_entity *entity = get_Address_entity(node);
459
460
461
462
	x86_imm32_t imm = {
		.kind   = X86_IMM_ADDR,
		.entity = entity,
	};
463
	adjust_relocation(&imm);
464

465
	if (is_tls_entity(entity)) {
466
467
468
		ir_node     *const tls_base = new_bd_ia32_LdTls(NULL, block);
		ir_node     *const lea      = new_bd_ia32_Lea(dbgi, block, tls_base, noreg_GP);
		ia32_attr_t *const attr     = get_ia32_attr(lea);
469
		attr->addr.variant   = X86_ADDR_BASE;
470
		attr->addr.immediate = imm;
471
		return lea;
472
	} else {
473
		return new_bd_ia32_Const(dbgi, block, &imm);
474
475
476
	}
}

Matthias Braun's avatar
Matthias Braun committed
477
478
479
480
481
482
483
484
static ir_node *gen_be_Relocation(ir_node *node)
{
	ir_node  *block = be_transform_nodes_block(node);
	dbg_info *dbgi  = get_irn_dbg_info(node);
	x86_imm32_t imm = {
		.kind   = (x86_immediate_kind_t)be_get_Relocation_kind(node),
		.entity = be_get_Relocation_entity(node),
	};
485
	return new_bd_ia32_Const(dbgi, block, &imm);
Matthias Braun's avatar
Matthias Braun committed
486
487
}

Michael Beck's avatar
Michael Beck committed
488
489
490
491
492
/**
 * Create a float[2] array type for the given atomic type.
 *
 * @param tp  the atomic type
 */
493
494
static ir_type *ia32_create_float_array(ir_type *tp)
{
495
496
497
498
499
500
501
502
503
504
505
	static ir_type *float_F;
	static ir_type *float_D;
	static ir_type *float_E;
	ir_mode  *const mode = get_type_mode(tp);
	ir_type **const arr  =
		mode == ia32_mode_float32 ? &float_F :
		mode == ia32_mode_float64 ? &float_D :
		/*                       */ &float_E;
	if (!*arr)
		*arr = new_type_array(tp, 2);
	return *arr;
Michael Beck's avatar
Michael Beck committed
506
507
}

508
/* Generates an entity for a known FP const (used for FP Neg + Abs) */
509
ir_entity *ia32_gen_fp_known_const(ia32_known_const_t const kct)
Christoph Mallon's avatar
Christoph Mallon committed
510
{
511
	static const struct {
512
		const char *name;
513
		const char *cnst_str;
514
		char        mode;
515
	} names [ia32_known_const_max] = {
516
517
518
519
520
		{ "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 }
521
	};
522
	static ir_entity *ent_cache[ia32_known_const_max];
523

524
	ir_entity *ent = ent_cache[kct];
525

526
	if (ent == NULL) {
527
528
		char const *const cnst_str = names[kct].cnst_str;
		ident      *const name     = new_id_from_str(names[kct].name);
529
		ir_mode          *mode;
530
		switch (names[kct].mode) {
531
		case 0:  mode = ia32_mode_gp; break;
532
		case 1:  mode = mode_Lu; break;
533
		case 2:  mode = ia32_mode_float32;  break;
534
		default: panic("internal compiler error");
535
		}
536
		ir_tarval *tv = new_tarval_from_str(cnst_str, strlen(cnst_str), mode);
537

538
		if (kct == ia32_ULLBIAS) {
539
			ir_type *type  = get_type_for_mode(ia32_mode_float32);
540
			ir_type *atype = ia32_create_float_array(type);
541

542
543
544
			ent = new_global_entity(get_glob_type(), name, atype,
			                        ir_visibility_private,
			                        IR_LINKAGE_CONSTANT|IR_LINKAGE_NO_IDENTITY);
545

546
			ir_initializer_t *initializer = create_initializer_compound(2);
547
			set_initializer_compound_value(initializer, 0,
548
				create_initializer_tarval(get_mode_null(mode)));
549
550
551
552
			set_initializer_compound_value(initializer, 1,
				create_initializer_tarval(tv));
			set_entity_initializer(ent, initializer);
		} else {
553
			ent = create_float_const_entity(tv, name);
554
		}
555
556
		/* cache the entry */
		ent_cache[kct] = ent;
557
	}
558

559
	return ent_cache[kct];
560
561
}

562
563
564
565
566
567
568
569
570
571
static ir_node *gen_Unknown(ir_node *node)
{
	ir_mode  *mode  = get_irn_mode(node);
	dbg_info *dbgi  = get_irn_dbg_info(node);
	ir_graph *irg   = get_irn_irg(node);
	ir_node  *block = get_irg_start_block(irg);
	ir_node  *res   = NULL;

	if (mode_is_float(mode)) {
		if (ia32_cg_config.use_sse2) {
572
			res = new_bd_ia32_xUnknown(dbgi, block, X86_SIZE_128);
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
		} else {
			res = new_bd_ia32_fldz(dbgi, block);
		}
	} else if (mode_needs_gp_reg(mode)) {
		res = new_bd_ia32_Unknown(dbgi, block);
	} else {
		panic("unsupported Unknown-Mode");
	}

	return res;
}

/**
 * Checks whether other node inputs depend on the am_candidate (via mem-proj).
 */
static bool prevents_AM(ir_node *const block, ir_node *const am_candidate,
                        ir_node *const other)
{
	if (get_nodes_block(other) != block)
		return false;

	if (is_Sync(other)) {
		int i;

		for (i = get_Sync_n_preds(other) - 1; i >= 0; --i) {
			ir_node *const pred = get_Sync_pred(other, i);

			if (get_nodes_block(pred) != block)
				continue;

			/* Do not block ourselves from getting eaten */
			if (is_Proj(pred) && get_Proj_pred(pred) == am_candidate)
				continue;

			if (!heights_reachable_in_block(heights, pred, am_candidate))
				continue;

			return true;
		}

		return false;
	} else {
		/* Do not block ourselves from getting eaten */
		if (is_Proj(other) && get_Proj_pred(other) == am_candidate)
			return false;

		if (!heights_reachable_in_block(heights, other, am_candidate))
			return false;

		return true;
	}
}

626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
static bool cmp_can_use_sub_flags(ir_node *cmp, ir_node *sub, bool *swap)
{
	ir_node *cmp_block = get_nodes_block(cmp);
	ir_node *sub_block = get_nodes_block(sub);

	if (!(block_dominates(cmp_block, sub_block) ||
	      block_dominates(sub_block, cmp_block))) {
		return false;
	}

	ir_node *cmp_left  = get_Cmp_left(cmp);
	ir_node *cmp_right = get_Cmp_right(cmp);
	ir_node *sub_left  = get_Sub_left(sub);
	ir_node *sub_right = get_Sub_right(sub);

	if (cmp_left == sub_left && cmp_right == sub_right) {
		*swap = false;
	} else if (cmp_left == sub_right && cmp_right == sub_left) {
		*swap = true;
	} else {
		return false;
	}

	ir_mode *sub_mode = get_irn_mode(sub_left);
	if (get_mode_size_bits(sub_mode) != 32 &&
	    (!be_upper_bits_clean(sub_left,  sub_mode) ||
	     !be_upper_bits_clean(sub_right, sub_mode))) {
		return false;
	}

	return true;
}

659
660
661
662
663
664
665
/**
 * return true if the users of the given value will be merged by later
 * optimization. This applies to multiple Cmp nodes (and maybe a Sub
 * node) with the same inputs.
 */
static bool users_will_merge(ir_node *proj)
{
666
	ir_node *sub = NULL;
667

668
	/* Check that there is one Sub and some Cmps. */
669
670
671
	foreach_out_edge(proj, edge) {
		ir_node *user = get_edge_src_irn(edge);

672
673
674
		if (is_Sub(user)) {
			if (sub == NULL) {
				sub = user;
675
			} else {
676
				/* Two Subs will not merge */
677
678
				return false;
			}
679
680
681
682
		} else if (!is_Cmp(user)) {
			return false;
		}
	}
683

684
685
686
687
688
	if (sub == NULL) {
		/* Cmps only will not merge.
		 * (probably need to be rematerialized later anyway) */
		return false;
	}
689

690
691
	foreach_out_edge(proj, edge) {
		ir_node *user = get_edge_src_irn(edge);
692

693
694
695
		if (is_Cmp(user)) {
			bool dump;
			if (!cmp_can_use_sub_flags(user, sub, &dump)) {
696
697
698
699
700
701
702
				return false;
			}
		}
	}
	return true;
}

703
704
705
706
707
708
/**
 * 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).
 */
709
710
711
static bool ia32_use_source_address_mode(ir_node *block, ir_node *node,
                                         ir_node *other, ir_node *other2,
                                         match_flags_t flags)
712
{
713
	/* float constants are always available */
Michael Beck's avatar
Michael Beck committed
714
	if (is_Const(node)) {
715
		ir_mode *mode = get_irn_mode(node);
Michael Beck's avatar
Michael Beck committed
716
		if (mode_is_float(mode)) {
717
			ir_tarval *tv = get_Const_tarval(node);
718
			if (!tarval_ieee754_can_conv_lossless(tv, ia32_mode_float64))
719
				return false;
Michael Beck's avatar
Michael Beck committed
720
721
			if (ia32_cg_config.use_sse2) {
				if (is_simple_sse_Const(node))
722
					return false;
Michael Beck's avatar
Michael Beck committed
723
724
			} else {
				if (is_simple_x87_Const(node))
725
					return false;
Michael Beck's avatar
Michael Beck committed
726
727
			}
			if (get_irn_n_edges(node) > 1)
728
729
				return false;
			return true;
730
		}
731
		return false;
732
733
	}

Michael Beck's avatar
Michael Beck committed
734
	if (!is_Proj(node))
735
736
		return false;
	ir_node *load = get_Proj_pred(node);
737
	if (!is_Load(load))
738
		return false;
739
	assert(get_Proj_num(node) == pn_Load_res);
Michael Beck's avatar
Michael Beck committed
740
	if (get_nodes_block(load) != block)
741
742
		return false;
	ir_mode *mode = get_irn_mode(node);
743
	/* we can't fold mode_E AM */
744
	if (mode == x86_mode_E)
745
		return false;
746
747
748
749
	/* we only use address mode if we're the only user of the load
	 * or the users will be merged later anyway */
	if (get_irn_n_edges(node) != (flags & match_two_users ? 2 : 1) &&
	    !users_will_merge(node))
750
		return false;
751
752
753
	/* 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
754
	if (be_is_transformed(node))
755
		return false;
756
757

	/* don't do AM if other node inputs depend on the load (via mem-proj) */
758
	if (other != NULL && prevents_AM(block, load, other))
759
		return false;
760

761
	if (other2 != NULL && prevents_AM(block, load, other2))
762
		return false;
763

764
	return true;
765
766
767
768
}

typedef struct ia32_address_mode_t ia32_address_mode_t;
struct ia32_address_mode_t {
769
	x86_address_t   addr;
770
	ir_node        *mem_proj;
771
	x86_insn_size_t size;
772
773
774
	ia32_op_type_t  op_type;
	ir_node        *new_op1;
	ir_node        *new_op2;
Matthias Braun's avatar
Matthias Braun committed
775
	bool            pinned       : 1;
Matthias Braun's avatar
Matthias Braun committed
776
777
	unsigned        commutative  : 1;
	unsigned        ins_permuted : 1;
778
779
};

780
781
782
783
static void ia32_create_address_mode(x86_address_t *addr, ir_node *ptr,
                                     x86_create_am_flags_t flags)
{
	x86_create_address_mode(addr, ptr, flags);
784
	adjust_relocation(&addr->imm);
785
786
}

787
static void build_address_ptr(x86_address_t *addr, ir_node *ptr, ir_node *mem)
Matthias Braun's avatar
Matthias Braun committed
788
789
790
{
	/* construct load address */
	memset(addr, 0, sizeof(addr[0]));
791
	ia32_create_address_mode(addr, ptr, x86_create_am_normal);
Matthias Braun's avatar
Matthias Braun committed
792

793
794
795
796
797
798
799
	addr->variant = addr->base ? (addr->index ? X86_ADDR_BASE_INDEX
	                                          : X86_ADDR_BASE)
	                           : (addr->index ? X86_ADDR_INDEX
	                                          : X86_ADDR_JUST_IMM);
	addr->base    = addr->base  ? be_transform_node(addr->base)  : noreg_GP;
	addr->index   = addr->index ? be_transform_node(addr->index) : noreg_GP;
	addr->mem     = be_transform_node(mem);
Matthias Braun's avatar
Matthias Braun committed
800
801
}

802
static void build_address(ia32_address_mode_t *am, ir_node *node,
803
                          x86_create_am_flags_t flags)
804
{
805
	x86_address_t *addr = &am->addr;
806

807
	/* floating point immediates */
808
	if (is_Const(node)) {
809
810
		ir_graph  *const irg    = get_irn_irg(node);
		ir_tarval *const tv     = get_Const_tarval(node);
811
		ir_entity *const entity = create_float_const_entity(tv, NULL);
812
		addr->base        = get_global_base(irg);
813
814
		addr->index       = noreg_GP;
		addr->mem         = nomem;
815
		addr->imm         = (x86_imm32_t) {
816
			.kind   = lconst_imm_kind,
817
818
			.entity = entity,
		};
819
		addr->variant     = lconst_variant,
820
		adjust_relocation(&addr->imm);
821
		addr->tls_segment = false;
822
		am->size          = x86_size_from_mode(get_type_mode(get_entity_type(entity)));
Matthias Braun's avatar
Matthias Braun committed
823
		am->pinned        = false;
824
825
826
		return;
	}

827
828
829
830
831
	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);
832
	am->size         = x86_size_from_mode(get_Load_mode(load));
833
	am->mem_proj     = get_Proj_for_pn(load, pn_Load_M);
834
835

	/* construct load address */
836
	ia32_create_address_mode(addr, ptr, flags);
837

838
839
840
841
842
843
844
	addr->variant = addr->base ? (addr->index ? X86_ADDR_BASE_INDEX
	                                          : X86_ADDR_BASE)
	                           : (addr->index ? X86_ADDR_INDEX
	                                          : X86_ADDR_JUST_IMM);
	addr->base    = addr->base  ? be_transform_node(addr->base)  : noreg_GP;
	addr->index   = addr->index ? be_transform_node(addr->index) : noreg_GP;
	addr->mem     = new_mem;
845
846
}

847
static void set_address(ir_node *node, const x86_address_t *addr)
848
{
849
	ia32_attr_t *const attr = get_ia32_attr(node);
850
	attr->addr.immediate = addr->imm;
851
	attr->addr.log_scale = addr->scale;
852
	attr->addr.variant   = addr->variant;
853
854
	if (addr->tls_segment)
		attr->addr.segment = X86_SEGMENT_GS;
855
	if (addr->imm.kind == X86_IMM_FRAMEENT)
856
		set_ia32_frame_use(node, IA32_FRAME_USE_AUTO);
857
858
}

Michael Beck's avatar
Michael Beck committed
859
860
861
/**
 * Apply attributes of a given address mode to a node.
 */
862
static void set_am_attributes(ir_node *node, const ia32_address_mode_t *am)
863
864
{
	set_address(node, &am->addr);
865

866
	set_ia32_op_type(node, am->op_type);
867
868
	if (am->pinned && !get_irn_pinned(node))
		set_irn_pinned(node, true);
Michael Beck's avatar
Michael Beck committed
869
	if (am->commutative)
870
871
		set_ia32_commutative(node);
}
872

873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
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);