benode.c 42.7 KB
Newer Older
Sebastian Hack's avatar
Sebastian Hack committed
1
2
3
4
5
6
7
/**
 * @file   benode.c
 * @date   17.05.2005
 * @author Sebastian Hack
 *
 * Backend node support.
 *
Michael Beck's avatar
Michael Beck committed
8
 * This file provides Perm, Copy, Spill and Reload nodes.
9
 *
10
 * Copyright (C) 2005-2006 Universitaet Karlsruhe
Sebastian Hack's avatar
Sebastian Hack committed
11
12
 * Released under the GPL
 */
13

Michael Beck's avatar
Michael Beck committed
14
15
16
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
Sebastian Hack's avatar
Sebastian Hack committed
17
18
19
20
21
22

#include <stdlib.h>

#include "obst.h"
#include "set.h"
#include "pmap.h"
23
#include "util.h"
Sebastian Hack's avatar
Sebastian Hack committed
24
#include "debug.h"
25
#include "fourcc.h"
Sebastian Hack's avatar
Sebastian Hack committed
26
#include "offset.h"
Sebastian Hack's avatar
Sebastian Hack committed
27
#include "bitfiddle.h"
Sebastian Hack's avatar
Sebastian Hack committed
28
29
30
31

#include "irop_t.h"
#include "irmode_t.h"
#include "irnode_t.h"
32
#include "ircons_t.h"
33
#include "irprintf.h"
Sebastian Hack's avatar
Sebastian Hack committed
34
#include "irgwalk.h"
Michael Beck's avatar
Michael Beck committed
35
#include "iropt_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
36

37
38
39
#include "be_t.h"
#include "belive_t.h"
#include "besched_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
40
41
#include "benode_t.h"

42
43
#include "beirgmod.h"

Sebastian Hack's avatar
Sebastian Hack committed
44
45
#define OUT_POS(x) (-((x) + 1))

Sebastian Hack's avatar
Sebastian Hack committed
46
47
/* Sometimes we want to put const nodes into get_irn_generic_attr ... */
#define get_irn_attr(irn) get_irn_generic_attr((ir_node *) (irn))
Daniel Grund's avatar
Daniel Grund committed
48

Sebastian Hack's avatar
Sebastian Hack committed
49
static unsigned be_node_tag = FOURCC('B', 'E', 'N', 'O');
50

Sebastian Hack's avatar
Sebastian Hack committed
51
52
53
54
55
56
typedef enum {
	be_req_kind_old_limited,
	be_req_kind_negate_old_limited,
	be_req_kind_single_reg
} be_req_kind_t;

Sebastian Hack's avatar
Sebastian Hack committed
57
58
typedef struct {
	arch_register_req_t req;
Sebastian Hack's avatar
Sebastian Hack committed
59
	be_req_kind_t       kind;
Sebastian Hack's avatar
Sebastian Hack committed
60
	arch_irn_flags_t    flags;
Sebastian Hack's avatar
Sebastian Hack committed
61
62
63
64
65
66
67
68
	union {
		struct {
			void (*old_limited)(void *ptr, bitset_t *bs);
			void *old_limited_env;
		} old_limited;

		const arch_register_t *single_reg;
	} x;
Sebastian Hack's avatar
Sebastian Hack committed
69
70
} be_req_t;

71
typedef struct {
72
	const arch_register_t *reg;
Sebastian Hack's avatar
Sebastian Hack committed
73
	be_req_t              req;
Sebastian Hack's avatar
Sebastian Hack committed
74
	be_req_t              in_req;
75
76
} be_reg_data_t;

77
/** The generic be nodes attribute type. */
78
typedef struct {
79
80
	int                   max_reg_data;
	be_reg_data_t         *reg_data;
81
82
} be_node_attr_t;

83
84
85
86
87
88
/** The be_Return nodes attribute type. */
typedef struct {
	be_node_attr_t node_attr;
	int            num_ret_vals;  /**< number of return values */
} be_return_attr_t;

89
/** The be_Stack attribute type. */
Sebastian Hack's avatar
Sebastian Hack committed
90
91
typedef struct {
	be_node_attr_t node_attr;
92
	int offset;           /**< The offset by which the stack shall be expanded/shrinked. */
Sebastian Hack's avatar
Sebastian Hack committed
93
94
} be_stack_attr_t;

95
/** The be_Frame attribute type. */
96
97
typedef struct {
	be_node_attr_t node_attr;
98
	ir_entity *ent;
99
100
101
	int offset;
} be_frame_attr_t;

102
/** The be_Call attribute type. */
103
104
typedef struct {
	be_node_attr_t node_attr;
105
	ir_entity *ent;      /**< The called entity if this is a static call. */
106
	ir_type *call_tp;    /**< The call type, copied from the original Call node. */
107
108
} be_call_attr_t;

109
typedef struct {
Matthias Braun's avatar
Matthias Braun committed
110
	be_node_attr_t node_attr;
111
112
	ir_entity **in_entities;
	ir_entity **out_entities;
Matthias Braun's avatar
Matthias Braun committed
113
} be_memperm_attr_t;
114

115
116
117
ir_op *op_be_Spill;
ir_op *op_be_Reload;
ir_op *op_be_Perm;
Matthias Braun's avatar
Matthias Braun committed
118
ir_op *op_be_MemPerm;
119
120
ir_op *op_be_Copy;
ir_op *op_be_Keep;
Sebastian Hack's avatar
Sebastian Hack committed
121
ir_op *op_be_CopyKeep;
122
123
124
ir_op *op_be_Call;
ir_op *op_be_Return;
ir_op *op_be_IncSP;
Sebastian Hack's avatar
Sebastian Hack committed
125
ir_op *op_be_AddSP;
Michael Beck's avatar
Michael Beck committed
126
ir_op *op_be_SubSP;
127
128
129
130
131
132
ir_op *op_be_SetSP;
ir_op *op_be_RegParams;
ir_op *op_be_StackParam;
ir_op *op_be_FrameAddr;
ir_op *op_be_FrameLoad;
ir_op *op_be_FrameStore;
133
ir_op *op_be_Barrier;
Sebastian Hack's avatar
Sebastian Hack committed
134

Sebastian Hack's avatar
Sebastian Hack committed
135
static int beo_base = -1;
Sebastian Hack's avatar
Sebastian Hack committed
136

