benode.c 40.4 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
 *
Sebastian Hack's avatar
Sebastian Hack committed
10
11
12
 * Copyright (C) 2005 Universitaet Karlsruhe
 * 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
92
typedef struct {
	be_node_attr_t node_attr;
	int offset;           /**< The offset by which the stack shall be increased/decreased. */
93
	be_stack_dir_t dir;   /**< The direction in which the stack shall be modified (expand or shrink). */
Sebastian Hack's avatar
Sebastian Hack committed
94
95
} be_stack_attr_t;

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

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

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

116
117
118
ir_op *op_be_Spill;
ir_op *op_be_Reload;
ir_op *op_be_Perm;
Matthias Braun's avatar
Matthias Braun committed
119
ir_op *op_be_MemPerm;
120
121
ir_op *op_be_Copy;
ir_op *op_be_Keep;
Sebastian Hack's avatar
Sebastian Hack committed
122
ir_op *op_be_CopyKeep;
123
124
125
ir_op *op_be_Call;
ir_op *op_be_Return;
ir_op *op_be_IncSP;
Sebastian Hack's avatar
Sebastian Hack committed
126
ir_op *op_be_AddSP;
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
204
205
206
207
208
209
210
211
212
213
214
	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);
	op_be_Call       = new_ir_op(beo_base + beo_Call,       "be_Call",       op_pin_state_pinned,     N, oparity_variable, 0, sizeof(be_call_attr_t),    &be_node_op_ops);
	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);
	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);
	op_be_IncSP      = new_ir_op(beo_base + beo_IncSP,      "be_IncSP",      op_pin_state_pinned,     N, oparity_binary,   0, sizeof(be_stack_attr_t),   &be_node_op_ops);
	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);
215
216
217
218

	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
219
	set_op_tag(op_be_MemPerm,    &be_node_tag);
220
221
	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
222
	set_op_tag(op_be_CopyKeep,   &be_node_tag);
223
224
	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
225
	set_op_tag(op_be_AddSP,      &be_node_tag);
226
227
228
229
230
231
232
	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);
233
	set_op_tag(op_be_Barrier,    &be_node_tag);
Michael Beck's avatar
Michael Beck committed
234
235

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

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

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

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

Sebastian Hack's avatar
Sebastian Hack committed
253
254
255
		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
256
257
			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
258
259
260
261
262
		}
	}

	return a;
}
263

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

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

Sebastian Hack's avatar
Sebastian Hack committed
274
275
276
277
278
static int redir_proj(const ir_node **node, int pos)
{
	const ir_node *n = *node;

	if(is_Proj(n)) {
279
280
281
282
283
284
285
		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
286
287
288
289
290
291
		return get_Proj_proj(n);
	}

	return 0;
}

Sebastian Hack's avatar
Sebastian Hack committed
292
293
294
295
296
297
298
299
300
301
302
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
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
329
330
331
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
332
	be_reg_data_t *r = retrieve_reg_data(irn);
Sebastian Hack's avatar
Sebastian Hack committed
333

Sebastian Hack's avatar
Sebastian Hack committed
334
335
	if(r)
		r->reg = reg;
Sebastian Hack's avatar
Sebastian Hack committed
336
337
338
}


