beabi.c 78.8 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
 *
 * 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
18
19
20
21
22
 */

/**
 * @file
 * @brief       Backend ABI implementation.
23
 * @author      Sebastian Hack, Michael Beck
Christian Würdig's avatar
Christian Würdig committed
24
 * @version     $Id$
Sebastian Hack's avatar
Sebastian Hack committed
25
 */
Matthias Braun's avatar
Matthias Braun committed
26
#include "config.h"
27

Sebastian Hack's avatar
Sebastian Hack committed
28
#include "obst.h"
29
#include "offset.h"
Sebastian Hack's avatar
Sebastian Hack committed
30

31
#include "irgopt.h"
Sebastian Hack's avatar
Sebastian Hack committed
32
33
34
35
36
37
38

#include "irgraph_t.h"
#include "irnode_t.h"
#include "ircons_t.h"
#include "iredges_t.h"
#include "irgmod.h"
#include "irgwalk.h"
Sebastian Hack's avatar
Sebastian Hack committed
39
#include "irprintf_t.h"
40
#include "irgopt.h"
41
#include "irbitset.h"
42
43
44
#include "height.h"
#include "pdeq.h"
#include "irtools.h"
Matthias Braun's avatar
Matthias Braun committed
45
#include "raw_bitset.h"
46
#include "error.h"
47
#include "pset_new.h"
Sebastian Hack's avatar
Sebastian Hack committed
48
49
50

#include "be.h"
#include "beabi.h"
51
#include "bearch_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
52
#include "benode_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
53
#include "belive_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
54
#include "besched_t.h"
55
#include "beirg_t.h"
56
#include "bessaconstr.h"
Sebastian Hack's avatar
Sebastian Hack committed
57
58

typedef struct _be_abi_call_arg_t {
59
60
61
	unsigned is_res   : 1;  /**< 1: the call argument is a return value. 0: it's a call parameter. */
	unsigned in_reg   : 1;  /**< 1: this argument is transmitted in registers. */
	unsigned on_stack : 1;	/**< 1: this argument is transmitted on the stack. */
Sebastian Hack's avatar
Sebastian Hack committed
62

63
	int                    pos;
Sebastian Hack's avatar
Sebastian Hack committed
64
	const arch_register_t *reg;
65
66
67
68
69
	ir_entity             *stack_ent;
	ir_mode               *load_mode;
	unsigned               alignment;    /**< stack alignment */
	unsigned               space_before; /**< allocate space before */
	unsigned               space_after;  /**< allocate space after */
Sebastian Hack's avatar
Sebastian Hack committed
70
71
72
} be_abi_call_arg_t;

struct _be_abi_call_t {
Michael Beck's avatar
Michael Beck committed
73
74
	be_abi_call_flags_t          flags;  /**< Flags describing the ABI behavior on calls */
	int                          pop;    /**< number of bytes the stack frame is shrinked by the callee on return. */
75
76
77
	const be_abi_callbacks_t    *cb;
	ir_type                     *between_type;
	set                         *params;
Michael Beck's avatar
Michael Beck committed
78
	const arch_register_class_t *cls_addr; /**< register class of the call address */
Sebastian Hack's avatar
Sebastian Hack committed
79
80
};

Michael Beck's avatar
Michael Beck committed
81
82
83
/**
 * The ABI information for the current birg.
 */
Sebastian Hack's avatar
Sebastian Hack committed
84
struct _be_abi_irg_t {
Sebastian Hack's avatar
Sebastian Hack committed
85
	struct obstack       obst;
86
	be_irg_t             *birg;         /**< The back end IRG. */
87
	const arch_env_t     *arch_env;
Sebastian Hack's avatar
Sebastian Hack committed
88
89
	survive_dce_t        *dce_survivor;

Sebastian Hack's avatar
Sebastian Hack committed
90
	be_abi_call_t        *call;         /**< The ABI call information. */
91
	ir_type              *method_type;  /**< The type of the method of the IRG. */
Sebastian Hack's avatar
Sebastian Hack committed
92

Sebastian Hack's avatar
Sebastian Hack committed
93
	ir_node              *init_sp;      /**< The node representing the stack pointer
94
	                                         at the start of the function. */
Sebastian Hack's avatar
Sebastian Hack committed
95

Sebastian Hack's avatar
Sebastian Hack committed
96
97
	ir_node              *reg_params;   /**< The reg params node. */
	pmap                 *regs;         /**< A map of all callee-save and ignore regs to
98
	                                         their Projs to the RegParams node. */
Sebastian Hack's avatar
Sebastian Hack committed
99

100
	int                  start_block_bias; /**< The stack bias at the end of the start block. */
Sebastian Hack's avatar
Sebastian Hack committed
101

102
103
	void                 *cb;           /**< ABI Callback self pointer. */

Sebastian Hack's avatar
Sebastian Hack committed
104
105
106
	pmap                 *keep_map;     /**< mapping blocks to keep nodes. */
	pset                 *ignore_regs;  /**< Additional registers which shall be ignored. */

107
	ir_node              **calls;       /**< flexible array containing all be_Call nodes */
108

109
110
111
112
	arch_register_req_t  sp_req;
	arch_register_req_t  sp_cls_req;

	be_stack_layout_t    frame;         /**< The stack frame model. */
Matthias Braun's avatar
Matthias Braun committed
113

114
	DEBUG_ONLY(firm_dbg_module_t    *dbg;)  /**< The debugging module. */
Sebastian Hack's avatar
Sebastian Hack committed
115
};
Sebastian Hack's avatar
Sebastian Hack committed
116

117
static heights_t *ir_heights;
118

119
/** Flag: if set, try to omit the frame pointer in all routines. */
120
static int be_omit_fp = 1;
121

122
123
124
/** Flag: if set, try to omit the frame pointer in leaf routines only. */
static int be_omit_leaf_fp = 1;

