benode.c 45.6 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
 */
Michael Beck's avatar
Michael Beck committed
13
#ifdef HAVE_CONFIG_H
14
#include <config.h>
Michael Beck's avatar
Michael Beck committed
15
#endif
Sebastian Hack's avatar
Sebastian Hack committed
16
17
18
19
20
21

#include <stdlib.h>

#include "obst.h"
#include "set.h"
#include "pmap.h"
22
#include "util.h"
Sebastian Hack's avatar
Sebastian Hack committed
23
#include "debug.h"
24
#include "fourcc.h"
Sebastian Hack's avatar
Sebastian Hack committed
25
#include "offset.h"
Sebastian Hack's avatar
Sebastian Hack committed
26
#include "bitfiddle.h"
Matthias Braun's avatar
Matthias Braun committed
27
#include "raw_bitset.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
typedef struct {
	arch_register_req_t req;
Sebastian Hack's avatar
Sebastian Hack committed
53
	arch_irn_flags_t    flags;
Sebastian Hack's avatar
Sebastian Hack committed
54
55
} be_req_t;

56
typedef struct {
57
	const arch_register_t *reg;
Matthias Braun's avatar
Matthias Braun committed
58
59
	be_req_t req;
	be_req_t in_req;
60
61
} be_reg_data_t;

62
/** The generic be nodes attribute type. */
63
typedef struct {
64
	be_reg_data_t         *reg_data;
65
66
} be_node_attr_t;

67
68
69
70
71
72
/** 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;

73
/** The be_Stack attribute type. */
Sebastian Hack's avatar
Sebastian Hack committed
74
75
typedef struct {
	be_node_attr_t node_attr;
76
	int offset;           /**< The offset by which the stack shall be expanded/shrinked. */
Sebastian Hack's avatar
Sebastian Hack committed
77
78
} be_stack_attr_t;

79
/** The be_Frame attribute type. */
80
81
typedef struct {
	be_node_attr_t node_attr;
82
	ir_entity *ent;
83
84
85
	int offset;
} be_frame_attr_t;

86
/** The be_Call attribute type. */
87
88
typedef struct {
	be_node_attr_t node_attr;
89
	ir_entity *ent;      /**< The called entity if this is a static call. */
90
	ir_type *call_tp;    /**< The call type, copied from the original Call node. */
91
92
} be_call_attr_t;

93
typedef struct {
Matthias Braun's avatar
Matthias Braun committed
94
	be_node_attr_t node_attr;
95
96
	ir_entity **in_entities;
	ir_entity **out_entities;
Matthias Braun's avatar
Matthias Braun committed
97
} be_memperm_attr_t;
98

99
100
101
ir_op *op_be_Spill;
ir_op *op_be_Reload;
ir_op *op_be_Perm;
Matthias Braun's avatar
Matthias Braun committed
102
ir_op *op_be_MemPerm;
103
104
ir_op *op_be_Copy;
ir_op *op_be_Keep;
Sebastian Hack's avatar
Sebastian Hack committed
105
ir_op *op_be_CopyKeep;
106
107
108
ir_op *op_be_Call;
ir_op *op_be_Return;
ir_op *op_be_IncSP;
Sebastian Hack's avatar
Sebastian Hack committed
109
ir_op *op_be_AddSP;
Michael Beck's avatar
Michael Beck committed
110
ir_op *op_be_SubSP;
111
112
113
114
115
116
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;
117
ir_op *op_be_Barrier;
Sebastian Hack's avatar
Sebastian Hack committed
118

Sebastian Hack's avatar
Sebastian Hack committed
119
static int beo_base = -1;
Sebastian Hack's avatar
Sebastian Hack committed
120

Sebastian Hack's avatar
Sebastian Hack committed
121
static const ir_op_ops be_node_op_ops;
Sebastian Hack's avatar
Sebastian Hack committed
122

123
124
125
126
127
128
129
130
131
132
#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
133
134
#define M   irop_flag_machine

135

