benode.c 46.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
ir_op *op_be_RegParams;
ir_op *op_be_FrameAddr;
130
ir_op *op_be_Barrier;
Sebastian Hack's avatar
Sebastian Hack committed
131

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

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

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

148

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

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

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

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

171
172
173
174
175
176
177
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
178
179
180
181
182
183
184
185
186
/**
 * 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);

187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
	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
222
223
}

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

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

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

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

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

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

262
263
	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
264
	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);
265
	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
266
	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);
267
	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
268
	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);
269
	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);
270
	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
271
	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
272
	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);
273
	op_be_IncSP      = new_ir_op(beo_base + beo_IncSP,      "be_IncSP",      op_pin_state_pinned,     N, oparity_unary,    0, sizeof(be_stack_attr_t),   &be_node_op_ops);
Matthias Braun's avatar
Matthias Braun committed
274
	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);
275
	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);
276
	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);
277
278

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

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

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

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

	return a;
}
330

331
332
333
334
335
336
337
338
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);
}

339
int is_be_node(const ir_node *irn)
340
{
Sebastian Hack's avatar
Sebastian Hack committed
341
	return get_op_tag(get_irn_op(irn)) == &be_node_tag;
342
343
}

Sebastian Hack's avatar
Sebastian Hack committed
344
be_opcode_t be_get_irn_opcode(const ir_node *irn)
345
{
346
	return is_be_node(irn) ? (be_opcode_t) get_irn_opcode(irn) - beo_base : beo_NoBeOp;
347
348
}

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

	if(is_Proj(n)) {
363
364
365
366
367
368
369
		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
370
371
372
373
374
375
		return get_Proj_proj(n);
	}

	return 0;
}

Matthias Braun's avatar
Matthias Braun committed
376
static be_reg_data_t *retrieve_reg_data(const ir_node *node)
Sebastian Hack's avatar
Sebastian Hack committed
377
{
Matthias Braun's avatar
Matthias Braun committed
378
379
	be_node_attr_t *attr;
	int pos = 0;
Sebastian Hack's avatar
Sebastian Hack committed
380

Matthias Braun's avatar
Matthias Braun committed
381
382
383
	if(is_Proj(node)) {
		pos = get_Proj_proj(node);
		node = get_Proj_pred(node);
Sebastian Hack's avatar
Sebastian Hack committed
384
385
	}

Matthias Braun's avatar
Matthias Braun committed
386
387
388
	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
389

Matthias Braun's avatar
Matthias Braun committed
390
	return &attr->reg_data[pos];
Sebastian Hack's avatar
Sebastian Hack committed
391
392
}

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

401
402
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)
403
{
Matthias Braun's avatar
Matthias Braun committed
404
	be_frame_attr_t *a;
405
	ir_node         *in[2];
406
	ir_node         *res;
407

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

415
	be_node_set_reg_class(res, be_pos_Spill_frame, cls_frame);
416
	be_node_set_reg_class(res, be_pos_Spill_val, cls);
Sebastian Hack's avatar
Sebastian Hack committed
417
418
	return res;
}
419

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

437
ir_node *be_get_Reload_mem(const ir_node *irn)
Sebastian Hack's avatar
Sebastian Hack committed
438
439
{
	assert(be_is_Reload(irn));
Daniel Grund's avatar
Daniel Grund committed
440
	return get_irn_n(irn, be_pos_Reload_mem);
Sebastian Hack's avatar
Sebastian Hack committed
441
442
}

443
444
445
446
447
448
ir_node *be_get_Reload_frame(const ir_node *irn)
{
	assert(be_is_Reload(irn));
	return get_irn_n(irn, be_pos_Reload_frame);
}

449
450
451
452
453
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
454

455
456
457
458
459
ir_node *be_get_Spill_frame(const ir_node *irn)
{
	assert(be_is_Spill(irn));
	return get_irn_n(irn, be_pos_Spill_frame);
}
460

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

474
475
476
void be_Perm_reduce(ir_node *perm, int new_size, int *map)
{
	ir_graph *irg           = get_irn_irg(perm);
477
478
	int            arity    = get_irn_arity(perm);
	be_reg_data_t *old_data = alloca(arity * sizeof(old_data[0]));
479
	be_node_attr_t *attr    = get_irn_attr(perm);
480
	ir_node **new_in        = NEW_ARR_D(ir_node *, irg->obst, new_size);
481
482
483
484

	int i;

	assert(be_is_Perm(perm));
485
	assert(new_size <= arity);
486
487

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

	/* compose the new in array and set the new register data directly in place */