Sebastian Hack's avatar
Sebastian Hack committed
125
126
127
128
129
130
/*
     _    ____ ___    ____      _ _ _                _
    / \  | __ )_ _|  / ___|__ _| | | |__   __ _  ___| | _____
   / _ \ |  _ \| |  | |   / _` | | | '_ \ / _` |/ __| |/ / __|
  / ___ \| |_) | |  | |__| (_| | | | |_) | (_| | (__|   <\__ \
 /_/   \_\____/___|  \____\__,_|_|_|_.__/ \__,_|\___|_|\_\___/
131

Sebastian Hack's avatar
Sebastian Hack committed
132
133
134
  These callbacks are used by the backend to set the parameters
  for a specific call type.
*/
Sebastian Hack's avatar
Sebastian Hack committed
135

Michael Beck's avatar
Michael Beck committed
136
137
138
/**
 * Set compare function: compares two ABI call object arguments.
 */
Sebastian Hack's avatar
Sebastian Hack committed
139
140
141
static int cmp_call_arg(const void *a, const void *b, size_t n)
{
	const be_abi_call_arg_t *p = a, *q = b;
142
	(void) n;
Sebastian Hack's avatar
Sebastian Hack committed
143
144
145
	return !(p->is_res == q->is_res && p->pos == q->pos);
}

Michael Beck's avatar
Michael Beck committed
146
/**
Michael Beck's avatar
Michael Beck committed
147
 * Get  an ABI call object argument.
Michael Beck's avatar
Michael Beck committed
148
149
150
151
152
 *
 * @param call      the abi call
 * @param is_res    true for call results, false for call arguments
 * @param pos       position of the argument
 */
Michael Beck's avatar
Michael Beck committed
153
static be_abi_call_arg_t *get_call_arg(be_abi_call_t *call, int is_res, int pos)
Sebastian Hack's avatar
Sebastian Hack committed
154
155
156
157
{
	be_abi_call_arg_t arg;
	unsigned hash;

158
	memset(&arg, 0, sizeof(arg));
Sebastian Hack's avatar
Sebastian Hack committed
159
160
161
	arg.is_res = is_res;
	arg.pos    = pos;

Michael Beck's avatar
Michael Beck committed
162
	hash = is_res * 128 + pos;
Sebastian Hack's avatar
Sebastian Hack committed
163

Michael Beck's avatar
Michael Beck committed
164
	return set_find(call->params, &arg, sizeof(arg), hash);
Sebastian Hack's avatar
Sebastian Hack committed
165
166
}

Michael Beck's avatar
Michael Beck committed
167
/**
Michael Beck's avatar
Michael Beck committed
168
 * Set an ABI call object argument.
Michael Beck's avatar
Michael Beck committed
169
 *
Michael Beck's avatar
Michael Beck committed
170
 * @param call      the abi call
Michael Beck's avatar
Michael Beck committed
171
172
173
 * @param is_res    true for call results, false for call arguments
 * @param pos       position of the argument
 */
Michael Beck's avatar
Michael Beck committed
174
static be_abi_call_arg_t *create_call_arg(be_abi_call_t *call, int is_res, int pos)
Sebastian Hack's avatar
Sebastian Hack committed
175
{
Michael Beck's avatar
Michael Beck committed
176
177
178
179
180
181
182
183
184
185
	be_abi_call_arg_t arg;
	unsigned hash;

	memset(&arg, 0, sizeof(arg));
	arg.is_res = is_res;
	arg.pos    = pos;

	hash = is_res * 128 + pos;

	return set_insert(call->params, &arg, sizeof(arg), hash);
Sebastian Hack's avatar
Sebastian Hack committed
186
187
}

Michael Beck's avatar
Michael Beck committed
188
/* Set the flags for a call. */
189
void be_abi_call_set_flags(be_abi_call_t *call, be_abi_call_flags_t flags, const be_abi_callbacks_t *cb)
Sebastian Hack's avatar
Sebastian Hack committed
190
{
191
192
	call->flags = flags;
	call->cb    = cb;
Sebastian Hack's avatar
Sebastian Hack committed
193
194
}

Michael Beck's avatar
Michael Beck committed
195
/* Sets the number of bytes the stackframe is shrinked by the callee on return */
196
197
198
199
200
void be_abi_call_set_pop(be_abi_call_t *call, int pop)
{
	assert(pop >= 0);
	call->pop = pop;
}
201
202
203
204
205
206
207
208

/* Set register class for call address */
void be_abi_call_set_call_address_reg_class(be_abi_call_t *call, const arch_register_class_t *cls)
{
	call->cls_addr = cls;
}


209
void be_abi_call_param_stack(be_abi_call_t *call, int arg_pos, ir_mode *load_mode, unsigned alignment, unsigned space_before, unsigned space_after)
Sebastian Hack's avatar
Sebastian Hack committed
210
{
Michael Beck's avatar
Michael Beck committed
211
	be_abi_call_arg_t *arg = create_call_arg(call, 0, arg_pos);
212
	arg->on_stack     = 1;
213
	arg->load_mode    = load_mode;
214
215
216
	arg->alignment    = alignment;
	arg->space_before = space_before;
	arg->space_after  = space_after;
217
	assert(alignment > 0 && "Alignment must be greater than 0");
Sebastian Hack's avatar
Sebastian Hack committed
218
219
220
221
}

void be_abi_call_param_reg(be_abi_call_t *call, int arg_pos, const arch_register_t *reg)
{
Michael Beck's avatar
Michael Beck committed
222
	be_abi_call_arg_t *arg = create_call_arg(call, 0, arg_pos);
223
	arg->in_reg = 1;
Sebastian Hack's avatar
Sebastian Hack committed
224
225
226
227
228
	arg->reg = reg;
}