Sebastian Hack's avatar
Sebastian Hack committed
137
static const ir_op_ops be_node_op_ops;
Sebastian Hack's avatar
Sebastian Hack committed
138

139
140
141
142
143
144
145
146
147
148
#define N   irop_flag_none
#define L   irop_flag_labeled
#define C   irop_flag_commutative
#define X   irop_flag_cfopcode
#define I   irop_flag_ip_cfopcode
#define F   irop_flag_fragile
#define Y   irop_flag_forking
#define H   irop_flag_highlevel
#define c   irop_flag_constlike
#define K   irop_flag_keep
149
150
#define M   irop_flag_machine

151

Michael Beck's avatar
Michael Beck committed
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/**
 * Compare two node attributes.
 *
 * @return zero if both attributes are identically
 */
static int cmp_node_attr(be_node_attr_t *a, be_node_attr_t *b) {
	if (a->max_reg_data == b->max_reg_data) {
		int i;

		for (i = 0; i < a->max_reg_data; ++i) {
			if (a->reg_data[i].reg    != b->reg_data[i].reg ||
			    memcmp(&a->reg_data[i].in_req, &b->reg_data[i].in_req, sizeof(b->reg_data[i].in_req)) ||
			    memcmp(&a->reg_data[i].req,    &b->reg_data[i].req,    sizeof(a->reg_data[i].req)))
				return 1;
		}
		return 0;
	}
	return 1;
}

/**
 * Compare the attributes of two FrameAddr nodes.
 *
 * @return zero if both attributes are identically
 */
static int FrameAddr_cmp_attr(ir_node *a, ir_node *b) {
	be_frame_attr_t *a_attr = get_irn_attr(a);
	be_frame_attr_t *b_attr = get_irn_attr(b);

181
182
183
	if (a_attr->ent == b_attr->ent && a_attr->offset == b_attr->offset)
		return cmp_node_attr(&a_attr->node_attr, &b_attr->node_attr);
	return 1;
Michael Beck's avatar
Michael Beck committed
184
185
}

Sebastian Hack's avatar
Sebastian Hack committed
186
187
void be_node_init(void) {
	static int inited = 0;
Sebastian Hack's avatar
Sebastian Hack committed
188

Sebastian Hack's avatar
Sebastian Hack committed
189
190
	if(inited)
		return;
Sebastian Hack's avatar
Sebastian Hack committed
191

Sebastian Hack's avatar
Sebastian Hack committed
192
	inited = 1;
Sebastian Hack's avatar
Sebastian Hack committed
193

194
195
	/* Acquire all needed opcodes. */
	beo_base = get_next_ir_opcodes(beo_Last - 1);
Sebastian Hack's avatar
Sebastian Hack committed
196

Matthias Braun's avatar
Matthias Braun committed
197
198
199
200
201
202
203
	op_be_Spill      = new_ir_op(beo_base + beo_Spill,      "be_Spill",      op_pin_state_mem_pinned, N, oparity_unary,    0, sizeof(be_frame_attr_t),   &be_node_op_ops);
	op_be_Reload     = new_ir_op(beo_base + beo_Reload,     "be_Reload",     op_pin_state_mem_pinned, N, oparity_zero,     0, sizeof(be_frame_attr_t),   &be_node_op_ops);
	op_be_Perm       = new_ir_op(beo_base + beo_Perm,       "be_Perm",       op_pin_state_pinned,     N, oparity_variable, 0, sizeof(be_node_attr_t),    &be_node_op_ops);
	op_be_MemPerm    = new_ir_op(beo_base + beo_MemPerm,    "be_MemPerm",    op_pin_state_mem_pinned, N, oparity_variable, 0, sizeof(be_memperm_attr_t), &be_node_op_ops);
	op_be_Copy       = new_ir_op(beo_base + beo_Copy,       "be_Copy",       op_pin_state_floats,     N, oparity_unary,    0, sizeof(be_node_attr_t),    &be_node_op_ops);
	op_be_Keep       = new_ir_op(beo_base + beo_Keep,       "be_Keep",       op_pin_state_pinned,     K, oparity_variable, 0, sizeof(be_node_attr_t),    &be_node_op_ops);
	op_be_CopyKeep   = new_ir_op(beo_base + beo_CopyKeep,   "be_CopyKeep",   op_pin_state_pinned,     K, oparity_variable, 0, sizeof(be_node_attr_t),    &be_node_op_ops);
204
	op_be_Call       = new_ir_op(beo_base + beo_Call,       "be_Call",       op_pin_state_pinned,     F, oparity_variable, 0, sizeof(be_call_attr_t),    &be_node_op_ops);
Matthias Braun's avatar
Matthias Braun committed
205
206
	op_be_Return     = new_ir_op(beo_base + beo_Return,     "be_Return",     op_pin_state_pinned,     X, oparity_variable, 0, sizeof(be_return_attr_t),  &be_node_op_ops);
	op_be_AddSP      = new_ir_op(beo_base + beo_AddSP,      "be_AddSP",      op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_node_attr_t),    &be_node_op_ops);
Michael Beck's avatar
Michael Beck committed
207
	op_be_SubSP      = new_ir_op(beo_base + beo_SubSP,      "be_SubSP",      op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_node_attr_t),    &be_node_op_ops);
Matthias Braun's avatar
Matthias Braun committed
208
	op_be_SetSP      = new_ir_op(beo_base + beo_SetSP,      "be_SetSP",      op_pin_state_pinned,     N, oparity_binary,   0, sizeof(be_stack_attr_t),   &be_node_op_ops);
209
	op_be_IncSP      = new_ir_op(beo_base + beo_IncSP,      "be_IncSP",      op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_stack_attr_t),   &be_node_op_ops);
