benode.c 49.9 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
{
362
	return is_be_node(irn) ? (be_opcode_t) 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
static void
410
be_node_set_irn_reg(const void *self, ir_node *irn, const arch_register_t *reg)
Sebastian Hack's avatar
Sebastian Hack committed
411
{
Sebastian Hack's avatar
Sebastian Hack committed
412
	be_reg_data_t *r = retrieve_reg_data(irn);
413
	(void) self;
Matthias Braun's avatar
Matthias Braun committed
414
	r->reg = reg;
Sebastian Hack's avatar
Sebastian Hack committed
415
416
}

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

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

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

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

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

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

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

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

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

490
491
492
493
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
494
	be_reg_data_t *old_data = xmalloc(n * sizeof(old_data[0]));
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
	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
519
520
521
522
523
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);
524
525
	ir_node *irn;
	const arch_register_t *sp = arch_env->isa->sp;
Matthias Braun's avatar
Matthias Braun committed
526
	be_memperm_attr_t *attr;
527
	ir_node **real_in;
Matthias Braun's avatar
Matthias Braun committed
528

529
530
531
532
533
534
535
536
	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
537
	for(i = 0; i < n; ++i) {
538
		be_node_set_reg_class(irn, i + 1, cls_frame);
Matthias Braun's avatar
Matthias Braun committed
539
540
541
542
543
		be_node_set_reg_class(irn, OUT_POS(i), cls_frame);
	}

	attr = get_irn_attr(irn);

544
545
	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
546
547
548
549
550
551
552
	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
553
554
555
556
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
557
	arch_register_req_t *req;
558

Sebastian Hack's avatar
Sebastian Hack committed
559
	in[0] = op;
560
	res   = new_ir_node(NULL, irg, bl, op_be_Copy, get_irn_mode(op), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
561
562
563
	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
564
565
566
567
568
569

	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
570
	return res;
571
572
}

573
574
575
576
ir_node *be_get_Copy_op(const ir_node *cpy) {
	return get_irn_n(cpy, be_pos_Copy_op);
}

577
578
579
580
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
581
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
582
{
Sebastian Hack's avatar
Sebastian Hack committed
583
	int i;
584
585
586
587
	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
588

Sebastian Hack's avatar
Sebastian Hack committed
589
	for(i = 0; i < n; ++i) {
590
591
592
		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
593
	}
594
595
596
597
598
599
600
601
602
603
604
605
606
	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
607
608
}

Michael Beck's avatar
Michael Beck committed
609
/* creates a be_Call */
610
611
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
612
{
613
614
	be_call_attr_t *a;
	int real_n = be_pos_Call_first_arg + n;
Sebastian Hack's avatar
Sebastian Hack committed
615
616
	ir_node *irn;
	ir_node **real_in;
Sebastian Hack's avatar
Sebastian Hack committed
617

618
619
620
621
622
	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
623

624
	irn = new_ir_node(dbg, irg, bl, op_be_Call, mode_T, real_n, real_in);
625
626
627
	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
628
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
629
630
}

631
/* Gets the call entity or NULL if this is no static call. */
632
ir_entity *be_Call_get_entity(const ir_node *call) {
633
634
635
636
637
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	return a->ent;
}

638
/* Sets the call entity. */
639
void be_Call_set_entity(ir_node *call, ir_entity *ent) {
640
641
642
643
644
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	a->ent = ent;
}

645
646
647
648
649
650
651
652
653
654
655
656
657
658
/* 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;
}

659
/* Construct a new be_Return. */
660
661
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
662
{
663
	be_return_attr_t *a;
664
665
666
667
668
669
670
671
672
673
674
	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);
675
	a->num_ret_vals = n_res;
Sebastian Hack's avatar
Sebastian Hack committed
676

677
	return res;
Sebastian Hack's avatar
Sebastian Hack committed
678
679
}

680
681
682
683
684
685
686
/* 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;
}

687
688
689
690
691
692
693
694
695
696
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
697
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
698
{
Sebastian Hack's avatar
Sebastian Hack committed
699
700
	be_stack_attr_t *a;
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
701
	ir_node *in[1];
Sebastian Hack's avatar
Sebastian Hack committed
702
703

	in[0]     = old_sp;
Sebastian Hack's avatar
Sebastian Hack committed
704
	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
705
	a         = init_node_attr(irn, 1);
Sebastian Hack's avatar
Sebastian Hack committed
706
707
	a->offset = offset;

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

Sebastian Hack's avatar
Sebastian Hack committed
710
	/* Set output constraint to stack register. */
Sebastian Hack's avatar
Sebastian Hack committed
711
	be_node_set_reg_class(irn, 0, sp->reg_class);
712
	be_set_constr_single_reg(irn, BE_OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
713
	be_node_set_irn_reg(NULL, irn, sp);
Sebastian Hack's avatar
Sebastian Hack committed
714
715

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
716
}
Sebastian Hack's avatar
Sebastian Hack committed
717

Sebastian Hack's avatar
Sebastian Hack committed
718
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
719
{
Sebastian Hack's avatar
Sebastian Hack committed
720
	be_node_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
721
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
722
	ir_node *in[be_pos_AddSP_last];
Sebastian Hack's avatar
Sebastian Hack committed
723

Sebastian Hack's avatar
Sebastian Hack committed
724
725
	in[be_pos_AddSP_old_sp] = old_sp;
	in[be_pos_AddSP_size]   = sz;
Sebastian Hack's avatar
Sebastian Hack committed
726

727
728
	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
729

Sebastian Hack's avatar
Sebastian Hack committed
730
	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
731
732

	/* Set output constraint to stack register. */
733
734
	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
735
	be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_res), sp);