Matthias Braun's avatar
Matthias Braun committed
339
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)
340
{
Matthias Braun's avatar
Matthias Braun committed
341
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
342
	ir_node *in[2];
Sebastian Hack's avatar
Sebastian Hack committed
343
	ir_node *res;
344

Sebastian Hack's avatar
Sebastian Hack committed
345
346
	in[0] = frame;
	in[1] = to_spill;
347
	res   = new_ir_node(NULL, irg, bl, op_be_Spill, mode_M, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
348
	a     = init_node_attr(res, 2);
Matthias Braun's avatar
Matthias Braun committed
349
350
	a->ent = NULL;
	a->offset = 0;
Sebastian Hack's avatar
Sebastian Hack committed
351
352
353

	be_node_set_reg_class(res, 0, cls_frame);
	be_node_set_reg_class(res, 1, cls);
Sebastian Hack's avatar
Sebastian Hack committed
354
355
	return res;
}
356

Sebastian Hack's avatar
Sebastian Hack committed
357
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)
358
{
Sebastian Hack's avatar
Sebastian Hack committed
359
	ir_node *in[2];
Sebastian Hack's avatar
Sebastian Hack committed
360
	ir_node *res;
361

Sebastian Hack's avatar
Sebastian Hack committed
362
363
	in[0] = frame;
	in[1] = mem;
364
	res   = new_ir_node(NULL, irg, bl, op_be_Reload, mode, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
365
366
367
	init_node_attr(res, 2);
	be_node_set_reg_class(res, 0, cls_frame);
	be_node_set_reg_class(res, -1, cls);
Sebastian Hack's avatar
Sebastian Hack committed
368
369
	return res;
}
370

371
ir_node *be_get_Reload_mem(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
372
373
{
	assert(be_is_Reload(irn));
Daniel Grund's avatar
Daniel Grund committed
374
	return get_irn_n(irn, be_pos_Reload_mem);
Sebastian Hack's avatar
Sebastian Hack committed
375
376
}

377
378
379
380
381
382
ir_node *be_get_Reload_frame(const ir_node *irn)
{
	assert(be_is_Reload(irn));
	return get_irn_n(irn, be_pos_Reload_frame);
}

Sebastian Hack's avatar
Sebastian Hack committed
383
384
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
385
	int i;
386
	ir_node *irn = new_ir_node(NULL, irg, bl, op_be_Perm, mode_T, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
387
388
389
390
391
392
	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
393
394
	return irn;
}
395

Matthias Braun's avatar
Matthias Braun committed
396
397
398
399
400
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);
401
402
	ir_node *irn;
	const arch_register_t *sp = arch_env->isa->sp;
Matthias Braun's avatar
Matthias Braun committed
403
	be_memperm_attr_t *attr;
404
	ir_node **real_in;
Matthias Braun's avatar
Matthias Braun committed
405

406
407
408
409
410
411
412
413
	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
414
	for(i = 0; i < n; ++i) {
415
		be_node_set_reg_class(irn, i + 1, cls_frame);
Matthias Braun's avatar
Matthias Braun committed
416
417
418
419
420
		be_node_set_reg_class(irn, OUT_POS(i), cls_frame);
	}

	attr = get_irn_attr(irn);

421
422
	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
423
424
425
426
427
428
429
	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
430
431
432
433
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;
434

Sebastian Hack's avatar
Sebastian Hack committed
435
	in[0] = op;
436
	res   = new_ir_node(NULL, irg, bl, op_be_Copy, get_irn_mode(op), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
437
438
439
	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
440
	return res;
441
442
}

443
444
445
446
ir_node *be_get_Copy_op(const ir_node *cpy) {
	return get_irn_n(cpy, be_pos_Copy_op);
}

447
448
449
450
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
451
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
452
{
Sebastian Hack's avatar
Sebastian Hack committed
453
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
454
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
455

456
	irn = new_ir_node(NULL, irg, bl, op_be_Keep, mode_ANY, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
457
458
459
460
	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
461
462
	keep_alive(irn);
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
463
464
}

465
466
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
467
{
468
469
	be_call_attr_t *a;
	int real_n = be_pos_Call_first_arg + n;
Sebastian Hack's avatar
Sebastian Hack committed
470
471
	ir_node *irn;
	ir_node **real_in;
Sebastian Hack's avatar
Sebastian Hack committed
472

473
474
475
476
477
	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
478

479
	irn = new_ir_node(dbg, irg, bl, op_be_Call, mode_T, real_n, real_in);
480
481
482
	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
483
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
484
485
}

486
487
/* Gets the call entity or NULL if this is no static call. */
entity *be_Call_get_entity(const ir_node *call) {
488
489
490
491
492
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	return a->ent;
}

493
494
/* Sets the call entity. */
void be_Call_set_entity(ir_node *call, entity *ent) {
495
496
497
498
499
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	a->ent = ent;
}

500
501
502
503
504
505
506
507
508
509
510
511
512
513
/* 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;
}

514
515
/* 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
516
{
517
	be_return_attr_t *a;
518
	ir_node *irn = new_ir_node(dbg, irg, bl, op_be_Return, mode_X, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
519
	init_node_attr(irn, n);
520
521
	a = get_irn_attr(irn);
	a->num_ret_vals = n_res;
Sebastian Hack's avatar
Sebastian Hack committed
522
523
524
525

	return irn;
}

526
527
528
529
530
531
532
/* 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;
}

533
ir_node *be_new_IncSP(const arch_register_t *sp, ir_graph *irg, ir_node *bl, ir_node *old_sp, ir_node *mem, unsigned offset, be_stack_dir_t dir)
Sebastian Hack's avatar
Sebastian Hack committed
534
{
Sebastian Hack's avatar
Sebastian Hack committed
535
536
	be_stack_attr_t *a;
	ir_node *irn;
537
	ir_node *in[2];
Sebastian Hack's avatar
Sebastian Hack committed
538
539

	in[0]     = old_sp;
540
	in[1]     = mem;
541
	irn       = new_ir_node(NULL, irg, bl, op_be_IncSP, sp->reg_class->mode, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
542
	a         = init_node_attr(irn, 1);
Sebastian Hack's avatar
Sebastian Hack committed
543
544
545
	a->dir    = dir;
	a->offset = offset;

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

Sebastian Hack's avatar
Sebastian Hack committed
548
	/* Set output constraint to stack register. */
Sebastian Hack's avatar
Sebastian Hack committed
549
	be_node_set_reg_class(irn, 0, sp->reg_class);
550
	be_set_constr_single_reg(irn, BE_OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
551
	be_node_set_irn_reg(NULL, irn, sp);
Sebastian Hack's avatar
Sebastian Hack committed
552
553

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
554
}
Sebastian Hack's avatar
Sebastian Hack committed
555

Sebastian Hack's avatar
Sebastian Hack committed
556
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
557
{
Sebastian Hack's avatar
Sebastian Hack committed
558
	be_node_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
559
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
560
	ir_node *in[be_pos_AddSP_last];
Sebastian Hack's avatar
Sebastian Hack committed
561

Sebastian Hack's avatar
Sebastian Hack committed
562
563
	in[be_pos_AddSP_old_sp] = old_sp;
	in[be_pos_AddSP_size]   = sz;
Sebastian Hack's avatar
Sebastian Hack committed
564

565
566
	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
567

Sebastian Hack's avatar
Sebastian Hack committed
568
	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
569
570

	/* Set output constraint to stack register. */
571
572
	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
573
	be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_res), sp);
574
	a->reg_data[pn_be_AddSP_res].reg = sp;
Sebastian Hack's avatar
Sebastian Hack committed
575
576
577
578
579
580
581
582
583
584
585
586
587

	return irn;
}

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;
588
	irn      = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