491
	for (i = 0; i < new_size; ++i) {
492
		int idx = map[i];
493
494
		new_in[i]         = get_irn_n(perm, idx);
		attr->reg_data[i] = old_data[idx];
495
496
497
498
499
	}

	set_irn_in(perm, new_size, new_in);
}

Matthias Braun's avatar
Matthias Braun committed
500
501
502
503
504
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);
505
506
	ir_node *irn;
	const arch_register_t *sp = arch_env->isa->sp;
Matthias Braun's avatar
Matthias Braun committed
507
	be_memperm_attr_t *attr;
508
	ir_node **real_in;
Matthias Braun's avatar
Matthias Braun committed
509

510
511
512
513
514
515
516
517
	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
518
	for(i = 0; i < n; ++i) {
519
		be_node_set_reg_class(irn, i + 1, cls_frame);
Matthias Braun's avatar
Matthias Braun committed
520
521
522
523
524
		be_node_set_reg_class(irn, OUT_POS(i), cls_frame);
	}

	attr = get_irn_attr(irn);

525
526
	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
527
528
529
530
531
532
533
	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
534
535
536
537
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
538
	arch_register_req_t *req;
539

Sebastian Hack's avatar
Sebastian Hack committed
540
	in[0] = op;
541
	res   = new_ir_node(NULL, irg, bl, op_be_Copy, get_irn_mode(op), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
542
543
544
	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
545
546
547
548

	req = get_req(res, OUT_POS(0));
	req->cls = cls;
	req->type = arch_register_req_type_should_be_same;
549
550
	req->other_same[0] =  0;
	req->other_same[1] = -1;
Matthias Braun's avatar
Matthias Braun committed
551

Sebastian Hack's avatar
Sebastian Hack committed
552
	return res;
553
554
}

555
556
557
558
ir_node *be_get_Copy_op(const ir_node *cpy) {
	return get_irn_n(cpy, be_pos_Copy_op);
}

559
560
561
562
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
563
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
564
{
Sebastian Hack's avatar
Sebastian Hack committed
565
	int i;
566
567
568
569
	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
570

Sebastian Hack's avatar
Sebastian Hack committed
571
	for(i = 0; i < n; ++i) {
572
573
574
		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
575
	}
576
577
578
579
580
581
582
583
584
585
586
587
588
	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
589
590
}

Michael Beck's avatar
Michael Beck committed
591
/* creates a be_Call */
592
593
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
594
{
595
596
	be_call_attr_t *a;
	int real_n = be_pos_Call_first_arg + n;
Sebastian Hack's avatar
Sebastian Hack committed
597
598
	ir_node *irn;
	ir_node **real_in;
Sebastian Hack's avatar
Sebastian Hack committed
599

600
601
602
603
604
	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
605

606
	irn = new_ir_node(dbg, irg, bl, op_be_Call, mode_T, real_n, real_in);
607
608
609
	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
610
	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
611
612
}

613
/* Gets the call entity or NULL if this is no static call. */
614
ir_entity *be_Call_get_entity(const ir_node *call) {
615
616
617
618
619
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	return a->ent;
}

620
/* Sets the call entity. */
621
void be_Call_set_entity(ir_node *call, ir_entity *ent) {
622
623
624
625
626
	be_call_attr_t *a = get_irn_attr(call);
	assert(be_is_Call(call));
	a->ent = ent;
}

627
628
629
630
631
632
633
634
635
636
637
638
639
640
/* 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;
}

641
/* Construct a new be_Return. */
642
643
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
644
{
645
	be_return_attr_t *a;
646
647
648
649
650
651
652
653
654
655
656
	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);
657
	a->num_ret_vals = n_res;
Sebastian Hack's avatar
Sebastian Hack committed
658

659
	return res;
Sebastian Hack's avatar
Sebastian Hack committed
660
661
}

662
663
664
665
666
667
668
/* 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;
}

669
670
671
672
673
674
675
676
677
678
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
679
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
680
{
Sebastian Hack's avatar
Sebastian Hack committed
681
682
	be_stack_attr_t *a;
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
683
	ir_node *in[1];
Sebastian Hack's avatar
Sebastian Hack committed
684
685

	in[0]     = old_sp;
Sebastian Hack's avatar
Sebastian Hack committed
686
	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
687
	a         = init_node_attr(irn, 1);
Sebastian Hack's avatar
Sebastian Hack committed
688
689
	a->offset = offset;

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

Sebastian Hack's avatar
Sebastian Hack committed
692
	/* Set output constraint to stack register. */