void be_abi_call_res_reg(be_abi_call_t *call, int arg_pos, const arch_register_t *reg)
{
Michael Beck's avatar
Michael Beck committed
229
	be_abi_call_arg_t *arg = create_call_arg(call, 1, arg_pos);
230
	arg->in_reg = 1;
Sebastian Hack's avatar
Sebastian Hack committed
231
232
233
	arg->reg = reg;
}

Michael Beck's avatar
Michael Beck committed
234
/* Get the flags of a ABI call object. */
235
236
237
238
239
be_abi_call_flags_t be_abi_call_get_flags(const be_abi_call_t *call)
{
	return call->flags;
}

Michael Beck's avatar
Michael Beck committed
240
241
242
/**
 * Constructor for a new ABI call object.
 *
Michael Beck's avatar
Michael Beck committed
243
244
 * @param cls_addr  register class of the call address
 *
Michael Beck's avatar
Michael Beck committed
245
246
 * @return the new ABI call object
 */
247
static be_abi_call_t *be_abi_call_new(const arch_register_class_t *cls_addr)
Sebastian Hack's avatar
Sebastian Hack committed
248
{
249
	be_abi_call_t *call = XMALLOCZ(be_abi_call_t);
250

Sebastian Hack's avatar
Sebastian Hack committed
251
252
253
	call->flags.val  = 0;
	call->params     = new_set(cmp_call_arg, 16);
	call->cb         = NULL;
254
	call->cls_addr   = cls_addr;
255

256
	call->flags.bits.try_omit_fp = be_omit_fp | be_omit_leaf_fp;
257

Sebastian Hack's avatar
Sebastian Hack committed
258
259
260
	return call;
}

Michael Beck's avatar
Michael Beck committed
261
262
263
264
/**
 * Destructor for an ABI call object.
 */
static void be_abi_call_free(be_abi_call_t *call)
Sebastian Hack's avatar
Sebastian Hack committed
265
266
267
268
269
{
	del_set(call->params);
	free(call);
}

Sebastian Hack's avatar
Sebastian Hack committed
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/*
  _____                           _   _                 _ _ _
 |  ___| __ __ _ _ __ ___   ___  | | | | __ _ _ __   __| | (_)_ __   __ _
 | |_ | '__/ _` | '_ ` _ \ / _ \ | |_| |/ _` | '_ \ / _` | | | '_ \ / _` |
 |  _|| | | (_| | | | | | |  __/ |  _  | (_| | | | | (_| | | | | | | (_| |
 |_|  |_|  \__,_|_| |_| |_|\___| |_| |_|\__,_|_| |_|\__,_|_|_|_| |_|\__, |
                                                                    |___/

  Handling of the stack frame. It is composed of three types:
  1) The type of the arguments which are pushed on the stack.
  2) The "between type" which consists of stuff the call of the
     function pushes on the stack (like the return address and
	 the old base pointer for ia32).
  3) The Firm frame type which consists of all local variables
     and the spills.
*/

287
288
static int get_stack_entity_offset(be_stack_layout_t *frame, ir_entity *ent,
                                   int bias)
289
{
290
	ir_type *t = get_entity_owner(ent);
291
	int ofs    = get_entity_offset(ent);
292

293
	int index;
294
295

	/* Find the type the entity is contained in. */
296
297
	for (index = 0; index < N_FRAME_TYPES; ++index) {
		if (frame->order[index] == t)
298
			break;
299
300
		/* Add the size of all the types below the one of the entity to the entity's offset */
		ofs += get_type_size_bytes(frame->order[index]);
301
302
303
304
305
306
307
308
309
310
311
	}

	/* correct the offset by the initial position of the frame pointer */
	ofs -= frame->initial_offset;

	/* correct the offset with the current bias. */
	ofs += bias;

	return ofs;
}

Michael Beck's avatar
Michael Beck committed
312
313
314
/**
 * Retrieve the entity with given offset from a frame type.
 */
315
static ir_entity *search_ent_with_offset(ir_type *t, int offset)
Sebastian Hack's avatar
Sebastian Hack committed
316
317
318
{
	int i, n;

319
	for (i = 0, n = get_compound_n_members(t); i < n; ++i) {
320
		ir_entity *ent = get_compound_member(t, i);
321
		if (get_entity_offset(ent) == offset)
Sebastian Hack's avatar
Sebastian Hack committed
322
323
324
325
326
327
			return ent;
	}

	return NULL;
}

328
static int stack_frame_compute_initial_offset(be_stack_layout_t *frame)
329
{
330
331
	ir_type  *base = frame->stack_dir < 0 ? frame->between_type : frame->frame_type;
	ir_entity *ent = search_ent_with_offset(base, 0);
332
333
334

	frame->initial_offset = ent ? get_stack_entity_offset(frame, ent, 0) : 0;

335
336
337
	return frame->initial_offset;
}

338
339
340
341
342
343
344
/**
 * Initializes the frame layout from parts
 *
 * @param frame     the stack layout that will be initialized
 * @param args      the stack argument layout type
 * @param between   the between layout type
 * @param locals    the method frame type
345
 * @param stack_dir the stack direction: < 0 decreasing, > 0 increasing addresses
346
 * @param param_map an array mapping method argument positions to the stack argument type
347
348
349
350
 *
 * @return the initialized stack layout
 */
static be_stack_layout_t *stack_frame_init(be_stack_layout_t *frame, ir_type *args,
351
                                           ir_type *between, ir_type *locals, int stack_dir,
352
                                           ir_entity *param_map[])