Matthias Braun's avatar
Matthias Braun committed
210
211
212
213
214
215
	op_be_RegParams  = new_ir_op(beo_base + beo_RegParams,  "be_RegParams",  op_pin_state_pinned,     N, oparity_zero,     0, sizeof(be_node_attr_t),    &be_node_op_ops);
	op_be_StackParam = new_ir_op(beo_base + beo_StackParam, "be_StackParam", op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_frame_attr_t),   &be_node_op_ops);
	op_be_FrameAddr  = new_ir_op(beo_base + beo_FrameAddr,  "be_FrameAddr",  op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_frame_attr_t),   &be_node_op_ops);
	op_be_FrameLoad  = new_ir_op(beo_base + beo_FrameLoad,  "be_FrameLoad",  op_pin_state_pinned,     N, oparity_any,      0, sizeof(be_frame_attr_t),   &be_node_op_ops);
	op_be_FrameStore = new_ir_op(beo_base + beo_FrameStore, "be_FrameStore", op_pin_state_pinned,     N, oparity_any,      0, sizeof(be_frame_attr_t),   &be_node_op_ops);
	op_be_Barrier    = new_ir_op(beo_base + beo_Barrier,    "be_Barrier",    op_pin_state_pinned,     N, oparity_any,      0, sizeof(be_node_attr_t),    &be_node_op_ops);
216
217
218
219

	set_op_tag(op_be_Spill,      &be_node_tag);
	set_op_tag(op_be_Reload,     &be_node_tag);
	set_op_tag(op_be_Perm,       &be_node_tag);
Matthias Braun's avatar
Matthias Braun committed
220
	set_op_tag(op_be_MemPerm,    &be_node_tag);
221
222
	set_op_tag(op_be_Copy,       &be_node_tag);
	set_op_tag(op_be_Keep,       &be_node_tag);
Sebastian Hack's avatar
Sebastian Hack committed
223
	set_op_tag(op_be_CopyKeep,   &be_node_tag);
224
225
	set_op_tag(op_be_Call,       &be_node_tag);
	set_op_tag(op_be_Return,     &be_node_tag);
Sebastian Hack's avatar
Sebastian Hack committed
226
	set_op_tag(op_be_AddSP,      &be_node_tag);
Michael Beck's avatar
Michael Beck committed
227
	set_op_tag(op_be_SubSP,      &be_node_tag);
228
229
230
231
232
233
234
	set_op_tag(op_be_SetSP,      &be_node_tag);
	set_op_tag(op_be_IncSP,      &be_node_tag);
	set_op_tag(op_be_RegParams,  &be_node_tag);
	set_op_tag(op_be_StackParam, &be_node_tag);
	set_op_tag(op_be_FrameLoad,  &be_node_tag);
	set_op_tag(op_be_FrameStore, &be_node_tag);
	set_op_tag(op_be_FrameAddr,  &be_node_tag);
235
	set_op_tag(op_be_Barrier,    &be_node_tag);
Michael Beck's avatar
Michael Beck committed
236
237

	op_be_FrameAddr->ops.node_cmp_attr = FrameAddr_cmp_attr;
Sebastian Hack's avatar
Sebastian Hack committed
238
}
239

240
241
242
/**
 * Initializes the generic attribute of all be nodes and return ir.
 */
Sebastian Hack's avatar
Sebastian Hack committed
243
static void *init_node_attr(ir_node* irn, int max_reg_data)
Sebastian Hack's avatar
Sebastian Hack committed
244
{
Sebastian Hack's avatar
Sebastian Hack committed
245
	ir_graph *irg     = get_irn_irg(irn);
Sebastian Hack's avatar
Sebastian Hack committed
246
247
	be_node_attr_t *a = get_irn_attr(irn);

248
	memset(a, 0, sizeof(get_op_attr_size(get_irn_op(irn))));
Sebastian Hack's avatar
Sebastian Hack committed
249
250
	a->max_reg_data = max_reg_data;
	a->reg_data     = NULL;
Sebastian Hack's avatar
Sebastian Hack committed
251

Sebastian Hack's avatar
Sebastian Hack committed
252
	if(max_reg_data > 0) {
Sebastian Hack's avatar
Sebastian Hack committed
253
254
		int i;

Sebastian Hack's avatar
Sebastian Hack committed
255
256
257
		a->reg_data = NEW_ARR_D(be_reg_data_t, get_irg_obstack(irg), max_reg_data);
		memset(a->reg_data, 0, max_reg_data * sizeof(a->reg_data[0]));
		for(i = 0; i < max_reg_data; ++i) {
Sebastian Hack's avatar
Sebastian Hack committed
258
259
			a->reg_data[i].req.req.cls  = NULL;
			a->reg_data[i].req.req.type = arch_register_req_type_none;
Sebastian Hack's avatar
Sebastian Hack committed
260
261
262
263
264
		}
	}

	return a;
}
265

266
int is_be_node(const ir_node *irn)
267
{
Sebastian Hack's avatar
Sebastian Hack committed
268
	return get_op_tag(get_irn_op(irn)) == &be_node_tag;
269
270
}

Sebastian Hack's avatar
Sebastian Hack committed
271
be_opcode_t be_get_irn_opcode(const ir_node *irn)
272
{
Sebastian Hack's avatar
Sebastian Hack committed
273
	return is_be_node(irn) ? get_irn_opcode(irn) - beo_base : beo_NoBeOp;
274
275
}

Michael Beck's avatar
Michael Beck committed
276
277
278
279
280
281
282
283
284
285
/**
 * Skip Proj nodes and return their Proj numbers.
 *
 * If *node is a Proj or Proj(Proj) node, skip it.
 *
 * @param node  points to the node to be skipped
 *
 * @return 0 if *node was no Proj node, its Proj number else.
 */
static int redir_proj(const ir_node **node)
Sebastian Hack's avatar
Sebastian Hack committed
286
287
288
289
{
	const ir_node *n = *node;

	if(is_Proj(n)) {
290
291
292
293
294
295
296
		ir_node *irn;

		*node = irn = get_Proj_pred(n);
		if(is_Proj(irn)) {
			assert(get_irn_mode(irn) == mode_T);
			*node = get_Proj_pred(irn);
		}
Sebastian Hack's avatar
Sebastian Hack committed
297
298
299
300
301
302
		return get_Proj_proj(n);
	}

	return 0;
}

Sebastian Hack's avatar
Sebastian Hack committed
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
static be_node_attr_t *retrieve_irn_attr(const ir_node *irn, int *the_pos)
{
	int dummy;
	be_node_attr_t *res = NULL;
	int *pos = the_pos ? the_pos : &dummy;

	*pos = -1;
	if(is_Proj(irn)) {
		ir_node *pred = get_Proj_pred(irn);
		int p         = get_Proj_proj(irn);

		if(is_be_node(pred)) {
			assert(get_irn_mode(pred) == mode_T);
			*pos = p;
			res = get_irn_attr(pred);
			assert(p >= 0 && p < res->max_reg_data && "illegal proj number");
		}
	}

	else if(is_be_node(irn) && get_irn_mode(irn) != mode_T) {
		be_node_attr_t *a = get_irn_attr(irn);
		if(a->max_reg_data > 0) {
			res  = a;
			*pos = 0;
		}
	}

	return res;
}