589
590
	a        = init_node_attr(irn, 3);

591
	be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
592
593
594
595
596

	/* Set output constraint to stack register. */
	be_set_constr_single_reg(irn, OUT_POS(0), sp);
	be_node_set_reg_class(irn, 1, sp->reg_class);
	be_node_set_reg_class(irn, 2, sp->reg_class);
Sebastian Hack's avatar
Sebastian Hack committed
597
	be_node_set_irn_reg(NULL, irn, sp);
Sebastian Hack's avatar
Sebastian Hack committed
598
599

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
600
}
Sebastian Hack's avatar
Sebastian Hack committed
601

Sebastian Hack's avatar
Sebastian Hack committed
602
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, entity *ent)
Sebastian Hack's avatar
Sebastian Hack committed
603
{
604
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
605
606
607
	ir_node *irn;
	ir_node *in[1];

608
	in[0] = frame_pointer;
609
	irn = new_ir_node(NULL, irg, bl, op_be_StackParam, mode, 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
610
	a = init_node_attr(irn, 1);
611
	a->ent = ent;
Sebastian Hack's avatar
Sebastian Hack committed
612
613
614

	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
615
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
616
}
Sebastian Hack's avatar
Sebastian Hack committed
617

618
ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs)
Sebastian Hack's avatar
Sebastian Hack committed
619
620
621
622
{
	ir_node *irn;
	ir_node *in[1];

623
	irn = new_ir_node(NULL, irg, bl, op_be_RegParams, mode_T, 0, in);
Sebastian Hack's avatar
Sebastian Hack committed
624
	init_node_attr(irn, n_outs);
Sebastian Hack's avatar
Sebastian Hack committed
625
626
627
	return irn;
}

628
629
630
631
632
633
634
635
636
ir_node *be_new_FrameLoad(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
						  ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, entity *ent)
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[2];

	in[0]  = mem;
	in[1]  = frame;
637
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameLoad, mode_T, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
638
	a      = init_node_attr(irn, 3);