Michael Beck's avatar
Michael Beck committed
136
137
138
139
140
141
/**
 * 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) {
142
143
144
145
	int i, len;

	if(ARR_LEN(a->reg_data) != ARR_LEN(b->reg_data))
		return 1;
Michael Beck's avatar
Michael Beck committed
146

147
148
149
150
	len = ARR_LEN(a->reg_data);
	for (i = 0; i < len; ++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)) ||
Michael Beck's avatar
Michael Beck committed
151
			    memcmp(&a->reg_data[i].req,    &b->reg_data[i].req,    sizeof(a->reg_data[i].req)))
152
			return 1;
Michael Beck's avatar
Michael Beck committed
153
	}
154
155

	return 0;
Michael Beck's avatar
Michael Beck committed
156
157
158
159
160
161
162
163
164
165
166
}

/**
 * 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);

167
168
169
	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
170
171
}

Matthias Braun's avatar
Matthias Braun committed
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
static INLINE be_req_t *get_be_req(const ir_node *node, int pos)
{
	int idx;
	be_node_attr_t *attr;
	be_reg_data_t *rd;

	assert(is_be_node(node));
	attr = get_irn_attr(node);

	if(pos < 0) {
		idx = -(pos + 1);
	} else {
		idx = pos;
		assert(idx < get_irn_arity(node));
	}
	assert(idx < ARR_LEN(attr->reg_data));
	rd = &attr->reg_data[idx];

	return pos < 0 ? &rd->req : &rd->in_req;
}

static inline arch_register_req_t *get_req(const ir_node *node, int pos)
{
	be_req_t *bereq = get_be_req(node, pos);
	return &bereq->req;
}

Sebastian Hack's avatar
Sebastian Hack committed
199
200
void be_node_init(void) {
	static int inited = 0;
Sebastian Hack's avatar
Sebastian Hack committed
201

Sebastian Hack's avatar
Sebastian Hack committed
202
203
	if(inited)
		return;
Sebastian Hack's avatar
Sebastian Hack committed
204

Sebastian Hack's avatar
Sebastian Hack committed
205
	inited = 1;
Sebastian Hack's avatar
Sebastian Hack committed
206

207
208
	/* Acquire all needed opcodes. */
	beo_base = get_next_ir_opcodes(beo_Last - 1);
Sebastian Hack's avatar
Sebastian Hack committed
209

Matthias Braun's avatar
Matthias Braun committed
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);
215
	op_be_Keep       = new_ir_op(beo_base + beo_Keep,       "be_Keep",       op_pin_state_pinned,     K, oparity_dynamic,  0, sizeof(be_node_attr_t),    &be_node_op_ops);
Matthias Braun's avatar
Matthias Braun committed
216
	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);
217
	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);
218
	op_be_Return     = new_ir_op(beo_base + beo_Return,     "be_Return",     op_pin_state_pinned,     X, oparity_dynamic,  0, sizeof(be_return_attr_t),  &be_node_op_ops);
Matthias Braun's avatar
Matthias Braun committed
219
	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
220
	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
221
	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);
222
	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
223
224
225
226
227
	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);
228
	op_be_Barrier    = new_ir_op(beo_base + beo_Barrier,    "be_Barrier",    op_pin_state_pinned,     N, oparity_dynamic,  0, sizeof(be_node_attr_t),    &be_node_op_ops);
229
230
231
232

	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
233
	set_op_tag(op_be_MemPerm,    &be_node_tag);
234
235
	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
236
	set_op_tag(op_be_CopyKeep,   &be_node_tag);
237
238
	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
239
	set_op_tag(op_be_AddSP,      &be_node_tag);
Michael Beck's avatar
Michael Beck committed
240
	set_op_tag(op_be_SubSP,      &be_node_tag);
241
242
243
244
245
246
247
	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);
248
	set_op_tag(op_be_Barrier,    &be_node_tag);
Michael Beck's avatar
Michael Beck committed
249
250

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

253
254
255
/**
 * Initializes the generic attribute of all be nodes and return ir.
 */
256
static void *init_node_attr(ir_node *node, int max_reg_data)
Sebastian Hack's avatar
Sebastian Hack committed
257
{
258
	ir_graph *irg = get_irn_irg(node);
259
	struct obstack *obst = get_irg_obstack(irg);
260
	be_node_attr_t *a = get_irn_attr(node);
Sebastian Hack's avatar
Sebastian Hack committed
261

262
	memset(a, 0, sizeof(get_op_attr_size(get_irn_op(node))));
Sebastian Hack's avatar
Sebastian Hack committed
263

264
265
	if(max_reg_data >= 0) {
		a->reg_data = NEW_ARR_D(be_reg_data_t, obst, max_reg_data);
Sebastian Hack's avatar
Sebastian Hack committed
266
		memset(a->reg_data, 0, max_reg_data * sizeof(a->reg_data[0]));
267
268
	} else {
		a->reg_data = NEW_ARR_F(be_reg_data_t, 0);
Sebastian Hack's avatar
Sebastian Hack committed
269
270
271
272
	}

	return a;
}
273