353
354
355
356
357
{
	frame->arg_type       = args;
	frame->between_type   = between;
	frame->frame_type     = locals;
	frame->initial_offset = 0;
Matthias Braun's avatar
Matthias Braun committed
358
	frame->initial_bias   = 0;
359
360
	frame->stack_dir      = stack_dir;
	frame->order[1]       = between;
361
	frame->param_map      = param_map;
362

363
	if (stack_dir > 0) {
364
365
366
367
		frame->order[0] = args;
		frame->order[2] = locals;
	}
	else {
368
369
		/* typical decreasing stack: locals have the
		 * lowest addresses, arguments the highest */
370
371
372
373
374
375
		frame->order[0] = locals;
		frame->order[2] = args;
	}
	return frame;
}

376
#if 0
377
378
/** Dumps the stack layout to file. */
static void stack_layout_dump(FILE *file, be_stack_layout_t *frame)
Sebastian Hack's avatar
Sebastian Hack committed
379
380
381
382
{
	int i, j, n;

	ir_fprintf(file, "initial offset: %d\n", frame->initial_offset);
383
384
	for (j = 0; j < N_FRAME_TYPES; ++j) {
		ir_type *t = frame->order[j];
Sebastian Hack's avatar
Sebastian Hack committed
385

386
387
		ir_fprintf(file, "type %d: %F size: %d\n", j, t, get_type_size_bytes(t));
		for (i = 0, n = get_compound_n_members(t); i < n; ++i) {
388
			ir_entity *ent = get_compound_member(t, i);
Sebastian Hack's avatar
Sebastian Hack committed
389
390
391
392
			ir_fprintf(file, "\t%F int ofs: %d glob ofs: %d\n", ent, get_entity_offset_bytes(ent), get_stack_entity_offset(frame, ent, 0));
		}
	}
}
393
#endif
Sebastian Hack's avatar
Sebastian Hack committed
394

Michael Beck's avatar
Michael Beck committed
395
396
397
398
/**
 * Returns non-zero if the call argument at given position
 * is transfered on the stack.
 */
399
static inline int is_on_stack(be_abi_call_t *call, int pos)
Sebastian Hack's avatar
Sebastian Hack committed
400
401
402
403
404
{
	be_abi_call_arg_t *arg = get_call_arg(call, 0, pos);
	return arg && !arg->in_reg;
}

405
406
407
408
409
410
411
412
413
414
415
/*
   ____      _ _
  / ___|__ _| | |___
 | |   / _` | | / __|
 | |__| (_| | | \__ \
  \____\__,_|_|_|___/

  Adjustment of the calls inside a graph.

*/

Sebastian Hack's avatar
Sebastian Hack committed
416
/**
417
418
 * Transform a call node into a be_Call node.
 *
Sebastian Hack's avatar
Sebastian Hack committed
419
 * @param env The ABI environment for the current irg.
420
421
422
 * @param irn The call node.
 * @param curr_sp The stack pointer node to use.
 * @return The stack pointer after the call.
Sebastian Hack's avatar
Sebastian Hack committed
423
 */
Matthias Braun's avatar
Matthias Braun committed
424
static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp)
Sebastian Hack's avatar
Sebastian Hack committed
425
{
426
	ir_graph *irg              = env->birg->irg;
427
	const arch_env_t *arch_env = env->birg->main_env->arch_env;
428
	ir_type *call_tp           = get_Call_type(irn);
429
	ir_node *call_ptr          = get_Call_ptr(irn);
430
	int n_params               = get_method_n_params(call_tp);
431
432
433
	ir_node *curr_mem          = get_Call_mem(irn);
	ir_node *bl                = get_nodes_block(irn);
	int stack_size             = 0;
434
435
	int stack_dir              = arch_env->stack_dir;
	const arch_register_t *sp  = arch_env->sp;
436
437
438
439
	be_abi_call_t *call        = be_abi_call_new(sp->reg_class);
	ir_mode *mach_mode         = sp->reg_class->mode;
	struct obstack *obst       = &env->obst;
	int no_alloc               = call->flags.bits.frame_is_setup_on_call;
440
	int n_res                  = get_method_n_ress(call_tp);
441
	int do_seq                 = call->flags.bits.store_args_sequential && !no_alloc;
442
443
444
445
446

	ir_node *res_proj  = NULL;
	int n_reg_params   = 0;
	int n_stack_params = 0;
	int n_ins;
Sebastian Hack's avatar
Sebastian Hack committed
447

448
449
	pset_new_t              destroyed_regs, states;
	pset_new_iterator_t     iter;
450
451
452
453
454
455
456
457
	ir_node                *low_call;
	ir_node               **in;
	ir_node               **res_projs;
	int                     n_reg_results = 0;
	const arch_register_t  *reg;
	const ir_edge_t        *edge;
	int                    *reg_param_idxs;
	int                    *stack_param_idx;
458
	int                     i, n, destroy_all_regs;
459
	dbg_info               *dbgi;
Sebastian Hack's avatar
Sebastian Hack committed
460

461
462
463
	pset_new_init(&destroyed_regs);
	pset_new_init(&states);

Sebastian Hack's avatar
Sebastian Hack committed
464
	/* Let the isa fill out the abi description for that call node. */
465
	arch_env_get_call_abi(arch_env, call_tp, call);
Sebastian Hack's avatar
Sebastian Hack committed
466
467

	/* Insert code to put the stack arguments on the stack. */
468
	assert(get_Call_n_params(irn) == n_params);
469
	for (i = 0; i < n_params; ++i) {
Sebastian Hack's avatar
Sebastian Hack committed
470
		be_abi_call_arg_t *arg = get_call_arg(call, 0, i);
471
		assert(arg);
Michael Beck's avatar
Michael Beck committed
472
		if (arg->on_stack) {
473
			int arg_size = get_type_size_bytes(get_method_param_type(call_tp, i));
Michael Beck's avatar
Michael Beck committed
474
475
476
477

			stack_size += round_up2(arg->space_before, arg->alignment);
			stack_size += round_up2(arg_size, arg->alignment);
			stack_size += round_up2(arg->space_after, arg->alignment);
Sebastian Hack's avatar
Sebastian Hack committed
478
			obstack_int_grow(obst, i);
479
			++n_stack_params;
Sebastian Hack's avatar
Sebastian Hack committed
480
481
		}
	}
482
	stack_param_idx = obstack_finish(obst);
Sebastian Hack's avatar
Sebastian Hack committed
483
484

	/* Collect all arguments which are passed in registers. */
485
	for (i = 0; i < n_params; ++i) {
Sebastian Hack's avatar
Sebastian Hack committed
486
		be_abi_call_arg_t *arg = get_call_arg(call, 0, i);
487
		if (arg && arg->in_reg) {
Sebastian Hack's avatar
Sebastian Hack committed
488
			obstack_int_grow(obst, i);
489
			++n_reg_params;
Sebastian Hack's avatar
Sebastian Hack committed
490
491
		}
	}
492
	reg_param_idxs = obstack_finish(obst);
Sebastian Hack's avatar
Sebastian Hack committed
493

494
495
496
497
498
499
500
501
502
503
504
505
506
	/*
	 * If the stack is decreasing and we do not want to store sequentially,
	 * or someone else allocated the call frame
	 * we allocate as much space on the stack all parameters need, by
	 * moving the stack pointer along the stack's direction.
	 *
	 * Note: we also have to do this for stack_size == 0, because we may have
	 * to adjust stack alignment for the call.
	 */
	if (stack_dir < 0 && !do_seq && !no_alloc) {
		curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, stack_size, 1);
	}