639
640
641
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 1, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
642
	be_node_set_reg_class(irn, OUT_POS(pn_Load_res), cls_data);
643
644
645
646
647
648
649
650
651
652
653
654
655
	return irn;
}

ir_node *be_new_FrameStore(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
						   ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_node *data, entity *ent)
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[3];

	in[0]  = mem;
	in[1]  = frame;
	in[2]  = data;
656
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameStore, mode_T, 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
657
	a      = init_node_attr(irn, 3);
658
659
660
661
662
663
664
665
	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;
}

ir_node *be_new_FrameAddr(const arch_register_class_t *cls_frame, ir_graph *irg, ir_node *bl, ir_node *frame, entity *ent)
Sebastian Hack's avatar
Sebastian Hack committed
666
{
667
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
668
669
670
	ir_node *irn;
	ir_node *in[1];

671
	in[0]  = frame;
672
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameAddr, get_irn_mode(frame), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
673
	a      = init_node_attr(irn, 1);
674
675
676
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 0, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
677
	be_node_set_reg_class(irn, OUT_POS(0), cls_frame);
Michael Beck's avatar
Michael Beck committed
678
679

	return optimize_node(irn);
Sebastian Hack's avatar
Sebastian Hack committed
680
681
}

Sebastian Hack's avatar
Sebastian Hack committed
682
683
684
685
686
687
688
689
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
690
	init_node_attr(irn, n + 1);
Sebastian Hack's avatar
Sebastian Hack committed
691
692
693
694
695
696
697
698
699
700
701
702
703
704
	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);
}

705
706
707
708
709
710
711
712
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);
}

713
ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
714
715
716
{
	ir_node *irn;

717
	irn = new_ir_node(NULL, irg, bl, op_be_Barrier, mode_T, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
718
719
720
721
	init_node_attr(irn, n);
	return irn;
}

Sebastian Hack's avatar
Sebastian Hack committed
722
723
724
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
725
int be_is_CopyKeep      (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_CopyKeep       ; }
Sebastian Hack's avatar
Sebastian Hack committed
726
int be_is_Perm          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Perm           ; }
Matthias Braun's avatar
Matthias Braun committed
727
int be_is_MemPerm       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_MemPerm        ; }
Sebastian Hack's avatar
Sebastian Hack committed
728
729
730
731
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
732
int be_is_SetSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SetSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
733
int be_is_AddSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_AddSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
734
735
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     ; }
736
737
738
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     ; }
739
int be_is_Barrier       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Barrier        ; }
740
741
742
743
744
745

int be_has_frame_entity(const ir_node *irn)
{
	switch(be_get_irn_opcode(irn)) {
	case beo_StackParam:
	case beo_Spill:
746
	case beo_Reload:
747
748
749
750
	case beo_FrameStore:
	case beo_FrameLoad:
	case beo_FrameAddr:
		return 1;
751
752
	default:
		return 0;
753
754
755
	}
}

756
entity* be_get_frame_entity(const ir_node *irn)
757
758
759
760
761
762
763
{
	if(be_has_frame_entity(irn)) {
		be_frame_attr_t *a = get_irn_attr(irn);
		return a->ent;
	}
	return NULL;
}
Sebastian Hack's avatar
Sebastian Hack committed
764

Matthias Braun's avatar
Matthias Braun committed
765
766
767
768
769
void be_set_MemPerm_in_entity(const ir_node *irn, int n, entity *ent)
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
770
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
771
772
773
774
775
776
777
778
779

	attr->in_entities[n] = ent;
}

entity* be_get_MemPerm_in_entity(const ir_node* irn, int n)
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
780
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
781
782
783
784
785
786
787
788
789

	return attr->in_entities[n];
}

void be_set_MemPerm_out_entity(const ir_node *irn, int n, entity *ent)
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
790
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
791
792
793
794
795
796
797
798
799

	attr->out_entities[n] = ent;
}

entity* be_get_MemPerm_out_entity(const ir_node* irn, int n)
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
800
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
801
802
803
804

	return attr->out_entities[n];
}

805
806
807
808
809
int be_get_MemPerm_entity_arity(const ir_node *irn)
{
	return get_irn_arity(irn) - 1;
}

