benode.c 47.8 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
 *
 * This file is part of libFirm.
 *
 * This file may be distributed and/or modified under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation and appearing in the file LICENSE.GPL included in the
 * packaging of this file.
 *
 * Licensees holding valid libFirm Professional Edition licenses may use
 * this file in accordance with the libFirm Commercial License.
 * Agreement provided with the Software.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE.
 */

Sebastian Hack's avatar
Sebastian Hack committed
20
/**
Christian Würdig's avatar
Christian Würdig committed
21
22
23
24
25
 * @file
 * @brief       Backend node support for generic backend nodes.
 * @author      Sebastian Hack
 * @date        17.05.2005
 * @version     $Id$
Sebastian Hack's avatar
Sebastian Hack committed
26
 *
27
 * Backend node support for generic backend nodes.
Michael Beck's avatar
Michael Beck committed
28
 * This file provides Perm, Copy, Spill and Reload nodes.
Sebastian Hack's avatar
Sebastian Hack committed
29
 */
Michael Beck's avatar
Michael Beck committed
30
#ifdef HAVE_CONFIG_H
31
#include "config.h"
Michael Beck's avatar
Michael Beck committed
32
#endif
Sebastian Hack's avatar
Sebastian Hack committed
33
34
35
36
37
38

#include <stdlib.h>

#include "obst.h"
#include "set.h"
#include "pmap.h"
39
#include "util.h"
Sebastian Hack's avatar
Sebastian Hack committed
40
#include "debug.h"
41
#include "fourcc.h"
Sebastian Hack's avatar
Sebastian Hack committed
42
#include "offset.h"
Sebastian Hack's avatar
Sebastian Hack committed
43
#include "bitfiddle.h"
Matthias Braun's avatar
Matthias Braun committed
44
#include "raw_bitset.h"
Sebastian Hack's avatar
Sebastian Hack committed
45
46
47
48

#include "irop_t.h"
#include "irmode_t.h"
#include "irnode_t.h"
49
#include "ircons_t.h"
50
#include "irprintf.h"
Sebastian Hack's avatar
Sebastian Hack committed
51
#include "irgwalk.h"
Michael Beck's avatar
Michael Beck committed
52
#include "iropt_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
53

54
55
56
#include "be_t.h"
#include "belive_t.h"
#include "besched_t.h"
Sebastian Hack's avatar
Sebastian Hack committed
57
58
#include "benode_t.h"

59
60
#include "beirgmod.h"

Sebastian Hack's avatar
Sebastian Hack committed
61
62
#define OUT_POS(x) (-((x) + 1))

Sebastian Hack's avatar
Sebastian Hack committed
63
64
/* 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
65

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

Sebastian Hack's avatar
Sebastian Hack committed
68
69
typedef struct {
	arch_register_req_t req;
Sebastian Hack's avatar
Sebastian Hack committed
70
	arch_irn_flags_t    flags;
Sebastian Hack's avatar
Sebastian Hack committed
71
72
} be_req_t;

73
typedef struct {
74
	const arch_register_t *reg;
Matthias Braun's avatar
Matthias Braun committed
75
76
	be_req_t req;
	be_req_t in_req;
77
78
} be_reg_data_t;

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

84
85
86
87
88
89
/** 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;

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

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

103
/** The be_Call attribute type. */
104
105
typedef struct {
	be_node_attr_t node_attr;
106
	ir_entity *ent;      /**< The called entity if this is a static call. */
107
	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
	be_node_attr_t node_attr;
112
113
	ir_entity **in_entities;
	ir_entity **out_entities;
Matthias Braun's avatar
Matthias Braun committed
114
} 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;
Michael Beck's avatar
Michael Beck committed
127
ir_op *op_be_SubSP;
128
129
130
ir_op *op_be_SetSP;
ir_op *op_be_RegParams;
ir_op *op_be_FrameAddr;
131
ir_op *op_be_Barrier;
Sebastian Hack's avatar
Sebastian Hack committed
132

Sebastian Hack's avatar
Sebastian Hack committed
133
static int beo_base = -1;
Sebastian Hack's avatar
Sebastian Hack committed
134

Sebastian Hack's avatar
Sebastian Hack committed
135
static const ir_op_ops be_node_op_ops;
Sebastian Hack's avatar
Sebastian Hack committed
136