static be_reg_data_t *retrieve_reg_data(const ir_node *irn)
{
	int pos;
	be_node_attr_t *a = retrieve_irn_attr(irn, &pos);
	return a ? &a->reg_data[pos] : NULL;
}

Sebastian Hack's avatar
Sebastian Hack committed
340
341
342
static void
be_node_set_irn_reg(const void *_self, ir_node *irn, const arch_register_t *reg)
{
Sebastian Hack's avatar
Sebastian Hack committed
343
	be_reg_data_t *r = retrieve_reg_data(irn);
Sebastian Hack's avatar
Sebastian Hack committed
344

Sebastian Hack's avatar
Sebastian Hack committed
345
346
	if(r)
		r->reg = reg;
Sebastian Hack's avatar
Sebastian Hack committed
347
348
349
}


350
351
ir_node *be_new_Spill(const arch_register_class_t *cls, const arch_register_class_t *cls_frame,
	ir_graph *irg, ir_node *bl, ir_node *frame, ir_node *to_spill)
352
{
Matthias Braun's avatar
Matthias Braun committed
353
	be_frame_attr_t *a;
354
	ir_node         *in[2];
355
	ir_node         *res;
356

357
358
359
	in[0]     = frame;
	in[1]     = to_spill;
	res       = new_ir_node(NULL, irg, bl, op_be_Spill, mode_M, 2, in);
360
361
	a         = init_node_attr(res, 2);
	a->ent    = NULL;
Matthias Braun's avatar
Matthias Braun committed
362
	a->offset = 0;
Sebastian Hack's avatar
Sebastian Hack committed
363

364
	be_node_set_reg_class(res, be_pos_Spill_frame, cls_frame);
365
	be_node_set_reg_class(res, be_pos_Spill_val, cls);
Sebastian Hack's avatar
Sebastian Hack committed
366
367
	return res;
}
368

369
370
ir_node *be_new_Reload(const arch_register_class_t *cls, const arch_register_class_t *cls_frame,
	ir_graph *irg, ir_node *bl, ir_node *frame, ir_node *mem, ir_mode *mode)
371
{
372
373
374
375
376
377
378
	ir_node *in[2];
	ir_node *res;

	in[0] = frame;
	in[1] = mem;
	res   = new_ir_node(NULL, irg, bl, op_be_Reload, mode, 2, in);

Sebastian Hack's avatar
Sebastian Hack committed
379
380
	init_node_attr(res, 2);
	be_node_set_reg_class(res, -1, cls);
381
	be_node_set_reg_class(res, be_pos_Reload_frame, cls_frame);
382
	be_node_set_flags(res, -1, arch_irn_flags_rematerializable);
Sebastian Hack's avatar
Sebastian Hack committed
383
384
	return res;
}
385