Sebastian Hack's avatar
Sebastian Hack committed
810
static void be_limited(void *data, bitset_t *bs)
Sebastian Hack's avatar
Sebastian Hack committed
811
{
Sebastian Hack's avatar
Sebastian Hack committed
812
813
	be_req_t *req = data;

Sebastian Hack's avatar
Sebastian Hack committed
814
815
816
817
818
819
820
821
822
823
824
825
	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
826
827
}

Sebastian Hack's avatar
Sebastian Hack committed
828
static INLINE be_req_t *get_req(ir_node *irn, int pos)
Sebastian Hack's avatar
Sebastian Hack committed
829
{
Michael Beck's avatar
Michael Beck committed
830
	int idx           = pos < 0 ? -(pos + 1) : pos;
Sebastian Hack's avatar
Sebastian Hack committed
831
832
833
834
835
836
	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
837
	assert(!(pos < 0)  || -(pos + 1) <= a->max_reg_data);
Sebastian Hack's avatar
Sebastian Hack committed
838

Sebastian Hack's avatar
Sebastian Hack committed
839
840
841
842
843
844
845
	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
846
847
848
849
850
851
852
853
	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;
}

854
855
void be_set_constr_limited(ir_node *irn, int pos, const arch_register_req_t *req)
{
Sebastian Hack's avatar
Sebastian Hack committed
856
	be_req_t *r = get_req(irn, pos);
857
858
859
860
861
862
863
864
865
866
867
868
869

	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
870
871
872
873
874
875
876
877
878
879
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);
	r->req.cls = cls;
Sebastian Hack's avatar
Sebastian Hack committed
880
881
	if(r->req.type == arch_register_req_type_none)
		r->req.type = arch_register_req_type_normal;
Sebastian Hack's avatar
Sebastian Hack committed
882
883
}

884
885
886
887
888
889
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
890
891
892
893
894
ir_node *be_get_IncSP_pred(ir_node *irn) {
	assert(be_is_IncSP(irn));
	return get_irn_n(irn, 0);
}

895
void be_set_IncSP_pred(ir_node *incsp, ir_node *pred) {
896
897
898
899
	assert(be_is_IncSP(incsp));
	set_irn_n(incsp, 0, pred);
}

Michael Beck's avatar
Michael Beck committed
900
901
902
903
904
ir_node *be_get_IncSP_mem(ir_node *irn) {
	assert(be_is_IncSP(irn));
	return get_irn_n(irn, 1);
}

Sebastian Hack's avatar
Sebastian Hack committed
905
906
907
908
909
910
void be_set_IncSP_offset(ir_node *irn, unsigned offset)
{
	be_stack_attr_t *a = get_irn_attr(irn);
	assert(be_is_IncSP(irn));
	a->offset = offset;
}
911