137
138
139
140
141
142
143
144
145
146
#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
147
148
#define M   irop_flag_machine

149

Michael Beck's avatar
Michael Beck committed
150
151
152
153
154
/**
 * Compare two node attributes.
 *
 * @return zero if both attributes are identically
 */
155
static int _node_cmp_attr(be_node_attr_t *a, be_node_attr_t *b) {
156
157
158
159
	int i, len;

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

161
162
163
164
	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
165
			    memcmp(&a->reg_data[i].req,    &b->reg_data[i].req,    sizeof(a->reg_data[i].req)))
166
			return 1;
Michael Beck's avatar
Michael Beck committed
167
	}
168
169

	return 0;
Michael Beck's avatar
Michael Beck committed
170
171
}

172
173
174
175
176
177
178
static int node_cmp_attr(ir_node *a, ir_node *b) {
	be_node_attr_t *a_attr = get_irn_attr(a);
	be_node_attr_t *b_attr = get_irn_attr(b);

	return _node_cmp_attr(a_attr, b_attr);
}

Michael Beck's avatar
Michael Beck committed
179
180
181
182
183
184
185
186
187
/**
 * 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);

188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
	if (a_attr->ent != b_attr->ent || a_attr->offset != b_attr->offset)
		return 1;

	return _node_cmp_attr((be_node_attr_t*) a_attr, (be_node_attr_t*) b_attr);
}

static int Return_cmp_attr(ir_node *a, ir_node *b) {
	be_return_attr_t *a_attr = get_irn_attr(a);
	be_return_attr_t *b_attr = get_irn_attr(b);

	if (a_attr->num_ret_vals != b_attr->num_ret_vals)
		return 1;

	return _node_cmp_attr((be_node_attr_t*) a_attr, (be_node_attr_t*) b_attr);
}

static int Stack_cmp_attr(ir_node *a, ir_node *b) {
	be_stack_attr_t *a_attr = get_irn_attr(a);
	be_stack_attr_t *b_attr = get_irn_attr(b);

	if (a_attr->offset != b_attr->offset)
		return 1;

	return _node_cmp_attr((be_node_attr_t*) a_attr, (be_node_attr_t*) b_attr);
}

static int Call_cmp_attr(ir_node *a, ir_node *b) {
	be_call_attr_t *a_attr = get_irn_attr(a);
	be_call_attr_t *b_attr = get_irn_attr(b);

	if (a_attr->ent != b_attr->ent ||
			a_attr->call_tp != b_attr->call_tp)
		return 1;

	return _node_cmp_attr((be_node_attr_t*) a_attr, (be_node_attr_t*) b_attr);
Michael Beck's avatar
Michael Beck committed
223
224
}

Matthias Braun's avatar
Matthias Braun committed
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
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;
}

246
static INLINE arch_register_req_t *get_req(const ir_node *node, int pos)
Matthias Braun's avatar
Matthias Braun committed
247
248
249
250
251
{
	be_req_t *bereq = get_be_req(node, pos);
	return &bereq->req;
}

Sebastian Hack's avatar
Sebastian Hack committed
252
253
void be_node_init(void) {
	static int inited = 0;
Sebastian Hack's avatar
Sebastian Hack committed
254

Sebastian Hack's avatar
Sebastian Hack committed
255
256
	if(inited)
		return;
Sebastian Hack's avatar
Sebastian Hack committed
257

Sebastian Hack's avatar
Sebastian Hack committed
258
	inited = 1;
Sebastian Hack's avatar
Sebastian Hack committed
259

260
	/* Acquire all needed opcodes. */
261
	beo_base = get_next_ir_opcodes(beo_Last);
Sebastian Hack's avatar
Sebastian Hack committed
262

263
264
	op_be_Spill      = new_ir_op(beo_base + beo_Spill,      "be_Spill",      op_pin_state_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_pinned,     N, oparity_zero,     0, sizeof(be_frame_attr_t),   &be_node_op_ops);
Matthias Braun's avatar
Matthias Braun committed
265
	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);
266
	op_be_MemPerm    = new_ir_op(beo_base + beo_MemPerm,    "be_MemPerm",    op_pin_state_pinned,     N, oparity_variable, 0, sizeof(be_memperm_attr_t), &be_node_op_ops);