386
ir_node *be_get_Reload_mem(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
387
388
{
	assert(be_is_Reload(irn));
Daniel Grund's avatar
Daniel Grund committed
389
	return get_irn_n(irn, be_pos_Reload_mem);
Sebastian Hack's avatar
Sebastian Hack committed
390
391
}

392
393
394
395
396
397
ir_node *be_get_Reload_frame(const ir_node *irn)
{
	assert(be_is_Reload(irn));
	return get_irn_n(irn, be_pos_Reload_frame);
}

398
399
400
401
402
ir_node *be_get_Spill_val(const ir_node *irn)
{
	assert(be_is_Spill(irn));
	return get_irn_n(irn, be_pos_Spill_val);
}
403
404
405
406
407
ir_node *be_get_Spill_frame(const ir_node *irn)
{
	assert(be_is_Spill(irn));
	return get_irn_n(irn, be_pos_Spill_frame);
}
408

Sebastian Hack's avatar
Sebastian Hack committed
409
410
ir_node *be_new_Perm(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, int n, ir_node *in[])
{
Sebastian Hack's avatar
Sebastian Hack committed
411
	int i;
412
	ir_node *irn = new_ir_node(NULL, irg, bl, op_be_Perm, mode_T, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
413
414
415
416
417
418
	init_node_attr(irn, n);
	for(i = 0; i < n; ++i) {
		be_node_set_reg_class(irn, i, cls);
		be_node_set_reg_class(irn, OUT_POS(i), cls);
	}

Sebastian Hack's avatar
Sebastian Hack committed
419
420
	return irn;
}
421

Matthias Braun's avatar
Matthias Braun committed
422
423
424
425
426
ir_node *be_new_MemPerm(const arch_env_t *arch_env, ir_graph *irg, ir_node *bl, int n, ir_node *in[])
{
	int i;
	ir_node *frame = get_irg_frame(irg);
	const arch_register_class_t *cls_frame = arch_get_irn_reg_class(arch_env, frame, -1);
427
428
	ir_node *irn;
	const arch_register_t *sp = arch_env->isa->sp;
Matthias Braun's avatar
Matthias Braun committed
429
	be_memperm_attr_t *attr;
430
	ir_node **real_in;
Matthias Braun's avatar
Matthias Braun committed
431

432
433
434
435
436
437
438
439
	real_in = alloca((n+1) * sizeof(real_in[0]));
	real_in[0] = frame;
	memcpy(&real_in[1], in, n * sizeof(real_in[0]));

	irn =  new_ir_node(NULL, irg, bl, op_be_MemPerm, mode_T, n+1, real_in);

	init_node_attr(irn, n + 1);
	be_node_set_reg_class(irn, 0, sp->reg_class);
Matthias Braun's avatar
Matthias Braun committed
440
	for(i = 0; i < n; ++i) {
441
		be_node_set_reg_class(irn, i + 1, cls_frame);
Matthias Braun's avatar
Matthias Braun committed
442
443
444
445
446
		be_node_set_reg_class(irn, OUT_POS(i), cls_frame);
	}

	attr = get_irn_attr(irn);

447
448
	attr->in_entities = obstack_alloc(irg->obst, n * sizeof(attr->in_entities[0]));
	memset(attr->in_entities, 0, n * sizeof(attr->in_entities[0]));
Matthias Braun's avatar
Matthias Braun committed
449
450
451
452
453
454
455
	attr->out_entities = obstack_alloc(irg->obst, n*sizeof(attr->out_entities[0]));
	memset(attr->out_entities, 0, n*sizeof(attr->out_entities[0]));

	return irn;
}


Sebastian Hack's avatar
Sebastian Hack committed
456
457
458
459
ir_node *be_new_Copy(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, ir_node *op)
{
	ir_node *in[1];
	ir_node *res;
460

Sebastian Hack's avatar
Sebastian Hack committed
461
	in[0] = op;
462
	res   = new_ir_node(NULL, irg, bl, op_be_Copy, get_irn_mode(op), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
463
464
465
	init_node_attr(res, 1);
	be_node_set_reg_class(res, 0, cls);
	be_node_set_reg_class(res, OUT_POS(0), cls);
Sebastian Hack's avatar
Sebastian Hack committed
466
	return res;
467
468
}

469
470
471
472
ir_node *be_get_Copy_op(const ir_node *cpy) {
	return get_irn_n(cpy, be_pos_Copy_op);
}

473
474
475
476
void be_set_Copy_op(ir_node *cpy, ir_node *op) {
	set_irn_n(cpy, be_pos_Copy_op, op);
}

Sebastian Hack's avatar
Sebastian Hack committed
477
ir_node *be_new_Keep(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
478
{
Sebastian Hack's avatar
Sebastian Hack committed
479
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
480
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
481

482
	irn = new_ir_node(NULL, irg, bl, op_be_Keep, mode_ANY, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
483
484
485
486
	init_node_attr(irn, n);
	for(i = 0; i < n; ++i) {
		be_node_set_reg_class(irn, i, cls);
	}
Sebastian Hack's avatar
Sebastian Hack committed
487
488
	keep_alive(irn);
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
489
490
}

491
492
ir_node *be_new_Call(dbg_info *dbg, ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *sp, ir_node *ptr,
                     int n_outs, int n, ir_node *in[], ir_type *call_tp)
Sebastian Hack's avatar
Sebastian Hack committed
493
{
494
495
	be_call_attr_t *a;
	int real_n = be_pos_Call_first_arg + n;
Sebastian Hack's avatar
Sebastian Hack committed
496
497
	ir_node *irn;
	ir_node **real_in;
Sebastian Hack's avatar
Sebastian Hack committed
498

499
500
501
502
503
	NEW_ARR_A(ir_node *, real_in, real_n);
	real_in[be_pos_Call_mem] = mem;
	real_in[be_pos_Call_sp]  = sp;
	real_in[be_pos_Call_ptr] = ptr;
	memcpy(&real_in[be_pos_Call_first_arg], in, n * sizeof(in[0]));
Sebastian Hack's avatar
Sebastian Hack committed
504

505
	irn = new_ir_node(dbg, irg, bl, op_be_Call, mode_T, real_n, real_in);
506
507
508
	a = init_node_attr(irn, (n_outs > real_n ? n_outs : real_n));
	a->ent     = NULL;
	a->call_tp = call_tp;
Sebastian Hack's avatar
Sebastian Hack committed
509
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
510
511
}

512
/* Gets the call entity or NULL if this is no static call. */
513
ir_entity *be_Call_get_entity(const ir_node *call) {
514
515
516
517
518
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	return a->ent;
}

519
/* Sets the call entity. */
520
void be_Call_set_entity(ir_node *call, ir_entity *ent) {
521
522
523
524
525
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	a->ent = ent;
}

526
527
528
529
530
531
532
533
534
535
536
537
538
539
/* Gets the call type. */
ir_type *be_Call_get_type(ir_node *call) {
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	return a->call_tp;
}

/* Sets the call type. */
void be_Call_set_type(ir_node *call, ir_type *call_tp) {
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	a->call_tp = call_tp;
}

540
541
/* Construct a new be_Return. */
ir_node *be_new_Return(dbg_info *dbg, ir_graph *irg, ir_node *bl, int n_res, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
542
{
543
	be_return_attr_t *a;
544
	ir_node *irn = new_ir_node(dbg, irg, bl, op_be_Return, mode_X, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
545
	init_node_attr(irn, n);
546
547
	a = get_irn_attr(irn);
	a->num_ret_vals = n_res;
Sebastian Hack's avatar
Sebastian Hack committed
548
549
550
551

	return irn;
}

552
553
554
555
556
557
558
/* Returns the number of real returns values */
int be_Return_get_n_rets(ir_node *ret)
{
	be_return_attr_t *a = get_irn_attr(ret);
	return a->num_ret_vals;
}

Sebastian Hack's avatar
Sebastian Hack committed
559
ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, int offset)
Sebastian Hack's avatar
Sebastian Hack committed
560
{
Sebastian Hack's avatar
Sebastian Hack committed
561
562
	be_stack_attr_t *a;
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
563
	ir_node *in[1];
Sebastian Hack's avatar
Sebastian Hack committed
564
565

	in[0]     = old_sp;
Sebastian Hack's avatar
Sebastian Hack committed
566
	irn       = new_ir_node(NULL, irg, bl, op_be_IncSP, sp->reg_class->mode, sizeof(in) / sizeof(in[0]), in);
Sebastian Hack's avatar
Sebastian Hack committed
567
	a         = init_node_attr(irn, 1);
Sebastian Hack's avatar
Sebastian Hack committed
568
569
	a->offset = offset;

570
	be_node_set_flags(irn, -1, arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
571

Sebastian Hack's avatar
Sebastian Hack committed
572
	/* Set output constraint to stack register. */
Sebastian Hack's avatar
Sebastian Hack committed
573
	be_node_set_reg_class(irn, 0, sp->reg_class);
574
	be_set_constr_single_reg(irn, BE_OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
575
	be_node_set_irn_reg(NULL, irn, sp);
Sebastian Hack's avatar
Sebastian Hack committed
576
577

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
578
}
Sebastian Hack's avatar
Sebastian Hack committed
579

Sebastian Hack's avatar
Sebastian Hack committed
580
ir_node *be_new_AddSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *sz)
Sebastian Hack's avatar
Sebastian Hack committed
581
{
Sebastian Hack's avatar
Sebastian Hack committed
582
	be_node_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
583
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
584
	ir_node *in[be_pos_AddSP_last];
Sebastian Hack's avatar
Sebastian Hack committed
585

Sebastian Hack's avatar
Sebastian Hack committed
586
587
	in[be_pos_AddSP_old_sp] = old_sp;
	in[be_pos_AddSP_size]   = sz;
Sebastian Hack's avatar
Sebastian Hack committed
588

589
590
	irn = new_ir_node(NULL, irg, bl, op_be_AddSP, mode_T, be_pos_AddSP_last, in);
	a   = init_node_attr(irn, be_pos_AddSP_last);
Sebastian Hack's avatar
Sebastian Hack committed
591

Sebastian Hack's avatar
Sebastian Hack committed
592
	be_node_set_flags(irn, OUT_POS(pn_be_AddSP_res), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
593
594

	/* Set output constraint to stack register. */
595
596
	be_set_constr_single_reg(irn, be_pos_AddSP_old_sp, sp);
	be_node_set_reg_class(irn, be_pos_AddSP_size, arch_register_get_class(sp));
Sebastian Hack's avatar
Sebastian Hack committed
597
	be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_res), sp);
598
	a->reg_data[pn_be_AddSP_res].reg = sp;
Sebastian Hack's avatar
Sebastian Hack committed
599
600
601
602

	return irn;
}

Michael Beck's avatar
Michael Beck committed
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
ir_node *be_new_SubSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *sz)
{
	be_node_attr_t *a;
	ir_node *irn;
	ir_node *in[be_pos_SubSP_last];

	in[be_pos_SubSP_old_sp] = old_sp;
	in[be_pos_SubSP_size]   = sz;

	irn = new_ir_node(NULL, irg, bl, op_be_SubSP, mode_T, be_pos_SubSP_last, in);
	a   = init_node_attr(irn, be_pos_SubSP_last);

	be_node_set_flags(irn, OUT_POS(pn_be_SubSP_res), arch_irn_flags_ignore | arch_irn_flags_modify_sp);

	/* Set output constraint to stack register. */
	be_set_constr_single_reg(irn, be_pos_SubSP_old_sp, sp);
	be_node_set_reg_class(irn, be_pos_SubSP_size, arch_register_get_class(sp));
	be_set_constr_single_reg(irn, OUT_POS(pn_be_SubSP_res), sp);
	a->reg_data[pn_be_SubSP_res].reg = sp;

	return irn;
}

Sebastian Hack's avatar
Sebastian Hack committed
626
627
628
629
630
631
632
633
634
ir_node *be_new_SetSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *op, ir_node *mem)
{
	be_node_attr_t *a;
	ir_node *irn;
	ir_node *in[3];

	in[0]    = mem;
	in[1]    = old_sp;
	in[2]    = op;
635
	irn      = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
636
637
	a        = init_node_attr(irn, 3);

638
	be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
639
640
641

	/* Set output constraint to stack register. */
	be_set_constr_single_reg(irn, OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
642
643
	be_node_set_reg_class(irn, be_pos_AddSP_size, sp->reg_class);
	be_node_set_reg_class(irn, be_pos_AddSP_old_sp, sp->reg_class);
Sebastian Hack's avatar
Sebastian Hack committed
644
645

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
646
}
Sebastian Hack's avatar
Sebastian Hack committed
647

648
ir_node *be_new_StackParam(const arch_register_class_t *cls, const arch_register_class_t *cls_frame, ir_graph *irg, ir_node *bl, ir_mode *mode, ir_node *frame_pointer, ir_entity *ent)
Sebastian Hack's avatar
Sebastian Hack committed
649
{
650
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
651
652
653
	ir_node *irn;
	ir_node *in[1];

654
	in[0] = frame_pointer;
655
	irn = new_ir_node(NULL, irg, bl, op_be_StackParam, mode, 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
656
	a = init_node_attr(irn, 1);
657
	a->ent = ent;
Sebastian Hack's avatar
Sebastian Hack committed
658
659
660

	be_node_set_reg_class(irn, 0, cls_frame);
	be_node_set_reg_class(irn, OUT_POS(0), cls);
Sebastian Hack's avatar
Sebastian Hack committed
661
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
662
}
Sebastian Hack's avatar
Sebastian Hack committed
663

664
ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs)
Sebastian Hack's avatar
Sebastian Hack committed
665
666
667
668
{
	ir_node *irn;
	ir_node *in[1];

669
	irn = new_ir_node(NULL, irg, bl, op_be_RegParams, mode_T, 0, in);
Sebastian Hack's avatar
Sebastian Hack committed
670
	init_node_attr(irn, n_outs);
Sebastian Hack's avatar
Sebastian Hack committed
671
672
673
	return irn;
}

674
ir_node *be_new_FrameLoad(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
675
						  ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_entity *ent)
676
677
678
679
680
681
682
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[2];

	in[0]  = mem;
	in[1]  = frame;
683
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameLoad, mode_T, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
684
	a      = init_node_attr(irn, 3);
685
686
687
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 1, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
688
	be_node_set_reg_class(irn, OUT_POS(pn_Load_res), cls_data);
689
690
691
692
	return irn;
}

ir_node *be_new_FrameStore(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
693
						   ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_node *data, ir_entity *ent)
694
695
696
697
698
699
700
701
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[3];

	in[0]  = mem;
	in[1]  = frame;
	in[2]  = data;
702
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameStore, mode_T, 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
703
	a      = init_node_attr(irn, 3);
704
705
706
707
708
709
710
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 1, cls_frame);
	be_node_set_reg_class(irn, 2, cls_data);
	return irn;
}

711
ir_node *be_new_FrameAddr(const arch_register_class_t *cls_frame, ir_graph *irg, ir_node *bl, ir_node *frame, ir_entity *ent)
Sebastian Hack's avatar
Sebastian Hack committed
712
{
713
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
714
715
716
	ir_node *irn;
	ir_node *in[1];

717
	in[0]  = frame;
718
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameAddr, get_irn_mode(frame), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
719
	a      = init_node_attr(irn, 1);
720
721
722
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 0, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
723
	be_node_set_reg_class(irn, OUT_POS(0), cls_frame);
Michael Beck's avatar
Michael Beck committed
724
725

	return optimize_node(irn);
Sebastian Hack's avatar
Sebastian Hack committed
726
727
}

Sebastian Hack's avatar
Sebastian Hack committed
728
729
730
731
732
733
734
735
ir_node *be_new_CopyKeep(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, ir_node *src, int n, ir_node *in_keep[], ir_mode *mode)
{
	ir_node *irn;
	ir_node **in = (ir_node **) alloca((n + 1) * sizeof(in[0]));

	in[0] = src;
	memcpy(&in[1], in_keep, n * sizeof(in[0]));
	irn   = new_ir_node(NULL, irg, bl, op_be_CopyKeep, mode, n + 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
736
	init_node_attr(irn, n + 1);
Sebastian Hack's avatar
Sebastian Hack committed
737
738
739
740
741
742
743
744
745
746
747
748
749
750
	be_node_set_reg_class(irn, OUT_POS(0), cls);
	be_node_set_reg_class(irn, 0, cls);

	return irn;
}

ir_node *be_new_CopyKeep_single(const arch_register_class_t *cls, ir_graph *irg, ir_node *bl, ir_node *src, ir_node *keep, ir_mode *mode)
{
	ir_node *in[1];

	in[0] = keep;
	return be_new_CopyKeep(cls, irg, bl, src, 1, in, mode);
}

751
752
753
754
755
756
757
758
ir_node *be_get_CopyKeep_op(const ir_node *cpy) {
	return get_irn_n(cpy, be_pos_CopyKeep_op);
}

void be_set_CopyKeep_op(ir_node *cpy, ir_node *op) {
	set_irn_n(cpy, be_pos_CopyKeep_op, op);
}

759
ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
760
761
762
{
	ir_node *irn;

763
	irn = new_ir_node(NULL, irg, bl, op_be_Barrier, mode_T, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
764
765
766
767
	init_node_attr(irn, n);
	return irn;
}

Sebastian Hack's avatar
Sebastian Hack committed
768
769
770
int be_is_Spill         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Spill          ; }
int be_is_Reload        (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Reload         ; }
int be_is_Copy          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Copy           ; }
Sebastian Hack's avatar
Sebastian Hack committed
771
int be_is_CopyKeep      (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_CopyKeep       ; }
Sebastian Hack's avatar
Sebastian Hack committed
772
int be_is_Perm          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Perm           ; }
Matthias Braun's avatar
Matthias Braun committed
773
int be_is_MemPerm       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_MemPerm        ; }
Sebastian Hack's avatar
Sebastian Hack committed
774
775
776
777
int be_is_Keep          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Keep           ; }
int be_is_Call          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Call           ; }
int be_is_Return        (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Return         ; }
int be_is_IncSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_IncSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
778
int be_is_SetSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SetSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
779
int be_is_AddSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_AddSP          ; }
780
int be_is_SubSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SubSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
781
782
int be_is_RegParams     (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_RegParams      ; }
int be_is_StackParam    (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_StackParam     ; }
783
784
785
int be_is_FrameAddr     (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_FrameAddr      ; }
int be_is_FrameLoad     (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_FrameLoad      ; }
int be_is_FrameStore    (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_FrameStore     ; }
786
int be_is_Barrier       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Barrier        ; }
787
788
789
790
791
792