Sebastian Hack's avatar
Sebastian Hack committed
693
	be_node_set_reg_class(irn, 0, sp->reg_class);
694
	be_set_constr_single_reg(irn, BE_OUT_POS(0), sp);
Sebastian Hack's avatar
Sebastian Hack committed
695
	be_node_set_irn_reg(NULL, irn, sp);
Sebastian Hack's avatar
Sebastian Hack committed
696
697

	return irn;
Sebastian Hack's avatar
Sebastian Hack committed
698
}
Sebastian Hack's avatar
Sebastian Hack committed
699

Sebastian Hack's avatar
Sebastian Hack committed
700
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
701
{
Sebastian Hack's avatar
Sebastian Hack committed
702
	be_node_attr_t *a;
Sebastian Hack's avatar
Sebastian Hack committed
703
	ir_node *irn;
Sebastian Hack's avatar
Sebastian Hack committed
704
	ir_node *in[be_pos_AddSP_last];
705
	const arch_register_class_t *class;
Sebastian Hack's avatar
Sebastian Hack committed
706

Sebastian Hack's avatar
Sebastian Hack committed
707
708
	in[be_pos_AddSP_old_sp] = old_sp;
	in[be_pos_AddSP_size]   = sz;
Sebastian Hack's avatar
Sebastian Hack committed
709

710
711
	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
712

713
714
	be_node_set_flags(irn, OUT_POS(pn_be_AddSP_sp),
	                  arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Sebastian Hack's avatar
Sebastian Hack committed
715
716

	/* Set output constraint to stack register. */
717
718
	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));
719
720
721
722
723
	be_set_constr_single_reg(irn, OUT_POS(pn_be_AddSP_sp), sp);
	a->reg_data[pn_be_AddSP_sp].reg = sp;

	class = arch_register_get_class(sp);
	be_node_set_reg_class(irn, OUT_POS(pn_be_AddSP_res), class);
Sebastian Hack's avatar
Sebastian Hack committed
724
725
726
727

	return irn;
}

Michael Beck's avatar
Michael Beck committed
728
729
730
731
732
733
734
735
736
737
738
739
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);

740
741
	be_node_set_flags(irn, OUT_POS(pn_be_SubSP_sp),
	                  arch_irn_flags_ignore | arch_irn_flags_modify_sp);
Michael Beck's avatar
Michael Beck committed
742
743
744
745

	/* 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));
746
747
	be_set_constr_single_reg(irn, OUT_POS(pn_be_SubSP_sp), sp);
	a->reg_data[pn_be_SubSP_sp].reg = sp;
Michael Beck's avatar
Michael Beck committed
748
749
750
751

	return irn;
}

752
ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_outs)
Sebastian Hack's avatar
Sebastian Hack committed
753
{
754
755
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
756

757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
	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
775
	ir_node *proj;
776
777

	assert(be_is_RegParams(regparams));
Michael Beck's avatar
Michael Beck committed
778
	proj = new_r_Proj(irg, block, regparams, mode, n);
779
	add_register_req(regparams);
780
	be_set_constr_single_reg(regparams, BE_OUT_POS(n), reg);
781
782
	arch_set_irn_register(arch_env, proj, reg);

Michael Beck's avatar
Michael Beck committed
783
	/* TODO decide, whether we need to set ignore/modify sp flags here? */
784
785

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
786
787
}

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

794
	in[0]  = frame;
795
	irn    = new_ir_node(NULL, irg, bl, op_be_FrameAddr, get_irn_mode(frame), 1, in);
Sebastian Hack's avatar
Sebastian Hack committed
796
	a      = init_node_attr(irn, 1);
797
798
799
	a->ent = ent;
	a->offset = 0;
	be_node_set_reg_class(irn, 0, cls_frame);
Sebastian Hack's avatar
Sebastian Hack committed
800
	be_node_set_reg_class(irn, OUT_POS(0), cls_frame);
Michael Beck's avatar
Michael Beck committed
801
802

	return optimize_node(irn);
Sebastian Hack's avatar
Sebastian Hack committed
803
804
}

Matthias Braun's avatar
Matthias Braun committed
805
ir_node *be_get_FrameAddr_frame(const ir_node *node) {
Michael Beck's avatar
Michael Beck committed
806
807
808
809
	assert(be_is_FrameAddr(node));
	return get_irn_n(node, be_pos_FrameAddr_ptr);
}

Matthias Braun's avatar
Matthias Braun committed
810
811
812
813
814
815
ir_entity *be_get_FrameAddr_entity(const ir_node *node)
{
	const be_frame_attr_t *attr = get_irn_generic_attr_const(node);
	return attr->ent;
}

