benode.c 48.6 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
131
132
133
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;
134
ir_op *op_be_Barrier;
Sebastian Hack's avatar
Sebastian Hack committed
135

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

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

140
141
142
143
144
145
146
147
148
149
#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
150
151
#define M   irop_flag_machine

152

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

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

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

	return 0;
Michael Beck's avatar
Michael Beck committed
173
174
}

175
176
177
178
179
180
181
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
182
183
184
185
186
187
188
189
190
/**
 * 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);

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
223
224
225
	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
226
227
}

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

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

Sebastian Hack's avatar
Sebastian Hack committed
255
256
void be_node_init(void) {
	static int inited = 0;
Sebastian Hack's avatar
Sebastian Hack committed
257

Sebastian Hack's avatar
Sebastian Hack committed
258
259
	if(inited)
		return;
Sebastian Hack's avatar
Sebastian Hack committed
260

Sebastian Hack's avatar
Sebastian Hack committed
261
	inited = 1;
Sebastian Hack's avatar
Sebastian Hack committed
262

263
	/* Acquire all needed opcodes. */
264
	beo_base = get_next_ir_opcodes(beo_Last);
Sebastian Hack's avatar
Sebastian Hack committed
265

266
267
	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
268
	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);
269
	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
270
	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);
271
	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
272
	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);
273
	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);
274
	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
275
	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
276
	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);
277
	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);
278
	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
279
	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);
280
281
282
283
	op_be_StackParam = new_ir_op(beo_base + beo_StackParam, "be_StackParam", op_pin_state_floats,     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_floats,     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_floats,     N, oparity_any,      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_floats,     N, oparity_unary,    0, sizeof(be_frame_attr_t),   &be_node_op_ops);
284
	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);
285
286

	set_op_tag(op_be_Spill,      &be_node_tag);
287
	op_be_Spill->ops.node_cmp_attr = FrameAddr_cmp_attr;
288
	set_op_tag(op_be_Reload,     &be_node_tag);
289
	op_be_Reload->ops.node_cmp_attr = FrameAddr_cmp_attr;
290
	set_op_tag(op_be_Perm,       &be_node_tag);
291
	op_be_Perm->ops.node_cmp_attr = node_cmp_attr;
Matthias Braun's avatar
Matthias Braun committed
292
	set_op_tag(op_be_MemPerm,    &be_node_tag);
293
	op_be_MemPerm->ops.node_cmp_attr = node_cmp_attr;
294
	set_op_tag(op_be_Copy,       &be_node_tag);
295
	op_be_Copy->ops.node_cmp_attr = node_cmp_attr;
296
	set_op_tag(op_be_Keep,       &be_node_tag);
297
	op_be_Keep->ops.node_cmp_attr = node_cmp_attr;
Sebastian Hack's avatar
Sebastian Hack committed
298
	set_op_tag(op_be_CopyKeep,   &be_node_tag);
299
	op_be_CopyKeep->ops.node_cmp_attr = node_cmp_attr;
300
	set_op_tag(op_be_Call,       &be_node_tag);
301
	op_be_Call->ops.node_cmp_attr = Call_cmp_attr;
302
	set_op_tag(op_be_Return,     &be_node_tag);
303
	op_be_Return->ops.node_cmp_attr = Return_cmp_attr;
Sebastian Hack's avatar
Sebastian Hack committed
304
	set_op_tag(op_be_AddSP,      &be_node_tag);
305
	op_be_AddSP->ops.node_cmp_attr = node_cmp_attr;
Michael Beck's avatar
Michael Beck committed
306
	set_op_tag(op_be_SubSP,      &be_node_tag);
307
	op_be_SubSP->ops.node_cmp_attr = node_cmp_attr;
308
	set_op_tag(op_be_SetSP,      &be_node_tag);
309
	op_be_SetSP->ops.node_cmp_attr = Stack_cmp_attr;
310
	set_op_tag(op_be_IncSP,      &be_node_tag);
311
	op_be_IncSP->ops.node_cmp_attr = Stack_cmp_attr;