int be_has_frame_entity(const ir_node *irn)
{
	switch(be_get_irn_opcode(irn)) {
	case beo_StackParam:
	case beo_Spill:
793
	case beo_Reload:
794
795
796
797
	case beo_FrameStore:
	case beo_FrameLoad:
	case beo_FrameAddr:
		return 1;
798
799
	default:
		return 0;
800
801
802
	}
}

803
ir_entity *be_get_frame_entity(const ir_node *irn)
804
{
805
	if (be_has_frame_entity(irn)) {
806
807
808
809
810
		be_frame_attr_t *a = get_irn_attr(irn);
		return a->ent;
	}
	return NULL;
}
Sebastian Hack's avatar
Sebastian Hack committed
811

812
813
814
815
816
817
818
819
820
821
int be_get_frame_offset(const ir_node *irn)
{
	assert(is_be_node(irn));
	if (be_has_frame_entity(irn)) {
		be_frame_attr_t *a = get_irn_attr(irn);
		return a->offset;
	}
	return 0;
}

822
void be_set_MemPerm_in_entity(const ir_node *irn, int n, ir_entity *ent)
Matthias Braun's avatar
Matthias Braun committed
823
824
825
826
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
827
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
828
829
830
831

	attr->in_entities[n] = ent;
}

832
ir_entity* be_get_MemPerm_in_entity(const ir_node* irn, int n)
Matthias Braun's avatar
Matthias Braun committed
833
834
835
836
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
837
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
838
839
840
841

	return attr->in_entities[n];
}