274
275
276
277
278
279
280
281
static void add_register_req(ir_node *node)
{
	be_node_attr_t *a = get_irn_attr(node);
	be_reg_data_t regreq;
	memset(&regreq, 0, sizeof(regreq));
	ARR_APP1(be_reg_data_t, a->reg_data, regreq);
}

282
int is_be_node(const ir_node *irn)
283
{
Sebastian Hack's avatar
Sebastian Hack committed
284
	return get_op_tag(get_irn_op(irn)) == &be_node_tag;
285
286
}

Sebastian Hack's avatar
Sebastian Hack committed
287
be_opcode_t be_get_irn_opcode(const ir_node *irn)
288
{
Sebastian Hack's avatar
Sebastian Hack committed
289
	return is_be_node(irn) ? get_irn_opcode(irn) - beo_base : beo_NoBeOp;
290
291
}

Michael Beck's avatar
Michael Beck committed
292
293
294
295
296
297
298
299
300
301
/**
 * 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
302
303
304
305
{
	const ir_node *n = *node;

	if(is_Proj(n)) {
306
307
308
309
310
311
312
		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
313
314
315
316
317
318
		return get_Proj_proj(n);
	}

	return 0;
}

Matthias Braun's avatar
Matthias Braun committed
319
static be_reg_data_t *retrieve_reg_data(const ir_node *node)
Sebastian Hack's avatar
Sebastian Hack committed
320
{
Matthias Braun's avatar
Matthias Braun committed
321
322
	be_node_attr_t *attr;
	int pos = 0;
Sebastian Hack's avatar
Sebastian Hack committed
323

Matthias Braun's avatar
Matthias Braun committed
324
325
326
	if(is_Proj(node)) {
		pos = get_Proj_proj(node);
		node = get_Proj_pred(node);
Sebastian Hack's avatar
Sebastian Hack committed
327
328
	}

Matthias Braun's avatar
Matthias Braun committed
329
330
331
	assert(is_be_node(node));
	attr = get_irn_attr(node);
	assert(pos >= 0 && pos < ARR_LEN(attr->reg_data) && "illegal proj number");
Sebastian Hack's avatar
Sebastian Hack committed
332

Matthias Braun's avatar
Matthias Braun committed
333
	return &attr->reg_data[pos];
Sebastian Hack's avatar
Sebastian Hack committed
334
335
}

Sebastian Hack's avatar
Sebastian Hack committed
336
337
338
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
339
	be_reg_data_t *r = retrieve_reg_data(irn);
Matthias Braun's avatar
Matthias Braun committed
340
	r->reg = reg;
Sebastian Hack's avatar
Sebastian Hack committed
341
342
}

343
344
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)
345
{
Matthias Braun's avatar
Matthias Braun committed
346
	be_frame_attr_t *a;
347
	ir_node         *in[2];
348
	ir_node         *res;
349

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

357
	be_node_set_reg_class(res, be_pos_Spill_frame, cls_frame);
358
	be_node_set_reg_class(res, be_pos_Spill_val, cls);
Sebastian Hack's avatar
Sebastian Hack committed
359
360
	return res;
}
361

362
363
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)
364
{
365
366
367
368
369
370
371
	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
372
373
	init_node_attr(res, 2);
	be_node_set_reg_class(res, -1, cls);
374
	be_node_set_reg_class(res, be_pos_Reload_frame, cls_frame);
375
	be_node_set_flags(res, -1, arch_irn_flags_rematerializable);
Sebastian Hack's avatar
Sebastian Hack committed
376
377
	return res;
}
378

379
ir_node *be_get_Reload_mem(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
380
381
{
	assert(be_is_Reload(irn));
Daniel Grund's avatar
Daniel Grund committed
382
	return get_irn_n(irn, be_pos_Reload_mem);
Sebastian Hack's avatar
Sebastian Hack committed
383
384
}

385
386
387
388
389
390
ir_node *be_get_Reload_frame(const ir_node *irn)
{
	assert(be_is_Reload(irn));
	return get_irn_n(irn, be_pos_Reload_frame);
}

391
392
393
394
395
ir_node *be_get_Spill_val(const ir_node *irn)
{
	assert(be_is_Spill(irn));
	return get_irn_n(irn, be_pos_Spill_val);
}
Matthias Braun's avatar
Matthias Braun committed
396

397
398
399
400
401
ir_node *be_get_Spill_frame(const ir_node *irn)
{
	assert(be_is_Spill(irn));
	return get_irn_n(irn, be_pos_Spill_frame);
}
402

Sebastian Hack's avatar
Sebastian Hack committed
403
404
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
405
	int i;
406
	ir_node *irn = new_ir_node(NULL, irg, bl, op_be_Perm, mode_T, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
407
408
409
410
411
412
	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
413
414
	return irn;
}
415

Matthias Braun's avatar
Matthias Braun committed
416
417
418
419
420
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);
421
422
	ir_node *irn;
	const arch_register_t *sp = arch_env->isa->sp;
Matthias Braun's avatar
Matthias Braun committed
423
	be_memperm_attr_t *attr;
424
	ir_node **real_in;
Matthias Braun's avatar
Matthias Braun committed
425

426
427
428
429
430
431
432
433
	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
434
	for(i = 0; i < n; ++i) {
435
		be_node_set_reg_class(irn, i + 1, cls_frame);
Matthias Braun's avatar
Matthias Braun committed
436
437
438
439
440
		be_node_set_reg_class(irn, OUT_POS(i), cls_frame);
	}

	attr = get_irn_attr(irn);

441
442
	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
443
444
445
446
447
448
449
	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
450
451
452
453
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;
Matthias Braun's avatar
Matthias Braun committed
454
	arch_register_req_t *req;
455

Sebastian Hack's avatar
Sebastian Hack committed
456
	in[0] = op;
457
	res   = new_ir_node(NULL, irg, bl, op_be_Copy, get_irn_mode(op), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
458
459
460
	init_node_attr(res, 1);
	be_node_set_reg_class(res, 0, cls);
	be_node_set_reg_class(res, OUT_POS(0), cls);
Matthias Braun's avatar
Matthias Braun committed
461
462
463
464
465
466

	req = get_req(res, OUT_POS(0));
	req->cls = cls;
	req->type = arch_register_req_type_should_be_same;
	req->other_same = 0;

Sebastian Hack's avatar
Sebastian Hack committed
467
	return res;
468
469
}

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

474
475
476
477
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
478
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
479
{
Sebastian Hack's avatar
Sebastian Hack committed
480
	int i;
481
482
483
484
	ir_node *res;

	res = new_ir_node(NULL, irg, bl, op_be_Keep, mode_ANY, -1, NULL);
	init_node_attr(res, -1);
Sebastian Hack's avatar
Sebastian Hack committed
485

Sebastian Hack's avatar
Sebastian Hack committed
486
	for(i = 0; i < n; ++i) {
487
488
489
		add_irn_n(res, in[i]);
		add_register_req(res);
		be_node_set_reg_class(res, i, cls);
Sebastian Hack's avatar
Sebastian Hack committed
490
	}
491
492
493
494
495
496
497
498
499
500
501
502
503
	keep_alive(res);

	return res;
}

void be_Keep_add_node(ir_node *keep, const arch_register_class_t *cls, ir_node *node)
{
	int n;

	assert(be_is_Keep(keep));
	n = add_irn_n(keep, node);
	add_register_req(keep);
	be_node_set_reg_class(keep, n, cls);
Sebastian Hack's avatar
Sebastian Hack committed
504
505
}

506
507
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
508
{
509
510
	be_call_attr_t *a;
	int real_n = be_pos_Call_first_arg + n;
Sebastian Hack's avatar
Sebastian Hack committed
511
512
	ir_node *irn;
	ir_node **real_in;
Sebastian Hack's avatar
Sebastian Hack committed
513

514
515
516
517
518
	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
519

520
	irn = new_ir_node(dbg, irg, bl, op_be_Call, mode_T, real_n, real_in);
521
522
523
	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
524
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
525
526
}

527
/* Gets the call entity or NULL if this is no static call. */
528
ir_entity *be_Call_get_entity(const ir_node *call) {
529
530
531
532
533
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	return a->ent;
}