Sebastian Hack's avatar
Sebastian Hack committed
816
817
818
819
820
821
822
823
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
824
	init_node_attr(irn, n + 1);
Sebastian Hack's avatar
Sebastian Hack committed
825
826
827
828
829
830
831
832
833
834
835
836
837
838
	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);
}

839
840
841
842
843
844
845
846
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);
}

847
ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[])
Sebastian Hack's avatar
Sebastian Hack committed
848
{
849
850
	ir_node *res;
	int i;
Sebastian Hack's avatar
Sebastian Hack committed
851

852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
	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);
868

869
870
871
872
	ir_node *proj = new_r_Proj(irg, block, barrier, mode, n);
	add_register_req(barrier);

	return proj;
Sebastian Hack's avatar
Sebastian Hack committed
873
874
}

Sebastian Hack's avatar
Sebastian Hack committed
875
876
877
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
878
int be_is_CopyKeep      (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_CopyKeep       ; }
Sebastian Hack's avatar
Sebastian Hack committed
879
int be_is_Perm          (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Perm           ; }
Matthias Braun's avatar
Matthias Braun committed
880
int be_is_MemPerm       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_MemPerm        ; }
Sebastian Hack's avatar
Sebastian Hack committed
881
882
883
884
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
885
int be_is_AddSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_AddSP          ; }
886
int be_is_SubSP         (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_SubSP          ; }
Sebastian Hack's avatar
Sebastian Hack committed
887
int be_is_RegParams     (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_RegParams      ; }
888
int be_is_FrameAddr     (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_FrameAddr      ; }
889
int be_is_Barrier       (const ir_node *irn) { return be_get_irn_opcode(irn) == beo_Barrier        ; }
890
891
892
893
894

int be_has_frame_entity(const ir_node *irn)
{
	switch(be_get_irn_opcode(irn)) {
	case beo_Spill:
895
	case beo_Reload:
896
897
	case beo_FrameAddr:
		return 1;
898
899
	default:
		return 0;
900
901
902
	}
}

903
ir_entity *be_get_frame_entity(const ir_node *irn)
904
{
905
	if (be_has_frame_entity(irn)) {
906
907
908
909
910
		be_frame_attr_t *a = get_irn_attr(irn);
		return a->ent;
	}
	return NULL;
}
Sebastian Hack's avatar
Sebastian Hack committed
911

912
913
914
915
916
917
918
919
920
921
int be_get_frame_offset(const ir_node *irn)
{
	assert(is_be_node(irn));
	if (be_has_frame_entity(irn)) {
		be_frame_attr_t *a = get_irn_attr(irn);
		return a->offset;
	}
	return 0;
}

922
void be_set_MemPerm_in_entity(const ir_node *irn, int n, ir_entity *ent)
Matthias Braun's avatar
Matthias Braun committed
923
924
925
926
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
927
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
928
929
930
931

	attr->in_entities[n] = ent;
}

932
ir_entity* be_get_MemPerm_in_entity(const ir_node* irn, int n)
Matthias Braun's avatar
Matthias Braun committed
933
934
935
936
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
937
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
938
939
940
941

	return attr->in_entities[n];
}

942
void be_set_MemPerm_out_entity(const ir_node *irn, int n, ir_entity *ent)
Matthias Braun's avatar
Matthias Braun committed
943
944
945
946
{
	be_memperm_attr_t *attr = get_irn_attr(irn);

	assert(be_is_MemPerm(irn));
947
	assert(n < be_get_MemPerm_entity_arity(irn));
Matthias Braun's avatar
Matthias Braun committed
948
949
950
951

	attr->out_entities[n] = ent;
}

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

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

	return attr->out_entities[n];
}

962
963
964
965
966
int be_get_MemPerm_entity_arity(const ir_node *irn)
{
	return get_irn_arity(irn) - 1;
}

Matthias Braun's avatar
Matthias Braun committed
967
void be_set_constr_single_reg(ir_node *node, int pos, const arch_register_t *reg)
Sebastian Hack's avatar
Sebastian Hack committed
968
{
Matthias Braun's avatar
Matthias Braun committed
969
970
971
972
973
	arch_register_req_t *req = get_req(node, pos);
	const arch_register_class_t *cls = arch_register_get_class(reg);
	ir_graph *irg = get_irn_irg(node);
	struct obstack *obst = get_irg_obstack(irg);
	unsigned *limited_bitset;
Sebastian Hack's avatar
Sebastian Hack committed