842
void be_set_MemPerm_out_entity(const ir_node *irn, int n, ir_entity *ent)
Matthias Braun's avatar
Matthias Braun committed
843
844
845
846
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
847
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
848
849
850
851

	attr->out_entities[n] = ent;
}

852
ir_entity* be_get_MemPerm_out_entity(const ir_node* irn, int n)
Matthias Braun's avatar
Matthias Braun committed
853
854
855
856
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
857
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
858
859
860
861

	return attr->out_entities[n];
}

862
863
864
865
866
int be_get_MemPerm_entity_arity(const ir_node *irn)
{
	return get_irn_arity(irn) - 1;
}

Sebastian Hack's avatar
Sebastian Hack committed
867
static void be_limited(void *data, bitset_t *bs)
Sebastian Hack's avatar
Sebastian Hack committed
868
{
Sebastian Hack's avatar
Sebastian Hack committed
869
870
	be_req_t *req = data;

Sebastian Hack's avatar
Sebastian Hack committed
871
872
873
874
875
876
877
878
879
880
881
882
	switch(req->kind) {
	case be_req_kind_negate_old_limited:
	case be_req_kind_old_limited:
		req->x.old_limited.old_limited(req->x.old_limited.old_limited_env, bs);
		if(req->kind == be_req_kind_negate_old_limited)
			bitset_flip_all(bs);
		break;
	case be_req_kind_single_reg:
		bitset_clear_all(bs);
		bitset_set(bs, req->x.single_reg->index);
		break;
	}
Sebastian Hack's avatar
Sebastian Hack committed
883
884
}

