benode.c 48.7 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
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	return irn;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Michael Beck's avatar
Michael Beck committed
864
865
866
867
868
ir_node *be_get_FrameAddr_frame(ir_node *node) {
	assert(be_is_FrameAddr(node));
	return get_irn_n(node, be_pos_FrameAddr_ptr);
}

Sebastian Hack's avatar
Sebastian Hack committed
869
870
871
872
873
874
875
876
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
877
	init_node_attr(irn, n + 1);
Sebastian Hack's avatar
Sebastian Hack committed
878
879
880
881
882
883
884
885
886
887
888
889
890
891
	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);
}

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

900
ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
901
{
902
903
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
904

905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
	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);
921

922
923
924
925
	ir_node *proj = new_r_Proj(irg, block, barrier, mode, n);
	add_register_req(barrier);

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
926
927
}

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

int be_has_frame_entity(const ir_node *irn)
{
	switch(be_get_irn_opcode(irn)) {
	case beo_StackParam:
	case beo_Spill:
953
	case beo_Reload:
954
955
956
957
	case beo_FrameStore:
	case beo_FrameLoad:
	case beo_FrameAddr:
		return 1;
958
959
	default:
		return 0;
960
961
962
	}
}

963
ir_entity *