312
	set_op_tag(op_be_RegParams,  &be_node_tag);
313
	op_be_RegParams->ops.node_cmp_attr = node_cmp_attr;
314
	set_op_tag(op_be_StackParam, &be_node_tag);
315
	op_be_StackParam->ops.node_cmp_attr = FrameAddr_cmp_attr;
316
	set_op_tag(op_be_FrameLoad,  &be_node_tag);
317
	op_be_FrameLoad->ops.node_cmp_attr = FrameAddr_cmp_attr;
318
	set_op_tag(op_be_FrameStore, &be_node_tag);
319
	op_be_FrameStore->ops.node_cmp_attr = FrameAddr_cmp_attr;
320
	set_op_tag(op_be_FrameAddr,  &be_node_tag);
Michael Beck's avatar
Michael Beck committed
321
	op_be_FrameAddr->ops.node_cmp_attr = FrameAddr_cmp_attr;
322
323
	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
324
}
325

326
327
328
/**
 * Initializes the generic attribute of all be nodes and return ir.
 */
329
static void *init_node_attr(ir_node *node, int max_reg_data)
Sebastian Hack's avatar
Sebastian Hack committed
330
{
331
	ir_graph *irg = get_irn_irg(node);
332
	struct obstack *obst = get_irg_obstack(irg);
333
	be_node_attr_t *a = get_irn_attr(node);
Sebastian Hack's avatar
Sebastian Hack committed
334

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

337
338
	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
339
		memset(a->reg_data, 0, max_reg_data * sizeof(a->reg_data[0]));
340
341
	} else {
		a->reg_data = NEW_ARR_F(be_reg_data_t, 0);
Sebastian Hack's avatar
Sebastian Hack committed
342
343
344
345
	}

	return a;
}
346

347
348
349
350
351
352
353
354
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);
}

355
int is_be_node(const ir_node *irn)
356
{
Sebastian Hack's avatar
Sebastian Hack committed
357
	return get_op_tag(get_irn_op(irn)) == &be_node_tag;
358
359
}

Sebastian Hack's avatar
Sebastian Hack committed
360
be_opcode_t be_get_irn_opcode(const ir_node *irn)
361
{
Sebastian Hack's avatar
Sebastian Hack committed
362
	return is_be_node(irn) ? get_irn_opcode(irn) - beo_base : beo_NoBeOp;
363
364
}

