bearch_ia32.c 60.6 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

Christian Würdig's avatar
Christian Würdig committed
20
/**
Christian Würdig's avatar
Christian Würdig committed
21
22
23
24
 * @file
 * @brief       This is the main ia32 firm backend driver.
 * @author      Christian Wuerdig
 * @version     $Id$
Christian Würdig's avatar
Christian Würdig committed
25
 */
26
#include "config.h"
27

Matthias Braun's avatar
Matthias Braun committed
28
29
#include "lc_opts.h"
#include "lc_opts_enum.h"
30

Christian Würdig's avatar
Christian Würdig committed
31
32
#include <math.h>

Christoph Mallon's avatar
Christoph Mallon committed
33
#include "irarch.h"
Christian Würdig's avatar
Christian Würdig committed
34
#include "irgwalk.h"
Christian Würdig's avatar
Christian Würdig committed
35
36
#include "irprog.h"
#include "irprintf.h"
37
#include "iredges_t.h"
38
#include "ircons.h"
39
#include "irflag.h"
Christian Würdig's avatar
Christian Würdig committed
40
#include "irgmod.h"
Christian Würdig's avatar
Christian Würdig committed
41
#include "irgopt.h"
42
#include "irbitset.h"
43
#include "irgopt.h"
44
#include "irdump.h"
45
#include "pdeq.h"
46
#include "pset.h"
Christian Würdig's avatar
Christian Würdig committed
47
#include "debug.h"
48
#include "error.h"
49
#include "xmalloc.h"
Michael Beck's avatar
Michael Beck committed
50
#include "irtools.h"
Matthias Braun's avatar
Matthias Braun committed
51
#include "iroptimize.h"
Michael Beck's avatar
Michael Beck committed
52
#include "instrument.h"
53
#include "iropt_t.h"
Christian Würdig's avatar
Christian Würdig committed
54

55
#include "../beabi.h"
56
#include "../beirg.h"
57
#include "../benode.h"
58
#include "../belower.h"
59
#include "../besched.h"
60
#include "be.h"
Christian Würdig's avatar
Christian Würdig committed
61
#include "../be_t.h"
62
#include "../beirgmod.h"
Michael Beck's avatar
Michael Beck committed
63
#include "../be_dbgout.h"
Matthias Braun's avatar
Matthias Braun committed
64
#include "../beblocksched.h"
65
#include "../bemachine.h"
66
#include "../bespillslots.h"
67
#include "../bemodule.h"
Matthias Braun's avatar
Matthias Braun committed
68
#include "../begnuas.h"
69
#include "../bestate.h"
70
#include "../beflags.h"
71
#include "../betranshlp.h"
72
#include "../belistsched.h"
73
#include "../beabihelper.h"
74

75
#include "bearch_ia32_t.h"
Christian Würdig's avatar
Christian Würdig committed
76

77
78
#include "ia32_new_nodes.h"
#include "gen_ia32_regalloc_if.h"
79
#include "gen_ia32_machine.h"
80
#include "ia32_common_transform.h"
Christian Würdig's avatar
Christian Würdig committed
81
#include "ia32_transform.h"
Christian Würdig's avatar
Christian Würdig committed
82
83
#include "ia32_emitter.h"
#include "ia32_map_regs.h"
Christian Würdig's avatar
Christian Würdig committed
84
#include "ia32_optimize.h"
85
#include "ia32_x87.h"
86
#include "ia32_dbg_stat.h"
Christian Würdig's avatar
Christian Würdig committed
87
#include "ia32_finish.h"
88
#include "ia32_util.h"
89
#include "ia32_fpu.h"
90
#include "ia32_architecture.h"
91

92
93
#ifdef FIRM_GRGEN_BE
#include "ia32_pbqp_transform.h"
94
95

transformer_t be_transformer = TRANSFORMER_DEFAULT;
96
97
#endif

98
DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
Christian Würdig's avatar
Christian Würdig committed
99

100
ir_mode         *mode_fpcw       = NULL;
101

102
103
104
105
106
107
108
109
/** The current omit-fp state */
static unsigned ia32_curr_fp_ommitted  = 0;
static ir_type *omit_fp_between_type   = NULL;
static ir_type *between_type           = NULL;
static ir_entity *old_bp_ent           = NULL;
static ir_entity *ret_addr_ent         = NULL;
static ir_entity *omit_fp_ret_addr_ent = NULL;

110
111
112
113
114
115
116
117
118
119
120
121
122
/**
 * The environment for the intrinsic mapping.
 */
