benode.c 44.9 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);
Matthias Braun's avatar
Matthias Braun committed
218
219
	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
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
556
/* 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
557
{
558
	be_return_attr_t *a;
559
	ir_node *irn = new_ir_node(dbg, irg, bl, op_be_Return, mode_X, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
560
	init_node_attr(irn, n);
561
562
	a = get_irn_attr(irn);
	a->num_ret_vals = n_res;
Sebastian Hack's avatar
Sebastian Hack committed
563
564
565
566

	return irn;
}

567
568
569
570
571
572
573
/* 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
574
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
575
{
Sebastian Hack's avatar
Sebastian Hack committed
576
577
	be_stack_attr_t *a;
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
578
	ir_node *in[1];
Sebastian Hack's avatar
Sebastian Hack committed
579
580

	in[0]     = old_sp;
Sebastian Hack's avatar
Sebastian Hack committed
581
	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
582
	a         = init_node_attr(irn, 1);
Sebastian Hack's avatar
Sebastian Hack committed
583
584
	a->offset = offset;

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

Sebastian Hack's avatar
Sebastian Hack committed
587
	/* Set output constraint to stack register. */
Sebastian Hack's avatar
Sebastian Hack committed
588
	be_node_set_reg_class(irn, 0, sp->reg_class);
589
	be_set_constr_single_reg(irn, BE_OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
590
	be_node_set_irn_reg(NULL, irn, sp);
Sebastian Hack's avatar
Sebastian Hack committed
591
592

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
593
}
Sebastian Hack's avatar
Sebastian Hack committed
594

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

Sebastian Hack's avatar
Sebastian Hack committed
601
602
	in[be_pos_AddSP_old_sp] = old_sp;
	in[be_pos_AddSP_size]   = sz;
Sebastian Hack's avatar
Sebastian Hack committed
603

604
605
	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
606

Sebastian Hack's avatar
Sebastian Hack committed
607
	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
608
609

	/* Set output constraint to stack register. */
610
611
	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
612
	be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_res), sp);
613
	a->reg_data[pn_be_AddSP_res].reg = sp;
Sebastian Hack's avatar
Sebastian Hack committed
614
615
616
617

	return irn;
}

Michael Beck's avatar
Michael Beck committed
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
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
641
642
643
644
645
646
647
648
649
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;
650
	irn      = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
651
652
	a        = init_node_attr(irn, 3);

653
	be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
654
655
656

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

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
661
}
Sebastian Hack's avatar
Sebastian Hack committed
662

663
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
664
{
665
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
666
667
668
	ir_node *irn;
	ir_node *in[1];

669
	in[0] = frame_pointer;
670
	irn = new_ir_node(NULL, irg, bl, op_be_StackParam, mode, 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
671
	a = init_node_attr(irn, 1);
672
	a->ent = ent;
Sebastian Hack's avatar
Sebastian Hack committed
673
674
675

	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
676
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
677
}
Sebastian Hack's avatar
Sebastian Hack committed
678

679
ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs)
Sebastian Hack's avatar
Sebastian Hack committed
680
{
681
682
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
683

684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
	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
702
	ir_node *proj;
703
704

	assert(be_is_RegParams(regparams));
Michael Beck's avatar
Michael Beck committed
705
	proj = new_r_Proj(irg, block, regparams, mode, n);
706
707
708
709
	add_register_req(regparams);
	be_set_constr_single_reg(regparams, n, reg);
	arch_set_irn_register(arch_env, proj, reg);

Michael Beck's avatar
Michael Beck committed
710
	/* TODO decide, whether we need to set ignore/modify sp flags here? */
711
712

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
713
714
}

715
ir_node *be_new_FrameLoad(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
716
						  ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_entity *ent)
717
718
719
720
721
722
723
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[2];

	in[0]  = mem;
	in[1]  = frame;
724
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameLoad, mode_T, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
725
	a      = init_node_attr(irn, 3);
726
727
728
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 1, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
729
	be_node_set_reg_class(irn, OUT_POS(pn_Load_res), cls_data);
730
731
732
733
	return irn;
}

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

	in[0]  = mem;
	in[1]  = frame;
	in[2]  = data;
743
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameStore, mode_T, 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
744
	a      = init_node_attr(irn, 3);
745
746
747
748
749
750
751
	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;
}

752
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
753
{
754
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
755
756
757
	ir_node *irn;
	ir_node *in[1];

758
	in[0]  = frame;
759
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameAddr, get_irn_mode(frame), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
760
	a      = init_node_attr(irn, 1);
761
762
763
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 0, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
764
	be_node_set_reg_class(irn, OUT_POS(0), cls_frame);
Michael Beck's avatar
Michael Beck committed
765
766

	return optimize_node(irn);
Sebastian Hack's avatar
Sebastian Hack committed
767
768
}

Sebastian Hack's avatar
Sebastian Hack committed
769
770
771
772
773
774
775
776
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
777
	init_node_attr(irn, n + 1);