534
/* Sets the call entity. */
535
void be_Call_set_entity(ir_node *call, ir_entity *ent) {
536
537
538
539
540
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	a->ent = ent;
}

541
542
543
544
545
546
547
548
549
550
551
552
553
554
/* 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;
}

555
/* Construct a new be_Return. */
556
557
ir_node *be_new_Return(dbg_info *dbg, ir_graph *irg, ir_node *block, int n_res,
                       int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
558
{
559
	be_return_attr_t *a;
560
561
562
563
564
565
566
567
568
569
570
	ir_node *res;
	int i;

	res = new_ir_node(dbg, irg, block, op_be_Return, mode_X, -1, NULL);
	init_node_attr(res, -1);
	for(i = 0; i < n; ++i) {
		add_irn_n(res, in[i]);
		add_register_req(res);
	}

	a = get_irn_attr(res);
571
	a->num_ret_vals = n_res;
Sebastian Hack's avatar
Sebastian Hack committed
572

573
	return res;
Sebastian Hack's avatar
Sebastian Hack committed
574
575
}

576
577
578
579
580
581
582
/* 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;
}

583
584
585
586
587
588
589
590
591
592
int be_Return_append_node(ir_node *ret, ir_node *node)
{
	int pos;

	pos = add_irn_n(ret, node);
	add_register_req(ret);

	return pos;
}

Sebastian Hack's avatar
Sebastian Hack committed
593
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
594
{
Sebastian Hack's avatar
Sebastian Hack committed
595
596
	be_stack_attr_t *a;
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
597
	ir_node *in[1];
Sebastian Hack's avatar
Sebastian Hack committed
598
599

	in[0]     = old_sp;
Sebastian Hack's avatar
Sebastian Hack committed
600
	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
601
	a         = init_node_attr(irn, 1);
Sebastian Hack's avatar
Sebastian Hack committed
602
603
	a->offset = offset;

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

Sebastian Hack's avatar
Sebastian Hack committed
606
	/* Set output constraint to stack register. */
Sebastian Hack's avatar
Sebastian Hack committed
607
	be_node_set_reg_class(irn, 0, sp->reg_class);
608
	be_set_constr_single_reg(irn, BE_OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
609
	be_node_set_irn_reg(NULL, irn, sp);
Sebastian Hack's avatar
Sebastian Hack committed
610
611

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
612
}
Sebastian Hack's avatar
Sebastian Hack committed
613

Sebastian Hack's avatar
Sebastian Hack committed
614
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
615
{
Sebastian Hack's avatar
Sebastian Hack committed
616
	be_node_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
617
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
618
	ir_node *in[be_pos_AddSP_last];
Sebastian Hack's avatar
Sebastian Hack committed
619

Sebastian Hack's avatar
Sebastian Hack committed
620
621
	in[be_pos_AddSP_old_sp] = old_sp;
	in[be_pos_AddSP_size]   = sz;
Sebastian Hack's avatar
Sebastian Hack committed
622

623
624
	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
625

Sebastian Hack's avatar
Sebastian Hack committed
626
	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
627
628

	/* Set output constraint to stack register. */
629
630
	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
631
	be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_res), sp);