static ia32_intrinsic_env_t intrinsic_env = {
	NULL,    /* the isa */
	NULL,    /* the irg, these entities belong to */
	NULL,    /* entity for __divdi3 library call */
	NULL,    /* entity for __moddi3 library call */
	NULL,    /* entity for __udivdi3 library call */
	NULL,    /* entity for __umoddi3 library call */
};


123
typedef ir_node *(*create_const_node_func) (dbg_info *dbg, ir_node *block);
124

125
/**
126
 * Used to create per-graph unique pseudo nodes.
127
 */
128
static inline ir_node *create_const(ir_graph *irg, ir_node **place,
129
                                    create_const_node_func func,
130
                                    const arch_register_t* reg)
131
132
133
{
	ir_node *block, *res;

134
	if (*place != NULL)
135
136
		return *place;

137
	block = get_irg_start_block(irg);
138
	res = func(NULL, block);
139
	arch_set_irn_register(res, reg);
140
141
142
143
144
	*place = res;

	return res;
}

145
/* Creates the unique per irg GP NoReg node. */
146
ir_node *ia32_new_NoReg_gp(ir_graph *irg)
147
{
148
149
	ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
	return create_const(irg, &irg_data->noreg_gp, new_bd_ia32_NoReg_GP,
150
	                    &ia32_registers[REG_GP_NOREG]);
151
152
}

153
ir_node *ia32_new_NoReg_vfp(ir_graph *irg)
154
{
155
156
	ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
	return create_const(irg, &irg_data->noreg_vfp, new_bd_ia32_NoReg_VFP,
157
	                    &ia32_registers[REG_VFP_NOREG]);
158
159
}

160
ir_node *ia32_new_NoReg_xmm(ir_graph *irg)
161
{
162
163
	ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
	return create_const(irg, &irg_data->noreg_xmm, new_bd_ia32_NoReg_XMM,
164
	                    &ia32_registers[REG_XMM_NOREG]);
165
166
}

167
ir_node *ia32_new_Fpu_truncate(ir_graph *irg)
168
{
169
170
	ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
	return create_const(irg, &irg_data->fpu_trunc_mode, new_bd_ia32_ChangeCW,
171
                        &ia32_registers[REG_FPCW]);
172
173
}

174

175
/**
176
 * Returns the admissible noreg register node for input register pos of node irn.
177
 */
178
static ir_node *ia32_get_admissible_noreg(ir_node *irn, int pos)
179
{
180
	ir_graph                  *irg = get_irn_irg(irn);
181
	const arch_register_req_t *req = arch_get_register_req(irn, pos);
182

Matthias Braun's avatar
Matthias Braun committed
183
184
	assert(req != NULL && "Missing register requirements");
	if (req->cls == &ia32_reg_classes[CLASS_ia32_gp])
185
		return ia32_new_NoReg_gp(irg);
Matthias Braun's avatar
Matthias Braun committed
186

187
	if (ia32_cg_config.use_sse2) {
188
		return ia32_new_NoReg_xmm(irg);
189
	} else {
190
		return ia32_new_NoReg_vfp(irg);
191
	}
192
193
}

194
195
static arch_irn_class_t ia32_classify(const ir_node *irn)
{
196
	arch_irn_class_t classification = 0;
197

198
	assert(is_ia32_irn(irn));
199

200
	if (is_ia32_is_reload(irn))
201
202
		classification |= arch_irn_class_reload;

203
204
205
	if (is_ia32_is_spill(irn))
		classification |= arch_irn_class_spill;

Matthias Braun's avatar
Matthias Braun committed
206
207
208
	if (is_ia32_is_remat(irn))
		classification |= arch_irn_class_remat;

209
	return classification;
Christian Würdig's avatar
Christian Würdig committed
210
}
Christian Würdig's avatar
Christian Würdig committed
211

212
213
214
/**
 * The IA32 ABI callback object.
 */
215
typedef struct {
216
217
	be_abi_call_flags_bits_t flags;  /**< The call flags. */
	ir_graph *irg;                   /**< The associated graph. */
218
219
} ia32_abi_env_t;

220
221
static ir_entity *ia32_get_frame_entity(const ir_node *irn)
{
Christian Würdig's avatar
Christian Würdig committed
222
	return is_ia32_irn(irn) ? get_ia32_frame_ent(irn) : NULL;
223
224
}

225
static void ia32_set_frame_entity(ir_node *node, ir_entity *entity)
226
{
227
228
229
230
	if (is_be_node(node))
		be_node_set_frame_entity(node, entity);
	else
		set_ia32_frame_ent(node, entity);
231
232
}