Michael Beck's avatar
Michael Beck committed
365
366
367
368
369
370
371
372
373
374
/**
 * 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
375
376
377
378
{
	const ir_node *n = *node;

	if(is_Proj(n)) {
379
380
381
382
383
384
385
		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
386
387
388
389
390
391
		return get_Proj_proj(n);
	}

	return 0;
}

Matthias Braun's avatar
Matthias Braun committed
392
static be_reg_data_t *retrieve_reg_data(const ir_node *node)
Sebastian Hack's avatar
Sebastian Hack committed
393
{
Matthias Braun's avatar
Matthias Braun committed
394
395
	be_node_attr_t *attr;
	int pos = 0;
Sebastian Hack's avatar
Sebastian Hack committed
396

Matthias Braun's avatar
Matthias Braun committed
397
398
399
	if(is_Proj(node)) {
		pos = get_Proj_proj(node);
		node = get_Proj_pred(node);
Sebastian Hack's avatar
Sebastian Hack committed
400
401
	}

Matthias Braun's avatar
Matthias Braun committed
402
403
404
	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
405

Matthias Braun's avatar
Matthias Braun committed
406
	return &attr->reg_data[pos];
Sebastian Hack's avatar
Sebastian Hack committed
407
408
}

Sebastian Hack's avatar
Sebastian Hack committed
409
410
411
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
412
	be_reg_data_t *r = retrieve_reg_data(irn);
Matthias Braun's avatar
Matthias Braun committed
413
	r->reg = reg;
Sebastian Hack's avatar
Sebastian Hack committed
414
415
}

416
417
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)
418
{
Matthias Braun's avatar
Matthias Braun committed
419
	be_frame_attr_t *a;
420
	ir_node         *in[2];
421
	ir_node         *res;
422

423
424
425
	in[0]     = frame;
	in[1]     = to_spill;
	res       = new_ir_node(NULL, irg, bl, op_be_Spill, mode_M, 2, in);
426
427
	a         = init_node_attr(res, 2);
	a->ent    = NULL;
Matthias Braun's avatar
Matthias Braun committed
428
	a->offset = 0;
Sebastian Hack's avatar
Sebastian Hack committed
429

430
	be_node_set_reg_class(res, be_pos_Spill_frame, cls_frame);
431
	be_node_set_reg_class(res, be_pos_Spill_val, cls);
Sebastian Hack's avatar
Sebastian Hack committed
432
433
	return res;
}
434

435
436
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)
437
{
438
439
440
441
442
443
444
	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
445
446
	init_node_attr(res, 2);
	be_node_set_reg_class(res, -1, cls);
447
	be_node_set_reg_class(res, be_pos_Reload_frame, cls_frame);
448
	be_node_set_flags(res, -1, arch_irn_flags_rematerializable);
Sebastian Hack's avatar
Sebastian Hack committed
449
450
	return res;
}
451

452
ir_node *be_get_Reload_mem(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
453
454
{
	assert(be_is_Reload(irn));
Daniel Grund's avatar
Daniel Grund committed
455
	return get_irn_n(irn, be_pos_Reload_mem);
Sebastian Hack's avatar
Sebastian Hack committed
456
457
}

458
459
460
461
462
463
ir_node *be_get_Reload_frame(const ir_node *irn)
{
	assert(be_is_Reload(irn));
	return get_irn_n(irn, be_pos_Reload_frame);
}

464
465
466
467
468
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
469

470
471
472
473
474
ir_node *be_get_Spill_frame(const ir_node *irn)
{
	assert(be_is_Spill(irn));
	return get_irn_n(irn, be_pos_Spill_frame);
}
475

Sebastian Hack's avatar
Sebastian Hack committed
476
477
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
478
	int i;
479
	ir_node *irn = new_ir_node(NULL, irg, bl, op_be_Perm, mode_T, n, in);
Sebastian Hack's avatar
Sebastian Hack committed
480
481
482
483
484
485
	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
486
487
	return irn;
}
488

Matthias Braun's avatar
Matthias Braun committed
489
490
491
492
493
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);
494
495
	ir_node *irn;
	const arch_register_t *sp = arch_env->isa->sp;
Matthias Braun's avatar
Matthias Braun committed
496
	be_memperm_attr_t *attr;
497
	ir_node **real_in;
Matthias Braun's avatar
Matthias Braun committed
498

499
500
501
502
503
504
505
506
	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
507
	for(i = 0; i < n; ++i) {
508
		be_node_set_reg_class(irn, i + 1, cls_frame);
Matthias Braun's avatar
Matthias Braun committed
509
510
511
512
513
		be_node_set_reg_class(irn, OUT_POS(i), cls_frame);
	}

	attr = get_irn_attr(irn);

514
515
	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
516
517
518
519
520
521
522
	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
523
524
525
526
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
527
	arch_register_req_t *req;
528

Sebastian Hack's avatar
Sebastian Hack committed
529
	in[0] = op;
530
	res   = new_ir_node(NULL, irg, bl, op_be_Copy, get_irn_mode(op), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
531
532
533
	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
534
535
536
537
538
539

	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
540
	return res;
541
542
}

543
544
545
546
ir_node *be_get_Copy_op(const ir_node *cpy) {
	return get_irn_n(cpy, be_pos_Copy_op);
}

547
548
549
550
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
551
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
552
{
Sebastian Hack's avatar
Sebastian Hack committed
553
	int i;
554
555
556
557
	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
558

Sebastian Hack's avatar
Sebastian Hack committed
559
	for(i = 0; i < n; ++i) {
560
561
562
		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
563
	}
564
565
566
567
568
569
570
571
572
573
574
575
576
	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
577
578
}

579
580
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
581
{
582
583
	be_call_attr_t *a;
	int real_n = be_pos_Call_first_arg + n;
Sebastian Hack's avatar
Sebastian Hack committed
584
585
	ir_node *irn;
	ir_node **real_in;
Sebastian Hack's avatar
Sebastian Hack committed
586

587
588
589
590
591
	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
592

593
	irn = new_ir_node(dbg, irg, bl, op_be_Call, mode_T, real_n, real_in);
594
595
596
	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
597
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
598
599
}

600
/* Gets the call entity or NULL if this is no static call. */
601
ir_entity *be_Call_get_entity(const ir_node *call) {
602
603
604
605
606
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	return a->ent;
}