632
	a->reg_data[pn_be_AddSP_res].reg = sp;
Sebastian Hack's avatar
Sebastian Hack committed
633
634
635
636

	return irn;
}

Michael Beck's avatar
Michael Beck committed
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
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
660
661
662
663
664
665
666
667
668
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;
669
	irn      = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
670
671
	a        = init_node_attr(irn, 3);

672
	be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
673
674
675

	/* Set output constraint to stack register. */
	be_set_constr_single_reg(irn, OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
676
677
	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
678
679

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

682
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
683
{
684
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
685
686
687
	ir_node *irn;
	ir_node *in[1];

688
	in[0] = frame_pointer;
689
	irn = new_ir_node(NULL, irg, bl, op_be_StackParam, mode, 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
690
	a = init_node_attr(irn, 1);
691
	a->ent = ent;
Sebastian Hack's avatar
Sebastian Hack committed
692
693
694

	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
695
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
696
}
Sebastian Hack's avatar
Sebastian Hack committed
697

698
ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs)
Sebastian Hack's avatar
Sebastian Hack committed
699
{
700
701
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
702

703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
	res = new_ir_node(NULL, irg, bl, op_be_RegParams, mode_T, 0, NULL);
	init_node_attr(res, -1);
	for(i = 0; i < n_outs; ++i)
		add_register_req(res);

	return res;
}

ir_node *be_RegParams_append_out_reg(ir_node *regparams,
                                     const arch_env_t *arch_env,
                                     const arch_register_t *reg)
{
	ir_graph *irg = get_irn_irg(regparams);
	ir_node *block = get_nodes_block(regparams);
	be_node_attr_t *attr = get_irn_attr(regparams);
	const arch_register_class_t *cls = arch_register_get_class(reg);
	ir_mode *mode = arch_register_class_mode(cls);
	int n = ARR_LEN(attr->reg_data);
Michael Beck's avatar
Michael Beck committed
721
	ir_node *proj;
722
723

	assert(be_is_RegParams(regparams));
Michael Beck's avatar
Michael Beck committed
724
	proj = new_r_Proj(irg, block, regparams, mode, n);
725
	add_register_req(regparams);
726
	be_set_constr_single_reg(regparams, BE_OUT_POS(n), reg);
727
728
	arch_set_irn_register(arch_env, proj, reg);

Michael Beck's avatar
Michael Beck committed
729
	/* TODO decide, whether we need to set ignore/modify sp flags here? */
730
731

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
732
733
}

734
ir_node *be_new_FrameLoad(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
735
						  ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_entity *ent)
736
737
738
739
740
741
742
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[2];

	in[0]  = mem;
	in[1]  = frame;
743
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameLoad, mode_T, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
744
	a      = init_node_attr(irn, 3);
745
746
747
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 1, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
748
	be_node_set_reg_class(irn, OUT_POS(pn_Load_res), cls_data);
749
750
751
752
	return irn;
}