Matthias Braun's avatar
Matthias Braun committed
267
	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);
268
	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
269
	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);
270
	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);
271
	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
272
	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
273
	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);
274
	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);
275
	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);
Matthias Braun's avatar
Matthias Braun committed
276
	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);
277
	op_be_FrameAddr  = new_ir_op(beo_base + beo_FrameAddr,  "be_FrameAddr",  op_pin_state_floats,     N, oparity_unary,    0, sizeof(be_frame_attr_t),   &be_node_op_ops);
278
	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);
279
280

	set_op_tag(op_be_Spill,      &be_node_tag);
281
	op_be_Spill->ops.node_cmp_attr = FrameAddr_cmp_attr;
282
	set_op_tag(op_be_Reload,     &be_node_tag);
283
	op_be_Reload->ops.node_cmp_attr = FrameAddr_cmp_attr;
284
	set_op_tag(op_be_Perm,       &be_node_tag);
285
	op_be_Perm->ops.node_cmp_attr = node_cmp_attr;
Matthias Braun's avatar
Matthias Braun committed
286
	set_op_tag(op_be_MemPerm,    &be_node_tag);
287
	op_be_MemPerm->ops.node_cmp_attr = node_cmp_attr;
288
	set_op_tag(op_be_Copy,       &be_node_tag);
289
	op_be_Copy->ops.node_cmp_attr = node_cmp_attr;
290
	set_op_tag(op_be_Keep,       &be_node_tag);
291
	op_be_Keep->ops.node_cmp_attr = node_cmp_attr;
Sebastian Hack's avatar
Sebastian Hack committed
292
	set_op_tag(op_be_CopyKeep,   &be_node_tag);
293
	op_be_CopyKeep->ops.node_cmp_attr = node_cmp_attr;
294
	set_op_tag(op_be_Call,       &be_node_tag);
295
	op_be_Call->ops.node_cmp_attr = Call_cmp_attr;
296
	set_op_tag(op_be_Return,     &be_node_tag);
297
	op_be_Return->ops.node_cmp_attr = Return_cmp_attr;
Sebastian Hack's avatar
Sebastian Hack committed
298
	set_op_tag(op_be_AddSP,      &be_node_tag);
299
	op_be_AddSP->ops.node_cmp_attr = node_cmp_attr;
Michael Beck's avatar
Michael Beck committed
300
	set_op_tag(op_be_SubSP,      &be_node_tag);
301
	op_be_SubSP->ops.node_cmp_attr = node_cmp_attr;
302
	set_op_tag(op_be_SetSP,      &be_node_tag);
303
	op_be_SetSP->ops.node_cmp_attr = Stack_cmp_attr;
304
	set_op_tag(op_be_IncSP,      &be_node_tag);
305
	op_be_IncSP->ops.node_cmp_attr = Stack_cmp_attr;
306
	set_op_tag(op_be_RegParams,  &be_node_tag);
307
	op_be_RegParams->ops.node_cmp_attr = node_cmp_attr;
308
	set_op_tag(op_be_FrameAddr,  &be_node_tag);
Michael Beck's avatar
Michael Beck committed
309
	op_be_FrameAddr->ops.node_cmp_attr = FrameAddr_cmp_attr;
310
311
	set_op_tag(op_be_Barrier,    &be_node_tag);
	op_be_Barrier->ops.node_cmp_attr = node_cmp_attr;
Sebastian Hack's avatar
Sebastian Hack committed
312
}
313

314
315
316
/**
 * Initializes the generic attribute of all be nodes and return ir.
 */
317
static void *init_node_attr(ir_node *node, int max_reg_data)
Sebastian Hack's avatar
Sebastian Hack committed
318
{
319
	ir_graph *irg = get_irn_irg(node);
320
	struct obstack *obst = get_irg_obstack(irg);
321
	be_node_attr_t *a = get_irn_attr(node);
Sebastian Hack's avatar
Sebastian Hack committed
322

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

325
326
	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
327
		memset(a->reg_data, 0, max_reg_data * sizeof(a->reg_data[0]));
328
329
	} else {
		a->reg_data = NEW_ARR_F(be_reg_data_t, 0);
Sebastian Hack's avatar
Sebastian Hack committed
330
331
332
333
	}

	return a;
}
334