233
static void ia32_set_frame_offset(ir_node *irn, int bias)
234
235
236
{
	if (get_ia32_frame_ent(irn) == NULL)
		return;
237

238
	if (is_ia32_Pop(irn) || is_ia32_PopMem(irn)) {
239
240
241
		ir_graph          *irg     = get_irn_irg(irn);
		be_stack_layout_t *layout  = be_get_irg_stack_layout(irg);
		if (layout->sp_relative) {
242
243
244
245
246
			/* Pop nodes modify the stack pointer before calculating the
			 * destination address, so fix this here
			 */
			bias -= 4;
		}
247
	}
248
	add_ia32_am_offs_int(irn, bias);
249
250
}

251
static int ia32_get_sp_bias(const ir_node *node)
252
{
253
254
255
	if (is_ia32_Call(node))
		return -(int)get_ia32_call_attr_const(node)->pop;

256
257
258
	if (is_ia32_Push(node))
		return 4;

259
	if (is_ia32_Pop(node) || is_ia32_PopMem(node))
260
		return -4;
261
262
263
264

	return 0;
}

265
/**
Michael Beck's avatar
Michael Beck committed
266
 * Generate the routine prologue.
267
 *
268
269
270
271
 * @param self       The callback object.
 * @param mem        A pointer to the mem node. Update this if you define new memory.
 * @param reg_map    A map mapping all callee_save/ignore/parameter registers to their defining nodes.
 * @param stack_bias Points to the current stack bias, can be modified if needed.
272
 *
273
 * @return           The register which shall be used as a stack frame base.
274
275
276
 *
 * All nodes which define registers in @p reg_map must keep @p reg_map current.
 */
277
static const arch_register_t *ia32_abi_prologue(void *self, ir_node **mem, pmap *reg_map, int *stack_bias)
Sebastian Hack's avatar
Sebastian Hack committed
278
{
279
	ia32_abi_env_t   *env      = self;
280
281
	ir_graph         *irg      = env->irg;
	const arch_env_t *arch_env = be_get_irg_arch_env(irg);
Sebastian Hack's avatar
Sebastian Hack committed
282

283
	ia32_curr_fp_ommitted = env->flags.try_omit_fp;
Christian Würdig's avatar
Christian Würdig committed
284
	if (! env->flags.try_omit_fp) {
285
		ir_node  *bl      = get_irg_start_block(env->irg);
286
287
		ir_node  *curr_sp = be_abi_reg_map_get(reg_map, arch_env->sp);
		ir_node  *curr_bp = be_abi_reg_map_get(reg_map, arch_env->bp);
288
		ir_node  *noreg   = ia32_new_NoReg_gp(irg);
289
		ir_node  *push;
Sebastian Hack's avatar
Sebastian Hack committed
290

291
292
293
		/* mark bp register as ignore */
		be_set_constr_single_reg_out(get_Proj_pred(curr_bp),
				get_Proj_proj(curr_bp), arch_env->bp, arch_register_req_type_ignore);
294

295
		/* push ebp */
296
		push    = new_bd_ia32_Push(NULL, bl, noreg, noreg, *mem, curr_bp, curr_sp);
297
298
		curr_sp = new_r_Proj(push, get_irn_mode(curr_sp), pn_ia32_Push_stack);
		*mem    = new_r_Proj(push, mode_M, pn_ia32_Push_M);
299
300

		/* the push must have SP out register */
301
		arch_set_irn_register(curr_sp, arch_env->sp);
302

303
304
305
		/* this modifies the stack bias, because we pushed 32bit */
		*stack_bias -= 4;

306
		/* move esp to ebp */
307
		curr_bp = be_new_Copy(arch_env->bp->reg_class, bl, curr_sp);
308
309
		be_set_constr_single_reg_out(curr_bp, 0, arch_env->bp,
		                             arch_register_req_type_ignore);
Sebastian Hack's avatar
Sebastian Hack committed
310

311
		/* beware: the copy must be done before any other sp use */
312
		curr_sp = be_new_CopyKeep_single(arch_env->sp->reg_class, bl, curr_sp, curr_bp, get_irn_mode(curr_sp));
313
314
		be_set_constr_single_reg_out(curr_sp, 0, arch_env->sp,
				                     arch_register_req_type_produces_sp);
315

316
317
		be_abi_reg_map_set(reg_map, arch_env->sp, curr_sp);
		be_abi_reg_map_set(reg_map, arch_env->bp, curr_bp);
318

319
		return arch_env->bp;
Sebastian Hack's avatar
Sebastian Hack committed
320
321
	}

322
	return arch_env->sp;
Sebastian Hack's avatar
Sebastian Hack committed
323
324
}