ir_node *be_new_FrameStore(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
753
						   ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_node *data, ir_entity *ent)
754
755
756
757
758
759
760
761
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[3];

	in[0]  = mem;
	in[1]  = frame;
	in[2]  = data;
762
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameStore, mode_T, 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
763
	a      = init_node_attr(irn, 3);
764
765
766
767
768
769
770
	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;
}

771
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
772
{
773
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
774
775
776
	ir_node *irn;
	ir_node *in[1];

777
	in[0]  = frame;
778
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameAddr, get_irn_mode(frame), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
779
	a      = init_node_attr(irn, 1);
780
781
782
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 0, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
783
	be_node_set_reg_class(irn, OUT_POS(0), cls_frame);
Michael Beck's avatar
Michael Beck committed
784
785

	return optimize_node(irn);
Sebastian Hack's avatar
Sebastian Hack committed
786
787
}

Sebastian Hack's avatar
Sebastian Hack committed
788
789
790
791
792
793
794
795
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
796
	init_node_attr(irn, n + 1);
Sebastian Hack's avatar
Sebastian Hack committed
797
798
799
800
801
802
803
804
805
806
807
808
809
810
	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);
}

811
812
813
814
815
816
817
818
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);
}

819
ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
820
{
821
822
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
823

824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
	res = new_ir_node(NULL, irg, bl, op_be_Barrier, mode_T, -1, NULL);
	init_node_attr(res, -1);
	for(i = 0; i < n; ++i) {
		add_irn_n(res, in[i]);
		add_register_req(res);
	}

	return res;
}

ir_node *be_Barrier_append_node(ir_node *barrier, ir_node *node)
{
	ir_graph *irg = get_irn_irg(barrier);
	ir_node *block = get_nodes_block(barrier);
	ir_mode *mode = get_irn_mode(node);
	int n = add_irn_n(barrier, node);
840

841
842
843
844
	ir_node *proj = new_r_Proj(irg, block, barrier, mode, n);
	add_register_req(barrier);

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
845
846
}

Sebastian Hack's avatar
Sebastian Hack committed
847
848
849
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
850
int be_is_CopyKeep      (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_CopyKeep       ; }
Sebastian Hack's avatar
Sebastian Hack committed
851
int be_is_Perm          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Perm           ; }
Matthias Braun's avatar
Matthias Braun committed
852
int be_is_MemPerm       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_MemPerm        ; }
Sebastian Hack's avatar
Sebastian Hack committed
853
854
855
856
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
857
int be_is_SetSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SetSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
858
int be_is_AddSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_AddSP          ; }
859
int be_is_SubSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SubSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
860
861
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     ; }
862
863
864
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     ; }
865
int be_is_Barrier       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Barrier        ; }
866
867
868
869
870
871