335
336
337
338
339
340
341
342
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);
}

343
int is_be_node(const ir_node *irn)
344
{
Sebastian Hack's avatar
Sebastian Hack committed
345
	return get_op_tag(get_irn_op(irn)) == &be_node_tag;
346
347
}

Sebastian Hack's avatar
Sebastian Hack committed
348
be_opcode_t be_get_irn_opcode(const ir_node *irn)
349
{
350
	return is_be_node(irn) ? (be_opcode_t) get_irn_opcode(irn) - beo_base : beo_NoBeOp;
351
352
}

Michael Beck's avatar
Michael Beck committed
353
354
355
356
357
358
359
360
361
362
/**
 * 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
363
364
365
366
{
	const ir_node *n = *node;

	if(is_Proj(n)) {
367
368
369
370
371
372
373
		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
374
375
376
377
378
379
		return get_Proj_proj(n);
	}

	return 0;
}

Matthias Braun's avatar
Matthias Braun committed
380
static be_reg_data_t *retrieve_reg_data(const ir_node *node)
Sebastian Hack's avatar
Sebastian Hack committed
381
{
Matthias Braun's avatar
Matthias Braun committed
382
383
	be_node_attr_t *attr;
	int pos = 0;
Sebastian Hack's avatar
Sebastian Hack committed
384

Matthias Braun's avatar
Matthias Braun committed
385
386
387
	if(is_Proj(node)) {
		pos = get_Proj_proj(node);
		node = get_Proj_pred(node);
Sebastian Hack's avatar
Sebastian Hack committed
388
389
	}

Matthias Braun's avatar
Matthias Braun committed
390
391
392
	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
393

Matthias Braun's avatar
Matthias Braun committed
394
	return &attr->reg_data[pos];
Sebastian Hack's avatar
Sebastian Hack committed
395
396
}

Sebastian Hack's avatar
Sebastian Hack committed
397
static void
398
be_node_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg)
Sebastian Hack's avatar
Sebastian Hack committed
399
{
Sebastian Hack's avatar
Sebastian Hack committed
400
	be_reg_data_t *r = retrieve_reg_data(irn);
401
	(void) self;
Matthias Braun's avatar
Matthias Braun committed
402
	r->reg = reg;
Sebastian Hack's avatar
Sebastian Hack committed
403
404
}

405
406
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)
407
{
Matthias Braun's avatar
Matthias Braun committed
408
	be_frame_attr_t *a;
409
	ir_node         *in[2];
410
	ir_node         *res;
411

412
413
414
	in[0]     = frame;
	in[1]     = to_spill;
	res       = new_ir_node(NULL, irg, bl, op_be_Spill, mode_M, 2, in);
415
416
	a         = init_node_attr(res, 2);
	a->ent    = NULL;
Matthias Braun's avatar
Matthias Braun committed
417
	a->offset = 0;
Sebastian Hack's avatar
Sebastian Hack committed
418

419
	be_node_set_reg_class(res, be_pos_Spill_frame, cls_frame);
420
	be_node_set_reg_class(res, be_pos_Spill_val, cls);
Sebastian Hack's avatar
Sebastian Hack committed
421
422
	return res;
}
423

424
425
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)
426
{
427
428
429
430
431
432
433
	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
434
435
	init_node_attr(res, 2);
	be_node_set_reg_class(res, -1, cls);
436
	be_node_set_reg_class(res, be_pos_Reload_frame, cls_frame);
437
	be_node_set_flags(res, -1, arch_irn_flags_rematerializable);
Sebastian Hack's avatar
Sebastian Hack committed
438
439
	return res;
}
440

441
ir_node *be_get_Reload_mem(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
442
443
{
	assert(be_is_Reload(irn));
Daniel Grund's avatar
Daniel Grund committed
444
	return get_irn_n(irn, be_pos_Reload_mem);
Sebastian Hack's avatar
Sebastian Hack committed
445
446
}

447
448
449
450
451
452
ir_node *be_get_Reload_frame(const ir_node *irn)
{
	assert(be_is_Reload(irn));
	return get_irn_n(irn, be_pos_Reload_frame);
}

453
454
455
456
457
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
458

459
460
461
462
463
ir_node *be_get_Spill_frame(const ir_node *irn)
{
	assert(be_is_Spill(irn));
	return get_irn_n(irn, be_pos_Spill_frame);
}
464

Sebastian Hack's avatar
Sebastian Hack committed
465
466
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
467
	int i;
468
	ir_node *irn = new_ir_node(NULL, irg, bl, op_be_Perm, mode_T, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
469
470
471
472
473
474
	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
475
476
	return irn;
}
477

478
479
480
481
void be_Perm_reduce(ir_node *perm, int new_size, int *map)
{
	ir_graph *irg           = get_irn_irg(perm);
	int n                   = get_irn_arity(perm);
Michael Beck's avatar
Michael Beck committed
482
	be_reg_data_t *old_data = xmalloc(n * sizeof(old_data[0]));
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
	be_node_attr_t *attr    = get_irn_attr(perm);
	ir_node **new_in        = NEW_ARR_D(ir_node *, irg->obst, new_size + 1);

	int i;

	assert(be_is_Perm(perm));
	assert(new_size <= n);

	/* save the old register data */
	memcpy(old_data, attr->reg_data, n * sizeof(old_data[0]));

	/* compose the new in array and set the new register data directly in place */
	for (i = 0; i < n; ++i) {
		int idx = map[i];
		if (idx >= 0) {
			new_in[idx] = get_irn_n(perm, i);
			attr->reg_data[idx] = old_data[i];
		}
	}

	free(old_data);
	set_irn_in(perm, new_size, new_in);
}