Michael Beck's avatar
Michael Beck committed
325
326
327
/**
 * Generate the routine epilogue.
 * @param self    The callback object.
328
 * @param bl      The block for the epilog
Michael Beck's avatar
Michael Beck committed
329
330
331
332
333
334
 * @param mem     A pointer to the mem node. Update this if you define new memory.
 * @param reg_map A map mapping all callee_save/ignore/parameter registers to their defining nodes.
 * @return        The register which shall be used as a stack frame base.
 *
 * All nodes which define registers in @p reg_map must keep @p reg_map current.
 */
Sebastian Hack's avatar
Sebastian Hack committed
335
336
static void ia32_abi_epilogue(void *self, ir_node *bl, ir_node **mem, pmap *reg_map)
{
337
	ia32_abi_env_t   *env      = self;
338
	const arch_env_t *arch_env = be_get_irg_arch_env(env->irg);
339
340
	ir_node          *curr_sp  = be_abi_reg_map_get(reg_map, arch_env->sp);
	ir_node          *curr_bp  = be_abi_reg_map_get(reg_map, arch_env->bp);
Sebastian Hack's avatar
Sebastian Hack committed
341

342
343
	if (env->flags.try_omit_fp) {
		/* simply remove the stack frame here */
344
		curr_sp = be_new_IncSP(arch_env->sp, bl, curr_sp, BE_STACK_FRAME_SIZE_SHRINK, 0);
345
	} else {
346
		ir_mode *mode_bp = arch_env->bp->reg_class->mode;
Sebastian Hack's avatar
Sebastian Hack committed
347

348
		if (ia32_cg_config.use_leave) {
349
			ir_node *leave;
350

351
			/* leave */
352
			leave   = new_bd_ia32_Leave(NULL, bl, curr_bp);
353
354
			curr_bp = new_r_Proj(leave, mode_bp, pn_ia32_Leave_frame);
			curr_sp = new_r_Proj(leave, get_irn_mode(curr_sp), pn_ia32_Leave_stack);
355
		} else {
356
357
			ir_node *pop;

Christoph Mallon's avatar
Christoph Mallon committed
358
359
			/* the old SP is not needed anymore (kill the proj) */
			assert(is_Proj(curr_sp));
360
			kill_node(curr_sp);
Christoph Mallon's avatar
Christoph Mallon committed
361

362
			/* copy ebp to esp */
363
			curr_sp = be_new_Copy(&ia32_reg_classes[CLASS_ia32_gp], bl, curr_bp);
364
			arch_set_irn_register(curr_sp, arch_env->sp);
365
366
			be_set_constr_single_reg_out(curr_sp, 0, arch_env->sp,
				                         arch_register_req_type_ignore);
367
368

			/* pop ebp */
369
			pop     = new_bd_ia32_PopEbp(NULL, bl, *mem, curr_sp);
370
371
			curr_bp = new_r_Proj(pop, mode_bp, pn_ia32_Pop_res);
			curr_sp = new_r_Proj(pop, get_irn_mode(curr_sp), pn_ia32_Pop_stack);
372

373
			*mem = new_r_Proj(pop, mode_M, pn_ia32_Pop_M);
374
		}
375
376
		arch_set_irn_register(curr_sp, arch_env->sp);
		arch_set_irn_register(curr_bp, arch_env->bp);
Sebastian Hack's avatar
Sebastian Hack committed
377
378
	}

379
380
	be_abi_reg_map_set(reg_map, arch_env->sp, curr_sp);
	be_abi_reg_map_set(reg_map, arch_env->bp, curr_bp);
Sebastian Hack's avatar
Sebastian Hack committed
381
382
}

383
384
385
386
387
388
/**
 * Initialize the callback object.
 * @param call The call object.
 * @param irg  The graph with the method.
 * @return     Some pointer. This pointer is passed to all other callback functions as self object.
 */
389
static void *ia32_abi_init(const be_abi_call_t *call, ir_graph *irg)
390
{
391
392
	ia32_abi_env_t      *env = XMALLOC(ia32_abi_env_t);
	be_abi_call_flags_t  fl  = be_abi_call_get_flags(call);
393
394
395
396
397
398
399
400
401
	env->flags = fl.bits;
	env->irg   = irg;
	return env;
}

/**
 * Destroy the callback object.
 * @param self The callback object.
 */
402
403
static void ia32_abi_done(void *self)
{
404
405
406
	free(self);
}

Sebastian Hack's avatar
Sebastian Hack committed
407
/**
408
 * Build the between type and entities if not already build.
Sebastian Hack's avatar
Sebastian Hack committed
409
 */