int be_has_frame_entity(const ir_node *irn)
{
	switch(be_get_irn_opcode(irn)) {
	case beo_StackParam:
	case beo_Spill:
872
	case beo_Reload:
873
874
875
876
	case beo_FrameStore:
	case beo_FrameLoad:
	case beo_FrameAddr:
		return 1;
877
878
	default:
		return 0;
879
880
881
	}
}

882
ir_entity *be_get_frame_entity(const ir_node *irn)
883
{
884
	if (be_has_frame_entity(irn)) {
885
886
887
888
889
		be_frame_attr_t *a = get_irn_attr(irn);
		return a->ent;
	}
	return NULL;
}
Sebastian Hack's avatar
Sebastian Hack committed
890

891
892
893
894
895
896
897
898
899
900
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;
}

901
void be_set_MemPerm_in_entity(const ir_node *irn, int n, ir_entity *ent)
Matthias Braun's avatar
Matthias Braun committed
902
903
904
905
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
906
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
907
908
909
910

	attr->in_entities[n] = ent;
}

911
ir_entity* be_get_MemPerm_in_entity(const ir_node* irn, int n)
Matthias Braun's avatar
Matthias Braun committed
912
913
914
915
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
916
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
917
918
919
920

	return attr->in_entities[n];
}

921
void be_set_MemPerm_out_entity(const ir_node *irn, int n, ir_entity *ent)
Matthias Braun's avatar
Matthias Braun committed
922
923
924
925
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
926
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
927
928
929
930

	attr->out_entities[n] = ent;
}

931
ir_entity* be_get_MemPerm_out_entity(const ir_node* irn, int n)
Matthias Braun's avatar
Matthias Braun committed
932
933
934
935
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
936
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
937
938
939
940

	return attr->out_entities[n];
}

941
942
943
944
945
int be_get_MemPerm_entity_arity(const ir_node *irn)
{
	return get_irn_arity(irn) - 1;
}

Matthias Braun's avatar
Matthias Braun committed
946
void be_set_constr_single_reg(ir_node *node, int pos, const arch_register_t *reg)
Sebastian Hack's avatar
Sebastian Hack committed
947
{
Matthias Braun's avatar
Matthias Braun committed
948
949
950
951
952
	arch_register_req_t *req = get_req(node, pos);
	const arch_register_class_t *cls = arch_register_get_class(reg);
	ir_graph *irg = get_irn_irg(node);
	struct obstack *obst = get_irg_obstack(irg);
	unsigned *limited_bitset;
Sebastian Hack's avatar
Sebastian Hack committed
953

Matthias Braun's avatar
Matthias Braun committed
954
955
956
	assert(req->cls == NULL || req->cls == cls);
	assert(! (req->type & arch_register_req_type_limited));
	assert(req->limited == NULL);
Sebastian Hack's avatar
Sebastian Hack committed
957

Matthias Braun's avatar
Matthias Braun committed
958
959
	limited_bitset = rbitset_obstack_alloc(obst, arch_register_class_n_regs(cls));
	rbitset_set(limited_bitset, arch_register_get_index(reg));
Sebastian Hack's avatar
Sebastian Hack committed
960

Matthias Braun's avatar
Matthias Braun committed
961
962
963
	req->cls = cls;
	req->type |= arch_register_req_type_limited;
	req->limited = limited_bitset;
Sebastian Hack's avatar
Sebastian Hack committed
964
965
}

Matthias Braun's avatar
Matthias Braun committed
966
void be_set_constr_limited(ir_node *node, int pos, const arch_register_req_t *req)
967
{
Matthias Braun's avatar
Matthias Braun committed
968
969
970
	ir_graph *irg = get_irn_irg(node);
	struct obstack *obst = get_irg_obstack(irg);
	arch_register_req_t *r = get_req(node, pos);
971
972

	assert(arch_register_req_is(req, limited));
Matthias Braun's avatar
Matthias Braun committed
973
974
975
	assert(! (req->type & (arch_register_req_type_should_be_same | arch_register_req_type_should_be_different)));
	memcpy(r, req, sizeof(r[0]));
	r->limited = rbitset_duplicate_obstack_alloc(obst, req->limited, req->cls->n_regs);
976
977
}

Sebastian Hack's avatar
Sebastian Hack committed
978
979
void be_node_set_flags(ir_node *irn, int pos, arch_irn_flags_t flags)
{
Matthias Braun's avatar
Matthias Braun committed
980
981
	be_req_t *bereq = get_be_req(irn