Christoph Mallon's avatar
Christoph Mallon committed
507
	dbgi = get_irn_dbg_info(irn);
Sebastian Hack's avatar
Sebastian Hack committed
508
	/* If there are some parameters which shall be passed on the stack. */
509
	if (n_stack_params > 0) {
Sebastian Hack's avatar
Sebastian Hack committed
510
511
		int curr_ofs      = 0;

512
513
		/*
		 * Reverse list of stack parameters if call arguments are from left to right.
514
		 * We must them reverse again if they are pushed (not stored) and the stack
515
516
517
		 * direction is downwards.
		 */
		if (call->flags.bits.left_to_right ^ (do_seq && stack_dir < 0)) {
518
519
520
521
522
			for (i = 0; i < n_stack_params >> 1; ++i) {
				int other  = n_stack_params - i - 1;
				int tmp    = stack_param_idx[i];
				stack_param_idx[i]     = stack_param_idx[other];
				stack_param_idx[other] = tmp;
Sebastian Hack's avatar
Sebastian Hack committed
523
524
525
			}
		}

526
		curr_mem = get_Call_mem(irn);
527
		if (! do_seq) {
528
			obstack_ptr_grow(obst, curr_mem);
529
530
		}

531
532
		for (i = 0; i < n_stack_params; ++i) {
			int p                  = stack_param_idx[i];
533
534
535
536
			be_abi_call_arg_t *arg = get_call_arg(call, 0, p);
			ir_node *param         = get_Call_param(irn, p);
			ir_node *addr          = curr_sp;
			ir_node *mem           = NULL;
537
			ir_type *param_type    = get_method_param_type(call_tp, p);
538
539
			int param_size         = get_type_size_bytes(param_type) + arg->space_after;

540
541
542
543
544
545
546
			/*
			 * If we wanted to build the arguments sequentially,
			 * the stack pointer for the next must be incremented,
			 * and the memory value propagated.
			 */
			if (do_seq) {
				curr_ofs = 0;
547
				addr = curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, param_size + arg->space_before, 0);
Sebastian Hack's avatar
Sebastian Hack committed
548
				add_irn_dep(curr_sp, curr_mem);
549
550
551
552
553
554
			}
			else {
				curr_ofs += arg->space_before;
				curr_ofs =  round_up2(curr_ofs, arg->alignment);

				/* Make the expression to compute the argument's offset. */
555
				if (curr_ofs > 0) {
556
					ir_mode *constmode = mach_mode;
557
					if (mode_is_reference(mach_mode)) {
558
559
						constmode = mode_Is;
					}
560
					addr = new_r_Const_long(irg, constmode, curr_ofs);
561
562
					addr = new_r_Add(irg, bl, curr_sp, addr, mach_mode);
				}
Sebastian Hack's avatar
Sebastian Hack committed
563
564
565
			}

			/* Insert a store for primitive arguments. */
566
			if (is_atomic_type(param_type)) {
567
				ir_node *store;
568
				ir_node *mem_input = do_seq ? curr_mem : new_NoMem();
569
				store = new_rd_Store(dbgi, irg, bl, mem_input, addr, param, 0);
570
				mem = new_r_Proj(irg, bl, store, mode_M, pn_Store_M);
Sebastian Hack's avatar
Sebastian Hack committed
571
572
			}

573
			/* Make a mem copy for compound arguments. */
Sebastian Hack's avatar
Sebastian Hack committed
574
			else {
575
576
				ir_node *copy;

Sebastian Hack's avatar
Sebastian Hack committed
577
				assert(mode_is_reference(get_irn_mode(param)));
578
				copy = new_rd_CopyB(dbgi, irg, bl, curr_mem, addr, param, param_type);
579
				mem = new_r_Proj(irg, bl, copy, mode_M, pn_CopyB_M_regular);
Sebastian Hack's avatar
Sebastian Hack committed
580
581
582
583
			}

			curr_ofs += param_size;

584
			if (do_seq)
Sebastian Hack's avatar
Sebastian Hack committed
585
				curr_mem = mem;
586
587
			else
				obstack_ptr_grow(obst, mem);
Sebastian Hack's avatar
Sebastian Hack committed
588
589
590
591
592
		}

		in = (ir_node **) obstack_finish(obst);

		/* We need the sync only, if we didn't build the stores sequentially. */