736
	a->reg_data[pn_be_AddSP_res].reg = sp;
Sebastian Hack's avatar
Sebastian Hack committed
737
738
739
740

	return irn;
}

Michael Beck's avatar
Michael Beck committed
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
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
764
765
766
767
768
769
770
771
772
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;
773
	irn      = new_ir_node(NULL, irg, bl, op_be_SetSP, get_irn_mode(old_sp), 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
774
775
	a        = init_node_attr(irn, 3);

776
	be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
777
778
779

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

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
784
}
Sebastian Hack's avatar
Sebastian Hack committed
785

786
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
787
{
788
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
789
790
791
	ir_node *irn;
	ir_node *in[1];

792
	in[0] = frame_pointer;
793
	irn = new_ir_node(NULL, irg, bl, op_be_StackParam, mode, 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
794
	a = init_node_attr(irn, 1);
795
	a->ent = ent;
Sebastian Hack's avatar
Sebastian Hack committed
796
797
798

	be_node_set_reg_class(irn, 0, cls_frame);
	be_node_set_reg_class(irn, OUT_POS(0), cls);
799
800
	be_node_set_flags(irn, OUT_POS(0), arch_irn_flags_rematerializable);

Sebastian Hack's avatar
Sebastian Hack committed
801
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
802
}
Sebastian Hack's avatar
Sebastian Hack committed
803

804
ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs)
Sebastian Hack's avatar
Sebastian Hack committed
805
{
806
807
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
808

809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
	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
827
	ir_node *proj;
828
829

	assert(be_is_RegParams(regparams));
Michael Beck's avatar
Michael Beck committed
830
	proj = new_r_Proj(irg, block, regparams, mode, n);
831
	add_register_req(regparams);
832
	be_set_constr_single_reg(regparams, BE_OUT_POS(n), reg);
833
834
	arch_set_irn_register(arch_env, proj, reg);

Michael Beck's avatar
Michael Beck committed
835
	/* TODO decide, whether we need to set ignore/modify sp flags here? */
836
837

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
838
839
}

840
ir_node *be_new_FrameLoad(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
841
						  ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_entity *ent)
842
843
844
845
846
847
848
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[2];

	in[0]  = mem;
	in[1]  = frame;
849
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameLoad, mode_T, 2, in);
Sebastian Hack's avatar
Sebastian Hack committed
850
	a      = init_node_attr(irn, 3);
851
852
853
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 1, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
854
	be_node_set_reg_class(irn, OUT_POS(pn_Load_res), cls_data);
855
856
857
858
	return irn;
}

ir_node *be_new_FrameStore(const arch_register_class_t *cls_frame, const arch_register_class_t *cls_data,
859
						   ir_graph *irg, ir_node *bl, ir_node *mem, ir_node *frame, ir_node *data, ir_entity *ent)
860
861
862
863
864
865
866
867
{
	be_frame_attr_t *a;
	ir_node *irn;
	ir_node *in[3];

	in[0]  = mem;
	in[1]  = frame;
	in[2]  = data;
868
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameStore, mode_T, 3, in);
Sebastian Hack's avatar
Sebastian Hack committed
869
	a      = init_node_attr(irn, 3);
870
871
872
873
874
875
876
	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;
}

877
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
878
{
879
	be_frame_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
880
881
882
	ir_node *irn;
	ir_node *in[1];

883
	in[0]  = frame;
884
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameAddr, get_irn_mode(frame), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
885
	a      = init_node_attr(irn, 1);
886
887
888
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 0, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
889
	be_node_set_reg_class(irn, OUT_POS(0), cls_frame);
Michael Beck's avatar
Michael Beck committed
890
891

	return optimize_node(irn);
Sebastian Hack's avatar
Sebastian Hack committed
892
893
}

Michael Beck's avatar
Michael Beck committed
894
895
896
897
898
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
899
900
901
902
903
904
905
906
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
907
	init_node_attr(irn, n + 1);
Sebastian Hack's avatar
Sebastian Hack committed
908
909
910
911
912
913
914
915
916
917
918
919
920
921
	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);
}

922
923
924
925
926
927
928
929
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);
}

930
ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
931
{
932
933
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
934

935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
	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);
951

952
953
954
955
	ir_node *proj = new_r_Proj(irg, block, barrier, mode, n);
	add_register_req(barrier);

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
956
957
}

Sebastian Hack's avatar
Sebastian Hack committed
958
959
960
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
961
int be_is_CopyKeep      (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_CopyKeep       ; }
Sebastian Hack's avatar
Sebastian Hack committed
962
int be_is_Perm          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Perm           ; }
Matthias Braun's avatar
Matthias Braun committed
963
int be_is_MemPerm       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_MemPerm        ; }
Sebastian Hack's avatar
Sebastian Hack committed
964
965
966
967
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
968
int be_is_SetSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SetSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
969
int be_is_AddSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_AddSP          ; }
970
int be_is_SubSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SubSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
971
972
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     ; }
973
974
975
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      ; }