Matthias Braun's avatar
Matthias Braun committed
507
508
509
510
511
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);
512
513
	ir_node *irn;
	const arch_register_t *sp = arch_env->isa->sp;
Matthias Braun's avatar
Matthias Braun committed
514
	be_memperm_attr_t *attr;
515
	ir_node **real_in;
Matthias Braun's avatar
Matthias Braun committed
516

517
518
519
520
521
522
523
524
	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
525
	for(i = 0; i < n; ++i) {
526
		be_node_set_reg_class(irn, i + 1, cls_frame);
Matthias Braun's avatar
Matthias Braun committed
527
528
529
530
531
		be_node_set_reg_class(irn, OUT_POS(i), cls_frame);
	}

	attr = get_irn_attr(irn);

532
533
	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
534
535
536
537
538
539
540
	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
541
542
543
544
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
545
	arch_register_req_t *req;
546

Sebastian Hack's avatar
Sebastian Hack committed
547
	in[0] = op;
548
	res   = new_ir_node(NULL, irg, bl, op_be_Copy, get_irn_mode(op), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
549
550
551
	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
552
553
554
555
556
557

	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
558
	return res;
559
560
}

561
562
563
564
ir_node *be_get_Copy_op(const ir_node *cpy) {
	return get_irn_n(cpy, be_pos_Copy_op);
}

565
566
567
568
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
569
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
570
{
Sebastian Hack's avatar
Sebastian Hack committed
571
	int i;
572
573
574
575
	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
576

Sebastian Hack's avatar
Sebastian Hack committed
577
	for(i = 0; i < n; ++i) {
578
579
580
		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
581
	}
582
583
584
585
586
587
588
589
590
591
592
593
594
	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
595
596
}

Michael Beck's avatar
Michael Beck committed
597
/* creates a be_Call */
598
599
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
600
{
601
602
	be_call_attr_t *a;
	int real_n = be_pos_Call_first_arg + n;
Sebastian Hack's avatar
Sebastian Hack committed
603
604
	ir_node *irn;
	ir_node **real_in;
Sebastian Hack's avatar
Sebastian Hack committed
605

606
607
608
609
610
	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
611

612
	irn = new_ir_node(dbg, irg, bl, op_be_Call, mode_T, real_n, real_in);
613
614
615
	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
616
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
617
618
}

619
/* Gets the call entity or NULL if this is no static call. */
620
ir_entity *be_Call_get_entity(const ir_node *call) {
621
622
623
624
625
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	return a->ent;
}

626
/* Sets the call entity. */
627
void be_Call_set_entity(ir_node *call, ir_entity *ent) {
628
629
630
631
632
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	a->ent = ent;
}