Sebastian Hack's avatar
Sebastian Hack committed
885
static INLINE be_req_t *get_req(ir_node *irn, int pos)
Sebastian Hack's avatar
Sebastian Hack committed
886
{
Michael Beck's avatar
Michael Beck committed
887
	int idx           = pos < 0 ? -(pos + 1) : pos;
Sebastian Hack's avatar
Sebastian Hack committed
888
889
890
891
892
893
	be_node_attr_t *a = get_irn_attr(irn);
	be_reg_data_t *rd = &a->reg_data[idx];
	be_req_t       *r = pos < 0 ? &rd->req : &rd->in_req;

	assert(is_be_node(irn));
	assert(!(pos >= 0) || pos < get_irn_arity(irn));
Sebastian Hack's avatar
Sebastian Hack committed
894
	assert(!(pos < 0)  || -(pos + 1) <= a->max_reg_data);
Sebastian Hack's avatar
Sebastian Hack committed
895

Sebastian Hack's avatar
Sebastian Hack committed
896
897
898
899
900
901
902
	return r;
}

void be_set_constr_single_reg(ir_node *irn, int pos, const arch_register_t *reg)
{
	be_req_t *r = get_req(irn, pos);

Sebastian Hack's avatar
Sebastian Hack committed
903
904
905
906
907
908
909
910
	r->kind            = be_req_kind_single_reg;
	r->x.single_reg    = reg;
	r->req.limited     = be_limited;
	r->req.limited_env = r;
	r->req.type        = arch_register_req_type_limited;
	r->req.cls         = reg->reg_class;
}

911
912
void be_set_constr_limited(ir_node *irn, int pos, const arch_register_req_t *req)
{
Sebastian Hack's avatar
Sebastian Hack committed
913
	be_req_t *r = get_req(irn, pos);
914
915
916
917
918
919
920
921
922
923
924
925
926

	assert(arch_register_req_is(req, limited));

	r->kind            = be_req_kind_old_limited;
	r->req.limited     = be_limited;
	r->req.limited_env = r;
	r->req.type        = arch_register_req_type_limited;
	r->req.cls         = req->cls;

	r->x.old_limited.old_limited     = req->limited;
	r->x.old_limited.old_limited_env = req->limited_env;
}

Sebastian Hack's avatar
Sebastian Hack committed
927
928
929
930
931
932
933
934
935
void be_node_set_flags(ir_node *irn, int pos, arch_irn_flags_t flags)
{
	be_req_t *r = get_req(irn, pos);
	r->flags = flags;
}

void be_node_set_reg_class(ir_node *irn, int pos, const arch_register_class_t *cls)
{
	be_req_t *r = get_req(irn, pos);
936

Sebastian Hack's avatar
Sebastian Hack committed
937
	r->req.cls = cls;
938
939
940
941

	if (cls == NULL)
		r->req.type = arch_register_req_type_none;
	else if (r->req.type == arch_register_req_type_none)
Sebastian Hack's avatar
Sebastian Hack committed
942
		r->req.type = arch_register_req_type_normal;
Sebastian Hack's avatar
Sebastian Hack committed
943
944
}

945
946
947
948
949
950
void be_node_set_req_type(ir_node *irn, int pos, arch_register_req_type_t type)
{
	be_req_t *r = get_req(irn, pos);
	r->req.type = type;
}

Michael Beck's avatar
BugFix:    
Michael Beck committed
951
952
953
954
955
ir_node *be_get_IncSP_pred(ir_node *irn) {
	assert(be_is_IncSP(irn));
	return get_irn_n(irn, 0);
}

956
void be_set_IncSP_pred(ir_node *incsp, ir_node *pred) {
957
958
959
960
	assert(be_is_IncSP(incsp));
	set_irn_n(incsp, 0, pred);
}

Michael Beck's avatar
Michael Beck committed
961
962
963
964
965
ir_node *be_get_IncSP_mem(ir_node *irn) {
	assert(be_is_IncSP(irn));
	return get_irn_n(irn, 1);
}

966
void be_set_IncSP_offset(ir_node *irn, int offset)
Sebastian Hack's avatar
Sebastian Hack committed
967
968
969
970
971
{
	be_stack_attr_t *a = get_irn_attr(irn);
	assert(be_is_IncSP(irn));
	a->offset = offset;
}
972

973
int be_get_IncSP_offset(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
974
{
Sebastian Hack's avatar
Sebastian Hack committed
975
976
977
978
	be_stack_attr_t *a = get_irn_attr(irn);
	assert(be_is_IncSP(irn));
	return a->offset;
}
Sebastian Hack's avatar
Sebastian Hack committed
979

Matthias Braun's avatar
Matthias Braun committed
980
ir_node *be_spill(const arch_env_t *arch_env, ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
981
{
982
983
984
985
986
	ir_node                     *bl        = get_nodes_block(irn);
	ir_graph                    *irg       = get_irn_irg(bl);
	ir_node                     *frame     = get_irg_frame(irg);
	const arch_register_class_t *cls       = arch_get_irn_reg_class(arch_env, irn, -1);
	const arch_register_class_t *cls_frame = arch_get_irn_reg_class(arch_env, frame, -1);
987
	ir_node                     *spill;
Sebastian Hack's avatar
Sebastian Hack committed
988

989
	spill = be_new_Spill(cls, cls_frame, irg, bl, frame, irn);
Christian Würdig's avatar
Christian Würdig committed
990
	return spill;
Sebastian Hack's avatar
Sebastian Hack committed
991
992
}

993
ir_node *be_reload(const arch_env_t *arch_env, const arch_register_class_t *cls, ir_node *insert, ir_mode *mode, ir_node *spill)
Sebastian Hack's avatar
Sebastian Hack committed
994
{
995
	ir_node  *reload;
996
997
998
999
	ir_node  *bl    = is_Block(insert) ? insert : get_nodes_block(insert);
	ir_graph *irg   = get_irn_irg(bl);
	ir_node  *frame = get_irg_frame(irg);
	const arch_register_class_t *cls_frame = arch_get_irn_reg_class(arch_env, frame, -1);
Sebastian Hack's avatar
Sebastian Hack committed
1000

Sebastian Hack's avatar
Sebastian Hack committed
1001
	assert(be_is_Spill(spill) || (is_Phi(spill) && get_irn_mode(spill) == mode_M));
Sebastian Hack's avatar
Sebastian Hack committed
1002

1003
	reload = be_new_Reload(cls, cls_frame, irg, bl, frame, spill, mode);
Sebastian Hack's avatar
Sebastian Hack committed
1004