607
/* Sets the call entity. */
608
void be_Call_set_entity(ir_node *call, ir_entity *ent) {
609
610
611
612
613
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	a->ent = ent;
}

614
615
616
617
618
619
620
621
622
623
624
625
626
627
/* 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;
}

628
/* Construct a new be_Return. */
629
630
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
631
{
632
	be_return_attr_t *a;
633
634
635
636
637
638
639
640
641
642
643
	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);
644
	a->num_ret_vals = n_res;
Sebastian Hack's avatar
Sebastian Hack committed
645

646
	return res;
Sebastian Hack's avatar
Sebastian Hack committed
647
648
}

649
650
651
652
653
654
655
/* 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;
}

656
657
658
659
660
661
662
663
664
665
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
666
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
667
{
Sebastian Hack's avatar
Sebastian Hack committed
668
669
	be_stack_attr_t *a;
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
670
	ir_node *in[1];
Sebastian Hack's avatar
Sebastian Hack committed
671
672

	in[0]     = old_sp;
Sebastian Hack's avatar
Sebastian Hack committed
673
	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
674
	a         = init_node_attr(irn, 1);
Sebastian Hack's avatar
Sebastian Hack committed
675
676
	a->offset = offset;

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

Sebastian Hack's avatar
Sebastian Hack committed
679
	/* Set output constraint to stack register. */
Sebastian Hack's avatar
Sebastian Hack committed
680
	be_node_set_reg_class(irn, 0, sp->reg_class);
681
	be_set_constr_single_reg(irn, BE_OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
682
	be_node_set_irn_reg(NULL, irn, sp);
Sebastian Hack's avatar
Sebastian Hack committed
683
684

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
685
}
Sebastian Hack's avatar
Sebastian Hack committed
686

Sebastian Hack's avatar
Sebastian Hack committed
687
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
688
{
Sebastian Hack's avatar
Sebastian Hack committed
689
	be_node_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
690
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
691
	ir_node *in[be_pos_AddSP_last];
Sebastian Hack's avatar
Sebastian Hack committed
692

Sebastian Hack's avatar
Sebastian Hack committed
693
694
	in[be_pos_AddSP_old_sp] = old_sp;
	in[be_pos_AddSP_size]   = sz;
Sebastian Hack's avatar
Sebastian Hack committed
695

696
697
	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
698

Sebastian Hack's avatar
Sebastian Hack committed
699
	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
700
701

	/* Set output constraint to stack register. */
702
703
	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
704
	be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_res), sp);
705
	a->reg_data[pn_be_AddSP_res].reg = sp;
Sebastian Hack's avatar
Sebastian Hack committed
706
707
708
709

	return irn;
}

Michael Beck's avatar
Michael Beck committed
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
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
733
734
735
736
737
738
739
740
741
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;
742
	irn      = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
743
744
	a        = init_node_attr(irn, 3);

745
	be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
746
747
748

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

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
753
}
Sebastian Hack's avatar
Sebastian Hack committed
754

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

761
	in[0] = frame_pointer;
762
	irn = new_ir_node(NULL, irg, bl, op_be_StackParam, mode, 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
763
	a = init_node_attr(irn, 1);
764
	a->ent = ent;
Sebastian Hack's avatar
Sebastian Hack committed
765
766
767

	be_node_set_reg_class(irn, 0, cls_frame);
	be_node_set_reg_class(irn, OUT_POS(0), cls);
768
769
	be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_rematerializable);