633
634
635
636
637
638
639
640
641
642
643
644
645
646
/* 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;
}

647
/* Construct a new be_Return. */
648
649
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
650
{
651
	be_return_attr_t *a;
652
653
654
655
656
657
658
659
660
661
662
	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);
663
	a->num_ret_vals = n_res;
Sebastian Hack's avatar
Sebastian Hack committed
664

665
	return res;
Sebastian Hack's avatar
Sebastian Hack committed
666
667
}

668
669
670
671
672
673
674
/* 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;
}

675
676
677
678
679
680
681
682
683
684
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
685
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
686
{
Sebastian Hack's avatar
Sebastian Hack committed
687
688
	be_stack_attr_t *a;
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
689
	ir_node *in[1];
Sebastian Hack's avatar
Sebastian Hack committed
690
691

	in[0]     = old_sp;
Sebastian Hack's avatar
Sebastian Hack committed
692
	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
693
	a         = init_node_attr(irn, 1);
Sebastian Hack's avatar
Sebastian Hack committed
694
695
	a->offset = offset;

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

Sebastian Hack's avatar
Sebastian Hack committed
698
	/* Set output constraint to stack register. */
Sebastian Hack's avatar
Sebastian Hack committed
699
	be_node_set_reg_class(irn, 0, sp->reg_class);
700
	be_set_constr_single_reg(irn, BE_OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
701
	be_node_set_irn_reg(NULL, irn, sp);
Sebastian Hack's avatar
Sebastian Hack committed
702
703

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
704
}
Sebastian Hack's avatar
Sebastian Hack committed
705

Sebastian Hack's avatar
Sebastian Hack committed
706
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
707
{
Sebastian Hack's avatar
Sebastian Hack committed
708
	be_node_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
709
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
710
	ir_node *in[be_pos_AddSP_last];
711
	const arch_register_class_t *class;
Sebastian Hack's avatar
Sebastian Hack committed
712

Sebastian Hack's avatar
Sebastian Hack committed
713
714
	in[be_pos_AddSP_old_sp] = old_sp;
	in[be_pos_AddSP_size]   = sz;
Sebastian Hack's avatar
Sebastian Hack committed
715

716
717
	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
718

719
720
	be_node_set_flags(irn, OUT_POS(pn_be_AddSP_sp),
	                  arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
721
722

	/* Set output constraint to stack register. */
723
724
	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));
725
726
727
728
729
	be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_sp), sp);
	a->reg_data[pn_be_AddSP_sp].reg = sp;

	class = arch_register_get_class(sp);
	be_node_set_reg_class(irn, OUT_POS(pn_be_AddSP_res), class);
Sebastian Hack's avatar
Sebastian Hack committed
730
731
732
733

	return irn;
}

Michael Beck's avatar
Michael Beck committed
734
735
736
737
738
739
740
741
742
743
744
745
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);

746
747
	be_node_set_flags(irn, OUT_POS(pn_be_SubSP_sp),
	                  arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Michael Beck's avatar
Michael Beck committed
748
749
750
751

	/* 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));
752
753
	be_set_constr_single_reg(irn, OUT_POS(pn_be_SubSP_sp), sp);
	a->reg_data[pn_be_SubSP_sp].reg = sp;
Michael Beck's avatar
Michael Beck committed
754
755
756
757

	return irn;
}

758
759
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)
Sebastian Hack's avatar
Sebastian Hack committed
760
761
762
763
764
{
	be_node_attr_t *a;
	ir_node *irn;
	ir_node *in[3];

765
766
767
768
769
	in[0] = mem;
	in[1] = old_sp;
	in[2] = op;
	irn   = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in);
	a     = init_node_attr(irn, 3);
Sebastian Hack's avatar
Sebastian Hack committed
770

771
	be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
772
773
774

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

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
779
}
Sebastian Hack's avatar
Sebastian Hack committed
780

781
ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs)
Sebastian Hack's avatar
Sebastian Hack committed
782
{
783
784
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
785

786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
	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
804
	ir_node *proj;
805
806

	assert(be_is_RegParams(regparams));
Michael Beck's avatar
Michael Beck committed
807
	proj = new_r_Proj(irg, block, regparams, mode, n);
808
	add_register_req(regparams);
809
	be_set_constr_single_reg(regparams, BE_OUT_POS(n), reg);
810
811
	arch_set_irn_register(arch_env, proj, reg);

Michael Beck's avatar
Michael Beck committed
812
	/* TODO decide, whether we need to set ignore/modify sp flags here? */
813
814

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
815
816
}