410
411
static void ia32_build_between_type(void)
{
412
#define IDENT(s) new_id_from_chars(s, sizeof(s)-1)
413
	if (! between_type) {
414
415
		ir_type *old_bp_type   = new_type_primitive(mode_Iu);
		ir_type *ret_addr_type = new_type_primitive(mode_Iu);
Sebastian Hack's avatar
Sebastian Hack committed
416

417
418
419
		between_type           = new_type_struct(IDENT("ia32_between_type"));
		old_bp_ent             = new_entity(between_type, IDENT("old_bp"), old_bp_type);
		ret_addr_ent           = new_entity(between_type, IDENT("ret_addr"), ret_addr_type);
Sebastian Hack's avatar
Sebastian Hack committed
420

421
422
423
		set_entity_offset(old_bp_ent, 0);
		set_entity_offset(ret_addr_ent, get_type_size_bytes(old_bp_type));
		set_type_size_bytes(between_type, get_type_size_bytes(old_bp_type) + get_type_size_bytes(ret_addr_type));
424
		set_type_state(between_type, layout_fixed);
425
426
427
428
429
430
431

		omit_fp_between_type = new_type_struct(IDENT("ia32_between_type_omit_fp"));
		omit_fp_ret_addr_ent = new_entity(omit_fp_between_type, IDENT("ret_addr"), ret_addr_type);

		set_entity_offset(omit_fp_ret_addr_ent, 0);
		set_type_size_bytes(omit_fp_between_type, get_type_size_bytes(ret_addr_type));
		set_type_state(omit_fp_between_type, layout_fixed);
Sebastian Hack's avatar
Sebastian Hack committed
432
	}
433
434
435
436
437
438
439
440
441
442
443
#undef IDENT
}

/**
 * Produces the type which sits between the stack args and the locals on the stack.
 * it will contain the return address and space to store the old base pointer.
 * @return The Firm type modeling the ABI between type.
 */
static ir_type *ia32_abi_get_between_type(void *self)
{
	ia32_abi_env_t *env = self;
Sebastian Hack's avatar
Sebastian Hack committed
444

445
	ia32_build_between_type();
446
	return env->flags.try_omit_fp ? omit_fp_between_type : between_type;
447
448
449
450
451
}

/**
 * Return the stack entity that contains the return address.
 */
452
453
ir_entity *ia32_get_return_address_entity(void)
{
454
455
	ia32_build_between_type();
	return ia32_curr_fp_ommitted ? omit_fp_ret_addr_ent : ret_addr_ent;
456
457
458
459
460
}

/**
 * Return the stack entity that contains the frame address.
 */
461
462
ir_entity *ia32_get_frame_address_entity(void)
{
463
464
	ia32_build_between_type();
	return ia32_curr_fp_ommitted ? NULL : old_bp_ent;
Sebastian Hack's avatar
Sebastian Hack committed
465
466
}

467
468
469
470
471
472
473
474
/**
 * Get the estimated cycle count for @p irn.
 *
 * @param self The this pointer.
 * @param irn  The node.
 *
 * @return     The estimated cycle count for this operation
 */
475
static int ia32_get_op_estimated_cost(const ir_node *irn)
476
{
477
	int            cost;
Christian Würdig's avatar
Christian Würdig committed
478
	ia32_op_type_t op_tp;
Adam Szalkowski's avatar
Adam Szalkowski committed
479

Christian Würdig's avatar
Christian Würdig committed
480
	if (is_Proj(irn))
481
482
483
		return 0;
	if (!is_ia32_irn(irn))
		return 0;
Adam Szalkowski's avatar
Adam Szalkowski committed
484

Christian Würdig's avatar
Christian Würdig committed
485
486
487
488
489
490
491
492
493
	assert(is_ia32_irn(irn));

	cost  = get_ia32_latency(irn);
	op_tp = get_ia32_op_type(irn);

	if (is_ia32_CopyB(irn)) {
		cost = 250;
	}
	else if (is_ia32_CopyB_i(irn)) {
Michael Beck's avatar
Michael Beck committed
494
		int size = get_ia32_copyb_size(irn);
Christian Würdig's avatar
Christian Würdig committed
495
496
497
498
499
		cost     = 20 + (int)ceil((4/3) * size);
	}
	/* in case of address mode operations add additional cycles */
	else if (op_tp == ia32_AddrModeD || op_tp == ia32_AddrModeS) {
		/*
500
501
502
			In case of stack access and access to fixed addresses add 5 cycles
			(we assume they are in cache), other memory operations cost 20
			cycles.
Christian Würdig's avatar
Christian Würdig committed
503
		*/
504
		if (is_ia32_use_frame(irn) || (
505
506
		    is_ia32_NoReg_GP(get_irn_n(irn, n_ia32_base)) &&
		    is_ia32_NoReg_GP(get_irn_n(irn, n_ia32_index))
507
		    )) {
508
509
510
511
			cost += 5;
		} else {
			cost += 20;
		}
Christian Würdig's avatar
Christian Würdig committed
512
513
514
	}

	return cost;
515
516
}