Sebastian Hack's avatar
Sebastian Hack committed
770
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
771
}
Sebastian Hack's avatar
Sebastian Hack committed
772

773
ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs)
Sebastian Hack's avatar
Sebastian Hack committed
774
{
775
776
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
777

778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
	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
796
	ir_node *proj;
797
798

	assert(be_is_RegParams(regparams));
Michael Beck's avatar
Michael Beck committed
799
	proj = new_r_Proj(irg, block, regparams, mode, n);
800
	add_register_req(regparams);
801
	be_set_constr_single_reg(regparams, BE_OUT_POS(n), reg);
802
803
	arch_set_irn_register(arch_env, proj, reg);

Michael Beck's avatar
Michael Beck committed
804
	/* TODO decide, whether we need to set ignore/modify sp flags here? */
805
806

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
807
808
}

809
ir_node *be_new_FrameLoad(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
810
						  ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_entity *ent)
811
812
813
814
815
816
817
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[2];

	in[0]  = mem;
	in[1]  = frame;
818
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameLoad, mode_T, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
819
	a      = init_node_attr(irn, 3);
820
821
822
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 1, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
823
	be_node_set_reg_class(irn, OUT_POS(pn_Load_res), cls_data);
824
825
826
827
	return irn;
}

ir_node *be_new_FrameStore(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
828
						   ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_node *data, ir_entity *ent)
829
830
831
832
833
834
835
836
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[3];

	in[0]  = mem;
	in[1]  = frame;
	in[2]  = data;
837
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameStore, mode_T, 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
838
	a      = init_node_attr(irn, 3);
839
840
841
842
843
844
845
	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;
}

846
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
847
{
848
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
849
850
851
	ir_node *irn;
	ir_node *in[1];

852
	in[0]  = frame;
853
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameAddr, get_irn_mode(frame), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
854
	a      = init_node_attr(irn, 1);
855
856
857
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 0, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
858
	be_node_set_reg_class(irn, OUT_POS(0), cls_frame);
Michael Beck's avatar
Michael Beck committed
859
860

	return optimize_node(irn);
Sebastian Hack's avatar
Sebastian Hack committed
861
862
}

Sebastian Hack's avatar
Sebastian Hack committed
863
864
865
866
867
868
869
870
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
871
	init_node_attr(irn, n + 1);
Sebastian Hack's avatar
Sebastian Hack committed
872
873
874
875
876
877
878
879
880
881
882
883
884
885
	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);
}

886
887
888
889
890
891
892
893
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);
}

894
ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
895
{
896
897
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
898

899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
	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);
915

916
917
918
919
	ir_node *proj = new_r_Proj(irg, block, barrier, mode, n);
	add_register_req(barrier);

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
920
921
}

Sebastian Hack's avatar
Sebastian Hack committed
922
923
924
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
925
int be_is_CopyKeep      (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_CopyKeep       ; }
Sebastian Hack's avatar
Sebastian Hack committed
926
int be_is_Perm          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Perm           ; }
Matthias Braun's avatar
Matthias Braun committed
927
int be_is_MemPerm       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_MemPerm        ; }
Sebastian Hack's avatar
Sebastian Hack committed
928
929
930
931
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
932
int be_is_SetSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SetSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
933
int be_is_AddSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_AddSP          ; }
934
int be_is_SubSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SubSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
935
936
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     ; }
937
938
939
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     ; }
940
int be_is_Barrier       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Barrier        ; }
941
942
943
944
945
946

int be_has_frame_entity(const ir_node *irn)
{
	switch(be_get_irn_opcode(irn)) {
	case beo_StackParam:
	case beo_Spill:
947
	case beo_Reload:
948
949
950
951
	case beo_FrameStore:
	case beo_FrameLoad:
	case beo_FrameAddr:
		return 1;
952
953
	default:
		return 0;
954
955
956
	}
}

957
ir_entity *be_get_frame_entity(const ir_node *irn)
958
{
959
	if (be_has_frame_entity(irn)) {