593
594
595
		if (! do_seq) {
			if (n_stack_params >= 1) {
				curr_mem = new_r_Sync(irg, bl, n_stack_params + 1, in);
596
597
598
599
			} else {
				curr_mem = get_Call_mem(irn);
			}
		}
Sebastian Hack's avatar
Sebastian Hack committed
600
601
602
		obstack_free(obst, in);
	}

603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
	/* check for the return_twice property */
	destroy_all_regs = 0;
	if (is_SymConst_addr_ent(call_ptr)) {
		ir_entity *ent = get_SymConst_entity(call_ptr);

		if (get_entity_additional_properties(ent) & mtp_property_returns_twice)
			destroy_all_regs = 1;
	} else {
		ir_type *call_tp = get_Call_type(irn);

		if (get_method_additional_properties(call_tp) & mtp_property_returns_twice)
			destroy_all_regs = 1;
	}

	/* Put caller save into the destroyed set and state registers in the states set */
618
	for (i = 0, n = arch_env_get_n_reg_class(arch_env); i < n; ++i) {
619
		unsigned j;
620
		const arch_register_class_t *cls = arch_env_get_reg_class(arch_env, i);
621
		for (j = 0; j < cls->n_regs; ++j) {
Sebastian Hack's avatar
Sebastian Hack committed
622
			const arch_register_t *reg = arch_register_for_index(cls, j);
623
624
625
626

			if (destroy_all_regs || arch_register_type_is(reg, caller_save)) {
				if (! arch_register_type_is(reg, ignore))
					pset_new_insert(&destroyed_regs, (void *) reg);
627
			}
628
			if (arch_register_type_is(reg, state)) {
629
630
				pset_new_insert(&destroyed_regs, (void*) reg);
				pset_new_insert(&states, (void*) reg);
631
			}
Sebastian Hack's avatar
Sebastian Hack committed
632
633
		}
	}
Sebastian Hack's avatar
Sebastian Hack committed
634

635
	if (destroy_all_regs) {
Christoph Mallon's avatar
Christoph Mallon committed
636
		/* even if destroyed all is specified, neither SP nor FP are destroyed (else bad things will happen) */
637
638
639
		pset_new_remove(&destroyed_regs, arch_env->sp);
		pset_new_remove(&destroyed_regs, arch_env->bp);
	}
Michael Beck's avatar
Michael Beck committed
640

Christoph Mallon's avatar
Christoph Mallon committed
641
	/* search the largest result proj number */
642
	res_projs = ALLOCANZ(ir_node*, n_res);
Matthias Braun's avatar
Matthias Braun committed
643

Sebastian Hack's avatar
Sebastian Hack committed
644
645
	foreach_out_edge(irn, edge) {
		const ir_edge_t *res_edge;
Matthias Braun's avatar
Matthias Braun committed
646
		ir_node         *irn = get_edge_src_irn(edge);
Sebastian Hack's avatar
Sebastian Hack committed
647

648
		if (!is_Proj(irn) || get_Proj_proj(irn) != pn_Call_T_result)
Matthias Braun's avatar
Matthias Braun committed
649
650
651
652
653
654
655
656
657
658
			continue;

		foreach_out_edge(irn, res_edge) {
			int proj;
			ir_node *res = get_edge_src_irn(res_edge);

			assert(is_Proj(res));

			proj = get_Proj_proj(res);
			assert(proj < n_res);
Matthias Braun's avatar
Matthias Braun committed
659
			assert(res_projs[proj] == NULL);
Matthias Braun's avatar
Matthias Braun committed
660
			res_projs[proj] = res;
Sebastian Hack's avatar
Sebastian Hack committed
661
		}
Matthias Braun's avatar
Matthias Braun committed
662
663
		res_proj = irn;
		break;
Sebastian Hack's avatar
Sebastian Hack committed
664
	}
665

Matthias Braun's avatar
Matthias Braun committed
666
	/** TODO: this is not correct for cases where return values are passed
Christoph Mallon's avatar
Christoph Mallon committed
667
	 * on the stack, but no known ABI does this currently...
Matthias Braun's avatar
Matthias Braun committed
668
669
	 */
	n_reg_results = n_res;
Sebastian Hack's avatar
Sebastian Hack committed
670

671
	/* make the back end call node and set its register requirements. */
672
673
	for (i = 0; i < n_reg_params; ++i) {
		obstack_ptr_grow(obst, get_Call_param(irn, reg_param_idxs[i]));
674
	}
675
676
677

	/* add state registers ins */
	foreach_pset_new(&states, reg, iter) {
678
679
680
681
682
683
684
685
		const arch_register_class_t *cls = arch_register_get_class(reg);
#if 0
		ir_node *regnode = be_abi_reg_map_get(env->regs, reg);
		ir_fprintf(stderr, "Adding %+F\n", regnode);
#endif
		ir_node *regnode = new_rd_Unknown(irg, arch_register_class_mode(cls));
		obstack_ptr_grow(obst, regnode);
	}
686
	n_ins = n_reg_params + pset_new_size(&states);
687
688

	in = obstack_finish(obst);
689

690
	/* ins collected, build the call */
691
692
	if (env->call->flags.bits.call_has_imm && is_SymConst(call_ptr)) {
		/* direct call */
693
		low_call = be_new_Call(dbgi, irg, bl, curr_mem, curr_sp, curr_sp,
694
		                       n_reg_results + pn_be_Call_first_res + pset_new_size(&destroyed_regs),
Matthias Braun's avatar
Matthias Braun committed
695
		                       n_ins, in, get_Call_type(irn));
Sebastian Hack's avatar
Sebastian Hack committed
696
		be_Call_set_entity(low_call, get_SymConst_entity(call_ptr));
697
	} else {
698
		/* indirect call */
699
		low_call = be_new_Call(dbgi, irg, bl, curr_mem, curr_sp, call_ptr,
700
		                       n_reg_results + pn_be_Call_first_res + pset_new_size(&destroyed_regs),
701
		                       n_ins, in, get_Call_type(irn));
Sebastian Hack's avatar
Sebastian Hack committed
702
	}