Christian Würdig's avatar
Christian Würdig committed
517
518
519
520
521
522
523
524
525
/**
 * Returns the inverse operation if @p irn, recalculating the argument at position @p i.
 *
 * @param irn       The original operation
 * @param i         Index of the argument we want the inverse operation to yield
 * @param inverse   struct to be filled with the resulting inverse op
 * @param obstack   The obstack to use for allocation of the returned nodes array
 * @return          The inverse operation or NULL if operation invertible
 */
526
527
static arch_inverse_t *ia32_get_inverse(const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obst)
{
528
529
530
531
532
533
534
	(void) irn;
	(void) i;
	(void) inverse;
	(void) obst;
	return NULL;

#if 0
535
	ir_mode  *mode;
536
	ir_mode  *irn_mode;
537
	ir_node  *block, *noreg, *nomem;
538
	dbg_info *dbg;
539
540
541
542
543
544

	/* we cannot invert non-ia32 irns */
	if (! is_ia32_irn(irn))
		return NULL;

	/* operand must always be a real operand (not base, index or mem) */
545
	if (i != n_ia32_binary_left && i != n_ia32_binary_right)
546
547
548
549
550
551
		return NULL;

	/* we don't invert address mode operations */
	if (get_ia32_op_type(irn) != ia32_Normal)
		return NULL;

552
553
554
555
556
	/* TODO: adjust for new immediates... */
	ir_fprintf(stderr, "TODO: fix get_inverse for new immediates (%+F)\n",
	           irn);
	return NULL;

557
	block    = get_nodes_block(irn);
558
	mode     = get_irn_mode(irn);
559
560
	irn_mode = get_irn_mode(irn);
	noreg    = get_irn_n(irn, 0);
561
	nomem    = new_r_NoMem(irg);
562
	dbg      = get_irn_dbg_info(irn);
563
564

	/* initialize structure */
565
	inverse->nodes = obstack_alloc(obst, 2 * sizeof(inverse->nodes[0]));
566
	inverse->costs = 0;
567
	inverse->n     = 1;
568

569
	switch (get_ia32_irn_opcode(irn)) {
570
		case iro_ia32_Add:
571
#if 0
572
573
574
			if (get_ia32_immop_type(irn) == ia32_ImmConst) {
				/* we have an add with a const here */
				/* invers == add with negated const */
575
				inverse->nodes[0] = new_bd_ia32_Add(dbg, block, noreg, noreg, nomem, get_irn_n(irn, i), noreg);
576
577
578
579
580
581
582
583
				inverse->costs   += 1;
				copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
				set_ia32_Immop_tarval(inverse->nodes[0], tarval_neg(get_ia32_Immop_tarval(irn)));
				set_ia32_commutative(inverse->nodes[0]);
			}
			else if (get_ia32_immop_type(irn) == ia32_ImmSymConst) {
				/* we have an add with a symconst here */
				/* invers == sub with const */
584
				inverse->nodes[0] = new_bd_ia32_Sub(dbg, block, noreg, noreg, nomem, get_irn_n(irn, i), noreg);
585
				inverse->costs   += 2;
586
587
588
589
				copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
			}
			else {
				/* normal add: inverse == sub */
590
				inverse->nodes[0] = new_bd_ia32_Sub(dbg, block, noreg, noreg, nomem, (ir_node*) irn, get_irn_n(irn, i ^ 1));
591
				inverse->costs   += 2;
592
			}
593
#endif
594
595
			break;
		case iro_ia32_Sub:
596
#if 0
597
598
599
			if (get_ia32_immop_type(irn) != ia32_ImmNone) {
				/* we have a sub with a const/symconst here */
				/* invers == add with this const */
600
				inverse->nodes[0] = new_bd_ia32_Add(dbg, block, noreg, noreg, nomem, get_irn_n(irn, i), noreg);
601
602
603
604
605
				inverse->costs   += (get_ia32_immop_type(irn) == ia32_ImmSymConst) ? 5 : 1;
				copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
			}
			else {
				/* normal sub */
606
				if (i == n_ia32_binary_left) {
607
					inverse->nodes[0] = new_bd_ia32_Add(dbg, block, noreg, noreg, nomem, (ir_node*) irn, get_irn_n(irn, 3));
608
609
				}
				else {
610
					inverse->nodes[0] = new_bd_ia32_Sub(dbg, block, noreg, noreg, nomem, get_irn_n(irn, n_ia32_binary_left), (ir_node*) irn);
611
612
613
				}
				inverse->costs += 1;
			}
614
#endif
615
			break;
616
		case iro_ia32_Xor:
617
#if 0
618
619
			if (get_ia32_immop_type(irn) != ia32_ImmNone) {
				/* xor with const: inverse = xor */
620
				inverse->nodes[0] = new_bd_ia32_Xor(dbg, block, noreg, noreg, nomem, get_irn_n(irn, i), noreg);
621
622
623
624
625
				inverse->costs   += (get_ia32_immop_type(irn) == ia32_ImmSymConst) ? 5 : 1;
				copy_ia32_Immop_attr(inverse->nodes[0], (ir_node *)irn);
			}
			else {
				/* normal xor */
626
				inverse->nodes[0] = new_bd_ia32_Xor(dbg, block, noreg, noreg, nomem, (ir_node *) irn, get_irn_n(irn, i));
627
628
				inverse->costs   += 1;
			}
629
#endif
630
			break;
631
		case iro_ia32_Not: {
632
			inverse->nodes[0] = new_bd_ia32_Not(dbg, block, (ir_node*) irn);
633
634
			inverse->costs   += 1;
			break;
635
		}
636
		case iro_ia32_Neg: {
637
			inverse->nodes[0] = new_bd_ia32_Neg(dbg, block, (ir_node*) irn);
638
639
			inverse->costs   += 1;
			break;
640
		}
641
642
643
644
645
646
		default:
			/* inverse operation not supported */
			return NULL;
	}

	return inverse;
647
#endif
Christian Würdig's avatar
Christian Würdig committed
648
649
}