817
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
818
{
819
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
820
821
822
	ir_node *irn;
	ir_node *in[1];

823
	in[0]  = frame;
824
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameAddr, get_irn_mode(frame), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
825
	a      = init_node_attr(irn, 1);
826
827
828
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 0, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
829
	be_node_set_reg_class(irn, OUT_POS(0), cls_frame);
Michael Beck's avatar
Michael Beck committed
830
831

	return optimize_node(irn);
Sebastian Hack's avatar
Sebastian Hack committed
832
833
}

Matthias Braun's avatar
Matthias Braun committed
834
ir_node *be_get_FrameAddr_frame(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
835
836
837
838
	assert(be_is_FrameAddr(node));
	return get_irn_n(node, be_pos_FrameAddr_ptr);
}

Matthias Braun's avatar
Matthias Braun committed
839
840
841
842
843
844
ir_entity *be_get_FrameAddr_entity(const ir_node *node)
{
	const be_frame_attr_t *attr = get_irn_generic_attr_const(node);
	return attr->ent;
}

Sebastian Hack's avatar
Sebastian Hack committed
845
846
847
848
849
850
851
852
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
853
	init_node_attr(irn, n + 1);
Sebastian Hack's avatar
Sebastian Hack committed
854
855
856
857
858
859
860
861
862
863
864
865
866
867
	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);
}

868
869
870
871
872
873
874
875
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);
}

876
ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
877
{
878
879
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
880

881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
	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);
897

898
899
900
901
	ir_node *proj = new_r_Proj(irg, block, barrier, mode, n);
	add_register_req(barrier);

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
902
903
}

Sebastian Hack's avatar
Sebastian Hack committed
904
905
906
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
907
int be_is_CopyKeep      (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_CopyKeep       ; }
Sebastian Hack's avatar
Sebastian Hack committed
908
int be_is_Perm          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Perm           ; }
Matthias Braun's avatar
Matthias Braun committed
909
int be_is_MemPerm       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_MemPerm        ; }
Sebastian Hack's avatar
Sebastian Hack committed
910
911
912
913
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
914
int be_is_SetSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SetSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
915
int be_is_AddSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_AddSP          ; }
916
int be_is_SubSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SubSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
917
int be_is_RegParams     (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_RegParams      ; }
918
int be_is_FrameAddr     (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_FrameAddr      ; }
919
int be_is_Barrier       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Barrier        ; }
920
921
922
923
924

int be_has_frame_entity(const ir_node *irn)
{
	switch(be_get_irn_opcode(irn)) {
	case beo_Spill:
925
	case beo_Reload:
926
927
	case beo_FrameAddr:
		return 1;
928
929
	default:
		return 0;
930
931
932
	}
}

933
ir_entity *be_get_frame_entity(const ir_node *irn)
934
{
935
	if (be_has_frame_entity(irn)) {
936
937
938
939
940
		be_frame_attr_t *a = get_irn_attr(irn);
		return a->ent;
	}
	return NULL;
}
Sebastian Hack's avatar
Sebastian Hack committed
941

942
943
944
945
946
947
948
949
950
951
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;
}

952
void be_set_MemPerm_in_entity(const ir_node *irn, int n, ir_entity *ent)
Matthias Braun's avatar
Matthias Braun committed
953
954
955
956
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
957
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
958
959
960
961

	attr->in_entities[n] = ent;
}

962
ir_entity* be_get_MemPerm_in_entity(const ir_node* irn, int n)
Matthias Braun's avatar
Matthias Braun committed
963
964
965
966
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
967
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
968
969
970
971

	return attr->in_entities[n];
}

972
void be_set_MemPerm_out_entity(const ir_node *irn, int n, ir_entity *ent)
Matthias Braun's avatar
Matthias Braun committed
973
974
975
976
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
977
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
978
979
980
981

	attr->out_entities[n] = ent;
}

982
ir_entity* be_get_MemPerm_out_entity(const ir_node* irn, int n)