703
	be_Call_set_pop(low_call, call->pop);
704
705

	/* put the call into the list of all calls for later processing */
706
	ARR_APP1(ir_node *, env->calls, low_call);
707

Matthias Braun's avatar
Matthias Braun committed
708
709
710
	/* create new stack pointer */
	curr_sp = new_r_Proj(irg, bl, low_call, get_irn_mode(curr_sp),
	                     pn_be_Call_sp);
711
712
	be_set_constr_single_reg_out(low_call, pn_be_Call_sp, sp,
			arch_register_req_type_ignore | arch_register_req_type_produces_sp);
713
	arch_set_irn_register(curr_sp, sp);
Matthias Braun's avatar
Matthias Braun committed
714

715
	/* now handle results */
716
	for (i = 0; i < n_res; ++i) {
Matthias Braun's avatar
Matthias Braun committed
717
718
719
720
		int pn;
		ir_node           *proj = res_projs[i];
		be_abi_call_arg_t *arg  = get_call_arg(call, 1, i);

Matthias Braun's avatar
Matthias Braun committed
721
722
723
		/* returns values on stack not supported yet */
		assert(arg->in_reg);

Matthias Braun's avatar
Matthias Braun committed
724
725
726
727
728
729
730
		/*
			shift the proj number to the right, since we will drop the
			unspeakable Proj_T from the Call. Therefore, all real argument
			Proj numbers must be increased by pn_be_Call_first_res
		*/
		pn = i + pn_be_Call_first_res;

731
		if (proj == NULL) {
732
			ir_type *res_type = get_method_res_type(call_tp, i);
Matthias Braun's avatar
Matthias Braun committed
733
734
735
736
737
738
739
740
741
			ir_mode *mode     = get_type_mode(res_type);
			proj              = new_r_Proj(irg, bl, low_call, mode, pn);
			res_projs[i]      = proj;
		} else {
			set_Proj_pred(proj, low_call);
			set_Proj_proj(proj, pn);
		}

		if (arg->in_reg) {
742
			pset_new_remove(&destroyed_regs, arg->reg);
Matthias Braun's avatar
Matthias Braun committed
743
744
745
		}
	}

746
	/*
747
748
		Set the register class of the call address to
		the backend provided class (default: stack pointer class)
749
	*/
750
	be_node_set_reg_class_in(low_call, be_pos_Call_ptr, call->cls_addr);
751

752
753
	DBG((env->dbg, LEVEL_3, "\tcreated backend call %+F\n", low_call));

Sebastian Hack's avatar
Sebastian Hack committed
754
	/* Set the register classes and constraints of the Call parameters. */
755
756
	for (i = 0; i < n_reg_params; ++i) {
		int index = reg_param_idxs[i];
Sebastian Hack's avatar
Sebastian Hack committed
757
758
		be_abi_call_arg_t *arg = get_call_arg(call, 0, index);
		assert(arg->reg != NULL);
759

760
761
		be_set_constr_single_reg_in(low_call, be_pos_Call_first_arg + i,
		                            arg->reg, 0);
Sebastian Hack's avatar
Sebastian Hack committed
762
763
764
	}

	/* Set the register constraints of the results. */
Matthias Braun's avatar
Matthias Braun committed
765
766
767
768
	for (i = 0; i < n_res; ++i) {
		ir_node                 *proj = res_projs[i];
		const be_abi_call_arg_t *arg  = get_call_arg(call, 1, i);
		int                      pn   = get_Proj_proj(proj);
769

Sebastian Hack's avatar
Sebastian Hack committed
770
		assert(arg->in_reg);
771
		be_set_constr_single_reg_out(low_call, pn, arg->reg, 0);
772
		arch_set_irn_register(proj, arg->reg);
Sebastian Hack's avatar
Sebastian Hack committed
773
	}
774
775
776
	obstack_free(obst, in);
	exchange(irn, low_call);

Matthias Braun's avatar
Matthias Braun committed
777
	/* kill the ProjT node */
778
	if (res_proj != NULL) {
779
		kill_node(res_proj);
780
781
	}

Sebastian Hack's avatar
Sebastian Hack committed
782
783
	/* Make additional projs for the caller save registers
	   and the Keep node which keeps them alive. */