912
unsigned be_get_IncSP_offset(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
913
{
Sebastian Hack's avatar
Sebastian Hack committed
914
915
916
917
	be_stack_attr_t *a = get_irn_attr(irn);
	assert(be_is_IncSP(irn));
	return a->offset;
}
Sebastian Hack's avatar
Sebastian Hack committed
918

Sebastian Hack's avatar
Sebastian Hack committed
919
920
921
922
923
void be_set_IncSP_direction(ir_node *irn, be_stack_dir_t dir)
{
	be_stack_attr_t *a = get_irn_attr(irn);
	assert(be_is_IncSP(irn));
	a->dir = dir;
Sebastian Hack's avatar
Sebastian Hack committed
924
925
}

926
be_stack_dir_t be_get_IncSP_direction(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
927
{
Sebastian Hack's avatar
Sebastian Hack committed
928
929
930
	be_stack_attr_t *a = get_irn_attr(irn);
	assert(be_is_IncSP(irn));
	return a->dir;
Sebastian Hack's avatar
Sebastian Hack committed
931
932
}

Matthias Braun's avatar
Matthias Braun committed
933
ir_node *be_spill(const arch_env_t *arch_env, ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
934
{
935
936
937
	ir_node *bl     = get_nodes_block(irn);
	ir_graph *irg   = get_irn_irg(bl);
	ir_node *frame  = get_irg_frame(irg);
Sebastian Hack's avatar
Sebastian Hack committed
938
	ir_node *spill;
Sebastian Hack's avatar
Sebastian Hack committed
939

Sebastian Hack's avatar
Sebastian Hack committed
940
941
942
	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);

Matthias Braun's avatar
Matthias Braun committed
943
	spill = be_new_Spill(cls, cls_frame, irg, bl, frame, irn);
Christian Würdig's avatar
Christian Würdig committed
944
	return spill;
Sebastian Hack's avatar
Sebastian Hack committed
945
946
}

947
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
948
949
950
{
	ir_node *reload;

951
	ir_node *bl    = is_Block(insert) ? insert : get_nodes_block(insert);
Sebastian Hack's avatar
Sebastian Hack committed
952
953
954
	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
955

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

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

960
961
962
963
964
965
966
967
	if(is_Block(insert)) {
		insert = sched_skip(insert, 0, sched_skip_cf_predicator, (void *) arch_env);
		sched_add_after(insert, reload);
	}

	else
		sched_add_before(insert, reload);

Christian Würdig's avatar
Christian Würdig committed
968
	return reload;
Sebastian Hack's avatar
Sebastian Hack committed
969
}
Sebastian Hack's avatar
Sebastian Hack committed
970

Sebastian Hack's avatar
Sebastian Hack committed
971
972
973
974
975
976
977
978
979
980
981
/*
  ____              ____
 |  _ \ ___  __ _  |  _ \ ___  __ _ ___
 | |_) / _ \/ _` | | |_) / _ \/ _` / __|
 |  _ <  __/ (_| | |  _ <  __/ (_| \__ \
 |_| \_\___|\__, | |_| \_\___|\__, |___/
            |___/                |_|

*/


Sebastian Hack's avatar
Sebastian Hack committed
982
static void *put_out_reg_req(arch_register_req_t *req, const ir_node *irn, int out_pos)
Sebastian Hack's avatar
Sebastian Hack committed
983
{
Sebastian Hack's avatar
Sebastian Hack committed
984
	const be_node_attr_t *a = get_irn_attr(irn);
Daniel Grund's avatar
Daniel Grund committed
985

Sebastian Hack's avatar
Sebastian Hack committed
986
	if(out_pos < a->max_reg_data) {
Sebastian Hack's avatar
Sebastian Hack committed
987
		memcpy(req, &a->reg_data[out_pos].req, sizeof(req[0]));
Sebastian Hack's avatar
Sebastian Hack committed
988
989
990

		if(be_is_Copy(irn)) {
			req->type |= arch_register_req_type_should_be_same;
991
			req->other_same = be_get_Copy_op(irn);
Sebastian Hack's avatar
Sebastian Hack committed
992
993
		}
	}
Sebastian Hack's avatar
Sebastian Hack committed
994
995
996
	else {
		req->type = arch_register_req_type_none;
		req->cls  = NULL;
Sebastian Hack's avatar
Sebastian Hack committed
997
	}
Sebastian Hack's avatar
Sebastian Hack committed
998

Sebastian Hack's avatar
Sebastian Hack committed
999
	return req;
Sebastian Hack's avatar
Sebastian Hack committed
1000
1001
}

Sebastian Hack's avatar
Sebastian Hack committed
1002
static void *put_in_reg_req(arch_register_req_t *req, const ir_node *irn, int pos)
1003
{
Sebastian Hack's avatar
Sebastian Hack committed
1004
1005
	const be_node_attr_t *a = get_irn_attr(irn);

Sebastian Hack's avatar
Sebastian Hack committed
1006
	if(pos < get_irn_arity(irn) && pos < a->max_reg_data)
Sebastian Hack's avatar
Sebastian Hack committed
1007
1008
1009
1010
		memcpy(req, &a->reg_data[pos].in_req, sizeof(req[0]));
	else {
		req->type = arch_register_req_type_none;
		req->cls  = NULL;
Sebastian Hack's avatar
Sebastian Hack committed
1011
1012
1013
	}

	return req;
1014
1015
}

Sebastian Hack's avatar
Sebastian Hack committed
1016
static const arch_register_req_t *
1017
be_node_get_irn_reg_req(const void *self, arch_register_req_t *req, const ir_node *irn, int pos)
Sebastian Hack's avatar
Sebastian Hack committed
1018
{
Sebastian Hack's avatar
Sebastian Hack committed
1019
	int out_pos = pos;
Sebastian Hack's avatar
Sebastian Hack committed
1020

Sebastian Hack's avatar
Sebastian Hack committed
1021
1022
1023
	if(pos < 0) {
		if(get_irn_mode(irn) == mode_T)
			return NULL;