650
651
static ir_mode *get_spill_mode_mode(const ir_mode *mode)
{
652
	if (mode_is_float(mode))
653
654
655
656
657
		return mode_D;

	return mode_Iu;
}

658
659
660
/**
 * Get the mode that should be used for spilling value node
 */
661
static ir_mode *get_spill_mode(const ir_node *node)
662
663
{
	ir_mode *mode = get_irn_mode(node);
664
	return get_spill_mode_mode(mode);
665
666
667
}

/**
Michael Beck's avatar
Michael Beck committed
668
 * Checks whether an addressmode reload for a node with mode mode is compatible
669
670
671
672
 * with a spillslot of mode spill_mode
 */
static int ia32_is_spillmode_compatible(const ir_mode *mode, const ir_mode *spillmode)
{
673
	return !mode_is_float(mode) || mode == spillmode;
674
675
}

676
/**
Christoph Mallon's avatar
Christoph Mallon committed
677
 * Check if irn can load its operand at position i from memory (source addressmode).
678
679
680
681
 * @param irn    The irn to be checked
 * @param i      The operands position
 * @return Non-Zero if operand can be loaded
 */
682
683
684
685
static int ia32_possible_memory_operand(const ir_node *irn, unsigned int i)
{
	ir_node       *op        = get_irn_n(irn, i);
	const ir_mode *mode      = get_irn_mode(op);
686
	const ir_mode *spillmode = get_spill_mode(op);
687

688
689
690
691
	if (!is_ia32_irn(irn)                              ||  /* must be an ia32 irn */
	    get_ia32_op_type(irn) != ia32_Normal           ||  /* must not already be a addressmode irn */
	    !ia32_is_spillmode_compatible(mode, spillmode) ||
	    is_ia32_use_frame(irn))                            /* must not already use frame */
692
693
		return 0;

694
695
696
697
	switch (get_ia32_am_support(irn)) {
		case ia32_am_none:
			return 0;

698
		case ia32_am_unary:
699
700
701
			if (i != n_ia32_unary_op)
				return 0;
			break;
702
703
704
705
706
707
708
709
710
711
712

		case ia32_am_binary:
			switch (i) {
				case n_ia32_binary_left: {
					const arch_register_req_t *req;
					if (!is_ia32_commutative(irn))
						return 0;

					/* we can't swap left/right for limited registers
					 * (As this (currently) breaks constraint handling copies)
					 */
713
					req = arch_get_in_register_req(irn, n_ia32_binary_left);
714
715
					if (req->type & arch_register_req_type_limited)
						return 0;
716
					break;
717
718
719
				}

				case n_ia32_binary_right:
720
					break;
721

722
723
724
				default:
					return 0;
			}
725
			break;
726
727

		default:
728
			panic("Unknown AM type");
729
	}
730
731
732
733
734
735
736

	/* HACK: must not already use "real" memory.
	 * This can happen for Call and Div */
	if (!is_NoMem(get_irn_n(irn, n_ia32_mem)))
		return 0;

	return 1;
737
738
}