Sebastian Hack's avatar
Sebastian Hack committed
778
779
780
781
782
783
784
785
786
787
788
789
790
791
	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);
}

792
793
794
795
796
797
798
799
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);
}

800
ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
801
{
802
803
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
804

805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
	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);
	ir_node *proj = new_r_Proj(irg, block, barrier, mode, n);
	add_register_req(barrier);

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
825
826
}

Sebastian Hack's avatar
Sebastian Hack committed
827
828
829
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
830
int be_is_CopyKeep      (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_CopyKeep       ; }
Sebastian Hack's avatar
Sebastian Hack committed
831
int be_is_Perm          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Perm           ; }
Matthias Braun's avatar
Matthias Braun committed
832
int be_is_MemPerm       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_MemPerm        ; }
Sebastian Hack's avatar
Sebastian Hack committed
833
834
835
836
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
837
int be_is_SetSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SetSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
838
int be_is_AddSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_AddSP          ; }
839
int be_is_SubSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SubSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
840
841
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     ; }
842
843
844
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     ; }
845
int be_is_Barrier       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Barrier        ; }
846
847
848
849
850
851

int be_has_frame_entity(const ir_node *irn)
{
	switch(be_get_irn_opcode(irn)) {
	case beo_StackParam:
	case beo_Spill:
852
	case beo_Reload:
853
854
855
856
	case beo_FrameStore:
	case beo_FrameLoad:
	case beo_FrameAddr:
		return 1;
857
858
	default:
		return 0;
859
860
861
	}
}

862
ir_entity *be_get_frame_entity(const ir_node *irn)
863
{
864
	if (be_has_frame_entity(irn)) {
865
866
867
868
869
		be_frame_attr_t *a = get_irn_attr(irn);
		return a->ent;
	}
	return NULL;
}
Sebastian Hack's avatar
Sebastian Hack committed
870

871
872
873
874
875
876
877
878
879
880
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;
}

881
void be_set_MemPerm_in_entity(const ir_node *irn, int n, ir_entity *ent)
Matthias Braun's avatar
Matthias Braun committed
882
883
884
885
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
886
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
887
888
889
890

	attr->in_entities[n] = ent;
}

891
ir_entity* be_get_MemPerm_in_entity(const ir_node* irn, int n)
Matthias Braun's avatar
Matthias Braun committed
892
893
894
895
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
896
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
897
898
899
900

	return attr->in_entities[n];
}

901
void be_set_MemPerm_out_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->out_entities[n] = ent;
}

911
ir_entity* be_get_MemPerm_out_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->out_entities[n];
}

921
922
923
924
925
int be_get_MemPerm_entity_arity(const ir_node *irn)
{
	return get_irn_arity(irn) - 1;
}

Matthias Braun's avatar
Matthias Braun committed
926
void be_set_constr_single_reg(ir_node *node, int pos, const arch_register_t *reg)
Sebastian Hack's avatar
Sebastian Hack committed
927
{
Matthias Braun's avatar
Matthias Braun committed
928
929
930
931
932
	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
933

Matthias Braun's avatar
Matthias Braun committed
934
935
936
	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
937

Matthias Braun's avatar
Matthias Braun committed
938
939
	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
940

Matthias Braun's avatar
Matthias Braun committed
941
942
943
	req->cls = cls;
	req->type |= arch_register_req_type_limited;
	req->limited = limited_bitset;
Sebastian Hack's avatar
Sebastian Hack committed
944
945
}

Matthias Braun's avatar
Matthias Braun committed
946
void be_set_constr_limited(ir_node *node, int pos, const arch_register_req_t *req)
947
{
Matthias Braun's avatar
Matthias Braun committed
948
949
950
	ir_graph *irg = get_irn_irg(node);
	struct obstack *obst = get_irg_obstack(irg);
	arch_register_req_t *r = get_req(node, pos);
951
952

	assert(arch_register_req_is(req, limited));
Matthias Braun's avatar
Matthias Braun committed
953
954
955
	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);
956
957
}

Sebastian Hack's avatar
Sebastian Hack committed
958
959
void be_node_set_flags(ir_node *irn, int pos, arch_irn_flags_t flags)
{
Matthias Braun's avatar
Matthias Braun committed
960
961
	be_req_t *bereq = get_be_req(irn, pos);
	bereq->flags = flags;
Sebastian Hack's avatar
Sebastian Hack committed
962
963
964
965
}

void be_node_set_reg_class(ir_node *irn, int pos, const arch_register_class_t *cls)
{
Matthias Braun's avatar
Matthias Braun committed
966
	arch_register_req_t *req = get_req(irn, pos);
967

Matthias Braun's avatar
Matthias Braun committed
968
	req->cls = cls;
969

970
	if (cls == NULL) {
Matthias Braun's avatar
Matthias Braun committed
971
972
973
		req->type = arch_register_req_type_none;
	} else if (req->type == arch_register_req_type_none) {
		req->type = arch_register_req_type_normal;
974
	}