784
	{
Sebastian Hack's avatar
Sebastian Hack committed
785
		const arch_register_t *reg;
786
		ir_node               **in, *keep;
787
788
		int                   i;
		int                   n = 0;
789
790
		int                   curr_res_proj = pn_be_Call_first_res + n_reg_results;
		pset_new_iterator_t   iter;
Sebastian Hack's avatar
Sebastian Hack committed
791

792
793
794
795
796
		/* also keep the stack pointer */
		++n;
		set_irn_link(curr_sp, (void*) sp);
		obstack_ptr_grow(obst, curr_sp);

797
798
		foreach_pset_new(&destroyed_regs, reg, iter) {
			ir_node *proj = new_r_Proj(irg, bl, low_call, reg->reg_class->mode, curr_res_proj);
Sebastian Hack's avatar
Sebastian Hack committed
799

Sebastian Hack's avatar
Sebastian Hack committed
800
			/* memorize the register in the link field. we need afterwards to set the register class of the keep correctly. */
801
			be_set_constr_single_reg_out(low_call, curr_res_proj, reg, 0);
802
			arch_set_irn_register(proj, reg);
803

Matthias Braun's avatar
Matthias Braun committed
804
			set_irn_link(proj, (void*) reg);
Sebastian Hack's avatar
Sebastian Hack committed
805
			obstack_ptr_grow(obst, proj);
806
807
			++curr_res_proj;
			++n;
Sebastian Hack's avatar
Sebastian Hack committed
808
809
		}

810
		for (i = 0; i < n_reg_results; ++i) {
Matthias Braun's avatar
Matthias Braun committed
811
			ir_node *proj = res_projs[i];
812
			const arch_register_t *reg = arch_get_irn_register(proj);
Matthias Braun's avatar
Matthias Braun committed
813
814
815
816
817
			set_irn_link(proj, (void*) reg);
			obstack_ptr_grow(obst, proj);
		}
		n += n_reg_results;

818
		/* create the Keep for the caller save registers */
Sebastian Hack's avatar
Sebastian Hack committed
819
820
		in   = (ir_node **) obstack_finish(obst);
		keep = be_new_Keep(NULL, irg, bl, n, in);
821
		for (i = 0; i < n; ++i) {
Sebastian Hack's avatar
Sebastian Hack committed
822
			const arch_register_t *reg = get_irn_link(in[i]);
823
			be_node_set_reg_class_in(keep, i, reg->reg_class);
Sebastian Hack's avatar
Sebastian Hack committed
824
		}
Sebastian Hack's avatar
Sebastian Hack committed
825
826
827
828
		obstack_free(obst, in);
	}

	/* Clean up the stack. */
829
830
831
	assert(stack_size >= call->pop);
	stack_size -= call->pop;

832
	if (stack_size > 0) {
833
834
835
836
		ir_node *mem_proj = NULL;

		foreach_out_edge(low_call, edge) {
			ir_node *irn = get_edge_src_irn(edge);
837
			if (is_Proj(irn) && get_Proj_proj(irn) == pn_Call_M) {
838
839
840
841
				mem_proj = irn;
				break;
			}
		}
Sebastian Hack's avatar
Sebastian Hack committed
842

843
		if (! mem_proj) {
844
			mem_proj = new_r_Proj(irg, bl, low_call, mode_M, pn_be_Call_M_regular);
Sebastian Hack's avatar
Sebastian Hack committed
845
846
			keep_alive(mem_proj);
		}
847
848
849
850
	}
	/* Clean up the stack frame or revert alignment fixes if we allocated it */
	if (! no_alloc) {
		curr_sp = be_new_IncSP(sp, irg, bl, curr_sp, -stack_size, 0);
Sebastian Hack's avatar
Sebastian Hack committed
851
852
853
	}

	be_abi_call_free(call);
854
	obstack_free(obst, stack_param_idx);
855
856
857

	pset_new_destroy(&states);
	pset_new_destroy(&destroyed_regs);
858
859
860
861

	return curr_sp;
}

862
863
864
865
866
867
868
869
870
871
872
/**
 * Adjust the size of a node representing a stack alloc or free for the minimum stack alignment.
 *
 * @param alignment  the minimum stack alignment
 * @param size       the node containing the non-aligned size
 * @param irg        the irg where new nodes are allocated on
 * @param irg        the block where new nodes are allocated on
 * @param dbg        debug info for new nodes
 *
 * @return a node representing the aligned size
 */
873
874
875
static ir_node *adjust_alloc_size(unsigned stack_alignment, ir_node *size,
                                  ir_graph *irg, ir_node *block, dbg_info *dbg)
{
876
	if (stack_alignment > 1) {
Michael Beck's avatar
Michael Beck committed
877
878
879
880
		ir_mode *mode;
		tarval  *tv;
		ir_node *mask;

881
		assert(is_po2(stack_alignment));
882

Michael Beck's avatar
Michael Beck committed
883
884
		mode = get_irn_mode(size);
		tv   = new_tarval_from_long(stack_alignment-1, mode);
885
		mask = new_r_Const(irg, tv);
886
887
888
		size = new_rd_Add(dbg, irg, block, size, mask, mode);

		tv   = new_tarval_from_long(-(long)stack_alignment, mode);
889
		mask = new_r_Const(irg, tv);
890
891
892
893
		size = new_rd_And(dbg, irg, block, size, mask, mode);
	}
	return size;
}
894
895
896
897
/**
 * Adjust an alloca.
 * The alloca is transformed into a back end alloca node and connected to the stack nodes.
 */
Matthias Braun's avatar
Matthias Braun committed
898
static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp)
899
{
900
901
902
903
904
	ir_node *block;
	ir_graph *irg;
	ir_node *alloc_mem;
	ir_node *alloc_res;
	ir_type *type;
905
	dbg_info *dbg;
906

907
	const ir_edge_t *edge;
Matthias Braun's avatar
Matthias Braun committed
908
	ir_node *new_alloc, *size, *addr, *ins[2];
909
	unsigned stack_alignment;
910

911
	assert(get_Alloc_where(alloc) == stack_alloc);
912

913
914
915
916
917
	block = get_nodes_block(alloc);
	irg = get_irn_irg(block);
	alloc_mem = NULL;
	alloc_res = NULL;
	type = get_Alloc_type(alloc);
918

919
920
	foreach_out_edge(alloc, edge) {
		ir_node *irn = get_edge_src_irn(edge);
921

922
		assert(is_Proj(irn));
923
		switch (get_Proj_proj(irn)) {
924
925
926
927
928
929
930
931
		case pn_Alloc_M:
			alloc_mem = irn;
			break;
		case pn_Alloc_res:
			alloc_res = irn;
			break;
		default:
			break;
932
		}
933
	}
934

935
936
937
938
939
940
941
942
	/* Beware: currently Alloc nodes without a result might happen,
	   only escape analysis kills them and this phase runs only for object
	   oriented source. We kill the Alloc here. */
	if (alloc