739
740
static void ia32_perform_memory_operand(ir_node *irn, ir_node *spill,
                                        unsigned int i)
741
{
742
743
744
	ir_mode *load_mode;
	ir_mode *dest_op_mode;

745
	assert(ia32_possible_memory_operand(irn, i) && "Cannot perform memory operand change");
746
747

	set_ia32_op_type(irn, ia32_AddrModeS);
748
749
750
751
752
753

	load_mode    = get_irn_mode(get_irn_n(irn, i));
	dest_op_mode = get_ia32_ls_mode(irn);
	if (get_mode_size_bits(load_mode) <= get_mode_size_bits(dest_op_mode)) {
		set_ia32_ls_mode(irn, load_mode);
	}
754
	set_ia32_use_frame(irn);
755
	set_ia32_need_stackent(irn);
756

757
758
	if (i == n_ia32_binary_left                    &&
	    get_ia32_am_support(irn) == ia32_am_binary &&
759
760
	    /* immediates are only allowed on the right side */
	    !is_ia32_Immediate(get_irn_n(irn, n_ia32_binary_right))) {
761
		ia32_swap_left_right(irn);
762
		i = n_ia32_binary_right;
763
	}
764

765
766
	assert(is_NoMem(get_irn_n(irn, n_ia32_mem)));

767
768
	set_irn_n(irn, n_ia32_base, get_irg_frame(get_irn_irg(irn)));
	set_irn_n(irn, n_ia32_mem,  spill);
769
	set_irn_n(irn, i,           ia32_get_admissible_noreg(irn, i));
770
	set_ia32_is_reload(irn);
771
772
}

Sebastian Hack's avatar
Sebastian Hack committed
773
774
static const be_abi_callbacks_t ia32_abi_callbacks = {
	ia32_abi_init,
775
	ia32_abi_done,
Sebastian Hack's avatar
Sebastian Hack committed
776
777
	ia32_abi_get_between_type,
	ia32_abi_prologue,
778
	ia32_abi_epilogue
Sebastian Hack's avatar
Sebastian Hack committed
779
780
};

781
/* register allocator interface */
Matthias Braun's avatar
Matthias Braun committed
782
static const arch_irn_ops_t ia32_irn_ops = {
783
784
785
786
787
788
789
790
791
792
	ia32_classify,
	ia32_get_frame_entity,
	ia32_set_frame_offset,
	ia32_get_sp_bias,
	ia32_get_inverse,
	ia32_get_op_estimated_cost,
	ia32_possible_memory_operand,
	ia32_perform_memory_operand,
};

Michael Beck's avatar
Michael Beck committed
793
794
static ir_entity *mcount = NULL;

795
static void ia32_before_abi(ir_graph *irg)
796
{
797
	if (be_get_irg_options(irg)->gprof) {
Michael Beck's avatar
Michael Beck committed
798
		if (mcount == NULL) {
799
			ir_type *tp = new_type_method(0, 0);
800
801
			ident   *id = new_id_from_str("mcount");
			mcount = new_entity(get_glob_type(), id, tp);
Michael Beck's avatar
Michael Beck committed
802
803
			/* FIXME: enter the right ld_ident here */
			set_entity_ld_ident(mcount, get_entity_ident(mcount));
804
			set_entity_visibility(mcount, ir_visibility_external);
Michael Beck's avatar
Michael Beck committed
805
		}
806
		instrument_initcall(irg, mcount);
Michael Beck's avatar
Michael Beck committed
807
	}
808
809
810
811
812
813
}

/**
 * Transforms the standard firm graph into
 * an ia32 firm graph
 */
814
static void ia32_prepare_graph(ir_graph *irg)
815
{
816
	ia32_irg_data_t *irg_data = ia32_get_irg_data(irg);
817

818
#ifdef FIRM_GRGEN_BE
819
	switch (be_transformer) {
820
821
	case TRANSFORMER_DEFAULT:
		/* transform remaining nodes into assembler instructions */
822
		ia32_transform_graph(irg);
823
		break;
824

825
826
827
	case TRANSFORMER_PBQP:
	case TRANSFORMER_RAND:
		/* transform nodes into assembler instructions by PBQP magic */
828
		ia32_transform_graph_by_pbqp(irg);
829
		break;
830

831
832
	default:
		panic("invalid transformer");
833
	}
834
#else
835
	ia32_transform_graph(irg);
836
#endif
837

yb9976's avatar
typo    
yb9976 committed
838
	/* do local optimizations (mainly CSE) */
839
	optimize_graph_df(irg);
840

841
842
	if (irg_data->dump)
		dump_ir_graph(irg, "transformed");
Christian Würdig's avatar
Christian Würdig committed
843