bearch.h 23.3 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
2
 * Copyright (C) 1995-2011 University of Karlsruhe.  All right reserved.
Christian Würdig's avatar
Christian Würdig committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * 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.
 */

Christian Würdig's avatar
Christian Würdig committed
20
21
22
23
24
25
26
/**
 * @file
 * @brief       Processor architecture specification.
 * @author      Sebastian Hack
 */
#ifndef FIRM_BE_BEARCH_H
#define FIRM_BE_BEARCH_H
27

28
29
#include <stdbool.h>

30
#include "firm_types.h"
Sebastian Hack's avatar
Sebastian Hack committed
31
#include "bitset.h"
Matthias Braun's avatar
Matthias Braun committed
32
#include "obst.h"
33
#include "raw_bitset.h"
34
#include "irop_t.h"
35

36
37
38
39
#include "be_types.h"
#include "beinfo.h"
#include "be.h"
#include "beirg.h"
40
#include "error.h"
41

42
43
44
45
46
47
48
/**
 * this constant is returned by the get_sp_bias functions if the stack
 * is reset (usually because the frame pointer is copied to the stack
 * pointer
 */
#define SP_BIAS_RESET      INT_MIN

Matthias Braun's avatar
Matthias Braun committed
49
50
typedef enum arch_register_class_flags_t {
	arch_register_class_flag_none      = 0,
Matthias Braun's avatar
Matthias Braun committed
51
	/** don't do automatic register allocation for this class */
52
	arch_register_class_flag_manual_ra = 1U << 0,
Matthias Braun's avatar
Matthias Braun committed
53
	/** the register models an abstract state (example: fpu rounding mode) */
54
	arch_register_class_flag_state     = 1U << 1
Matthias Braun's avatar
Matthias Braun committed
55
} arch_register_class_flags_t;
56
ENUM_BITSET(arch_register_class_flags_t)
Matthias Braun's avatar
Matthias Braun committed
57

58
typedef enum arch_register_type_t {
Michael Beck's avatar
Michael Beck committed
59
	arch_register_type_none         = 0,
60
	/** Do not consider this register when allocating. */
61
	arch_register_type_ignore       = 1U << 0,
62
63
	/** The emitter can choose an arbitrary register. The register fulfills any
	 * register constraints as long as the register class matches */
64
	arch_register_type_joker        = 1U << 1,
65
66
67
	/** This is just a virtual register. Virtual registers fulfill any register
	 * constraints as long as the register class matches. It is a allowed to
	 * have multiple definitions for the same virtual register at a point */
68
	arch_register_type_virtual      = 1U << 2,
69
70
	/** The register represents a state that should be handled by bestate
	 * code */
71
	arch_register_type_state        = 1U << 3,
Sebastian Hack's avatar
Sebastian Hack committed
72
} arch_register_type_t;
73
ENUM_BITSET(arch_register_type_t)
74

Sebastian Hack's avatar
Sebastian Hack committed
75
76
77
/**
 * Different types of register allocation requirements.
 */
78
typedef enum arch_register_req_type_t {
79
	/** No register requirement. */
80
	arch_register_req_type_none              = 0,
81
82
83
84
85
86
87
88
	/** All registers in the class are allowed. */
	arch_register_req_type_normal            = 1U << 0,
	/** Only a real subset of the class is allowed. */
	arch_register_req_type_limited           = 1U << 1,
	/** The register should be equal to another one at the node. */
	arch_register_req_type_should_be_same    = 1U << 2,
	/** The register must be unequal from some other at the node. */
	arch_register_req_type_must_be_different = 1U << 3,
89
	/** The registernumber should be aligned (in case of multiregister values)*/
90
	arch_register_req_type_aligned           = 1U << 4,
91
	/** ignore while allocating registers */
92
	arch_register_req_type_ignore            = 1U << 5,
93
94
95
	/** the output produces a new value for the stack pointer
	 * (this is not really a constraint but a marker to guide the stackpointer
	 * rewiring logic) */
96
	arch_register_req_type_produces_sp       = 1U << 6,
Sebastian Hack's avatar
Sebastian Hack committed
97
} arch_register_req_type_t;
98
ENUM_BITSET(arch_register_req_type_t)
99

Matthias Braun's avatar
Matthias Braun committed
100
101
extern const arch_register_req_t *arch_no_register_req;

Sebastian Hack's avatar
Sebastian Hack committed
102
/**
103
104
 * Print information about a register requirement in human readable form
 * @param F   output stream/file
Sebastian Hack's avatar
Sebastian Hack committed
105
106
 * @param req The requirements structure to format.
 */
107
108
void arch_dump_register_req(FILE *F, const arch_register_req_t *req,
                            const ir_node *node);
Sebastian Hack's avatar
Sebastian Hack committed
109

110
111
112
void arch_dump_register_reqs(FILE *F, const ir_node *node);
void arch_dump_reqs_and_registers(FILE *F, const ir_node *node);

Sebastian Hack's avatar
Sebastian Hack committed
113
/**
114
 * Node classification. Used for statistics and for detecting reload nodes.
Sebastian Hack's avatar
Sebastian Hack committed
115
 */
116
typedef enum arch_irn_class_t {
117
	arch_irn_class_none   = 0,
118
119
120
121
122
	arch_irn_class_spill  = 1 << 0,
	arch_irn_class_reload = 1 << 1,
	arch_irn_class_remat  = 1 << 2,
	arch_irn_class_copy   = 1 << 3,
	arch_irn_class_perm   = 1 << 4
Sebastian Hack's avatar
Sebastian Hack committed
123
} arch_irn_class_t;
124
ENUM_BITSET(arch_irn_class_t)
Sebastian Hack's avatar
Sebastian Hack committed
125

126
void arch_set_frame_offset(ir_node *irn, int bias);
127

128
ir_entity *arch_get_frame_entity(const ir_node *irn);
129
int        arch_get_sp_bias(ir_node *irn);
Sebastian Hack's avatar
Sebastian Hack committed
130

131
int             arch_get_op_estimated_cost(const ir_node *irn);
132
133
134
135
136
137
138
arch_inverse_t *arch_get_inverse(const ir_node *irn, int i,
                                 arch_inverse_t *inverse,
                                 struct obstack *obstack);
int             arch_possible_memory_operand(const ir_node *irn,
                                             unsigned int i);
void            arch_perform_memory_operand(ir_node *irn, ir_node *spill,
                                            unsigned int i);
139

Sebastian Hack's avatar
Sebastian Hack committed
140
/**
141
 * Get the register allocated for a value.
Sebastian Hack's avatar
Sebastian Hack committed
142
 */
143
const arch_register_t *arch_get_irn_register(const ir_node *irn);
144

Sebastian Hack's avatar
Sebastian Hack committed
145
/**
146
 * Assign register to a value
Sebastian Hack's avatar
Sebastian Hack committed
147
 */
148
void arch_set_irn_register(ir_node *irn, const arch_register_t *reg);
149

Sebastian Hack's avatar
Sebastian Hack committed
150
/**
151
 * Set the register for a certain output operand.
Sebastian Hack's avatar
Sebastian Hack committed
152
 */
153
void arch_set_irn_register_out(ir_node *irn, int pos, const arch_register_t *r);
Sebastian Hack's avatar
Sebastian Hack committed
154

155
156
const arch_register_t *arch_get_irn_register_out(const ir_node *irn, int pos);
const arch_register_t *arch_get_irn_register_in(const ir_node *irn, int pos);
157

Sebastian Hack's avatar
Sebastian Hack committed
158
/**
159
 * Get register constraints for an operand at position @p
Sebastian Hack's avatar
Sebastian Hack committed
160
 */
161
162
163
164
165
166
167
168
static inline const arch_register_req_t *arch_get_irn_register_req_in(
		const ir_node *node, int pos)
{
	const backend_info_t *info = be_get_info(node);
	if (info->in_reqs == NULL)
		return arch_no_register_req;
	return info->in_reqs[pos];
}
Sebastian Hack's avatar
Sebastian Hack committed
169
170

/**
171
 * Get register constraint for a produced result (the @p pos result)
Sebastian Hack's avatar
Sebastian Hack committed
172
 */
173
174
175
176
177
178
179
180
static inline const arch_register_req_t *arch_get_irn_register_req_out(
		const ir_node *node, int pos)
{
	const backend_info_t *info = be_get_info(node);
	if (info->out_infos == NULL)
		return arch_no_register_req;
	return info->out_infos[pos].req;
}
Sebastian Hack's avatar
Sebastian Hack committed
181

182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
static inline void arch_set_irn_register_req_out(ir_node *node, int pos,
		const arch_register_req_t *req)
{
	backend_info_t *info = be_get_info(node);
	assert(pos < (int)ARR_LEN(info->out_infos));
	info->out_infos[pos].req = req;
}

static inline void arch_set_irn_register_reqs_in(ir_node *node,
		const arch_register_req_t **reqs)
{
	backend_info_t *info = be_get_info(node);
	info->in_reqs = reqs;
}

static inline const arch_register_req_t **arch_get_irn_register_reqs_in(
		const ir_node *node)
{
	backend_info_t *info = be_get_info(node);
	return info->in_reqs;
}

const arch_register_req_t *arch_get_irn_register_req(const ir_node *node);
205

Sebastian Hack's avatar
Sebastian Hack committed
206
207
208
209
210
/**
 * Get the flags of a node.
 * @param irn The node.
 * @return The flags.
 */
211
arch_irn_flags_t arch_get_irn_flags(const ir_node *irn);
Sebastian Hack's avatar
Sebastian Hack committed
212

213
214
void arch_set_irn_flags(ir_node *node, arch_irn_flags_t flags);
void arch_add_irn_flags(ir_node *node, arch_irn_flags_t flags);
Sebastian Hack's avatar
Sebastian Hack committed
215

216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#define arch_irn_is(irn, flag) ((arch_get_irn_flags(irn) & arch_irn_flags_ ## flag) != 0)

static inline unsigned arch_get_irn_n_outs(const ir_node *node)
{
	backend_info_t *info = be_get_info(node);
	if (info->out_infos == NULL)
		return 0;

	return (unsigned)ARR_LEN(info->out_infos);
}

/**
 * Classify a node.
 * @param irn The node.
 * @return A classification of the node.
 */
arch_irn_class_t arch_irn_classify(const ir_node *irn);
Sebastian Hack's avatar
Sebastian Hack committed
233

Sebastian Hack's avatar
Sebastian Hack committed
234
/**
Sebastian Hack's avatar
Sebastian Hack committed
235
 * Initialize the architecture environment struct.
236
237
 * @param isa           The isa which shall be put into the environment.
 * @param file_handle   The file handle
Sebastian Hack's avatar
Sebastian Hack committed
238
239
 * @return The environment.
 */
240
extern arch_env_t *arch_env_init(const arch_isa_if_t *isa,
241
                                 be_main_env_t *main_env);
Sebastian Hack's avatar
Sebastian Hack committed
242

243
244
245
246
247
/**
 * Register an instruction set architecture
 */
void be_register_isa_if(const char *name, const arch_isa_if_t *isa);

248
249
250
251
/**
 * A register.
 */
struct arch_register_t {
Michael Beck's avatar
Michael Beck committed
252
253
254
255
256
257
258
	const char                  *name;         /**< The name of the register. */
	const arch_register_class_t *reg_class;    /**< The class of the register */
	unsigned short               index;        /**< The index of the register in
	                                                the class. */
	unsigned short               global_index; /** The global index this register
											       in the architecture. */
	arch_register_type_t         type;         /**< The type of the register. */
259
	/** register constraint allowing just this register */
260
	const arch_register_req_t   *single_req;
261
262
};

263
static inline const arch_register_class_t *arch_register_get_class(
264
		const arch_register_t *reg)
265
266
267
268
{
	return reg->reg_class;
}

269
static inline unsigned arch_register_get_index(const arch_register_t *reg)
270
271
272
273
{
	return reg->index;
}

274
static inline const char *arch_register_get_name(const arch_register_t *reg)
275
276
277
278
279
280
281
282
283
{
	return reg->name;
}

/**
 * A class of registers.
 * Like general purpose or floating point.
 */
struct arch_register_class_t {
284
285
286
287
288
289
290
291
	unsigned                     index;   /**< index of this register class */
	const char                  *name;    /**< The name of the register class.*/
	unsigned                     n_regs;  /**< Number of registers in this
	                                           class. */
	ir_mode                     *mode;    /**< The mode of the register class.*/
	const arch_register_t       *regs;    /**< The array of registers. */
	arch_register_class_flags_t  flags;   /**< register class flags. */
	const arch_register_req_t   *class_req;
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
};

/** return the number of registers in this register class */
#define arch_register_class_n_regs(cls) ((cls)->n_regs)

/** return the largest mode of this register class */
#define arch_register_class_mode(cls) ((cls)->mode)

/** return the name of this register class */
#define arch_register_class_name(cls) ((cls)->name)

/** return the index of this register class */
#define arch_register_class_index(cls)  ((cls)->index)

/** return the register class flags */
#define arch_register_class_flags(cls) ((cls)->flags)

309
static inline const arch_register_t *arch_register_for_index(
310
		const arch_register_class_t *cls, unsigned idx)
311
312
313
314
315
316
317
318
{
	assert(idx < cls->n_regs);
	return &cls->regs[idx];
}

/**
 * Convenience macro to check for set constraints.
 * @param req   A pointer to register requirements.
319
320
 * @param kind  The kind of constraint to check for
 *              (see arch_register_req_type_t).
321
322
323
324
325
326
327
328
329
 * @return      1, If the kind of constraint is present, 0 if not.
 */
#define arch_register_req_is(req, kind) \
	(((req)->type & (arch_register_req_type_ ## kind)) != 0)

/**
 * Expresses requirements to register allocation for an operand.
 */
struct arch_register_req_t {
330
331
332
	arch_register_req_type_t     type; /**< The type of the constraint. */
	const arch_register_class_t *cls;  /**< The register class this constraint
	                                        belongs to. */
333
334
335
336
337
338
	const unsigned *limited;            /**< allowed register bitset */
	unsigned other_same;                /**< Bitmask of ins which should use the
	                                         same register (should_be_same). */
	unsigned other_different;           /**< Bitmask of ins which shall use a
	                                         different register
	                                         (must_be_different) */
339
340
	unsigned char width;                /**< specifies how many sequential
	                                         registers are required */
341
342
};

343
344
static inline bool reg_reqs_equal(const arch_register_req_t *req1,
                                  const arch_register_req_t *req2)
345
346
{
	if (req1 == req2)
347
		return true;
348

Christoph Mallon's avatar
Christoph Mallon committed
349
350
351
352
353
	if (req1->type              != req2->type            ||
	    req1->cls               != req2->cls             ||
	    req1->other_same        != req2->other_same      ||
	    req1->other_different   != req2->other_different ||
	    (req1->limited != NULL) != (req2->limited != NULL))
354
		return false;
355
356

	if (req1->limited != NULL) {
Christoph Mallon's avatar
Christoph Mallon committed
357
		size_t const n_regs = arch_register_class_n_regs(req1->cls);
358
		if (!rbitsets_equal(req1->limited, req2->limited, n_regs))
359
			return false;
360
361
	}

362
	return true;
363
364
365
366
367
368
369
370
371
}

/**
 * An inverse operation returned by the backend
 */
struct arch_inverse_t {
	int      n;       /**< count of nodes returned in nodes array */
	int      costs;   /**< costs of this remat */

372
373
	/** nodes for this inverse operation. shall be in schedule order.
	 * last element is the target value */
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
	ir_node  **nodes;
};

struct arch_irn_ops_t {

	/**
	 * Classify the node.
	 * @param irn The node.
	 * @return A classification.
	 */
	arch_irn_class_t (*classify)(const ir_node *irn);

	/**
	 * Get the entity on the stack frame this node depends on.
	 * @param irn  The node in question.
389
390
	 * @return The entity on the stack frame or NULL, if the node does not have
	 *         a stack frame entity.
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
	 */
	ir_entity *(*get_frame_entity)(const ir_node *irn);

	/**
	 * Set the offset of a node carrying an entity on the stack frame.
	 * @param irn  The node.
	 * @param offset The offset of the node's stack frame entity.
	 */
	void (*set_frame_offset)(ir_node *irn, int offset);

	/**
	 * Returns the delta of the stackpointer for nodes that increment or
	 * decrement the stackpointer with a constant value. (push, pop
	 * nodes on most architectures).
	 * A positive value stands for an expanding stack area, a negative value for
	 * a shrinking one.
	 *
	 * @param irn       The node
	 * @return          0 if the stackpointer is not modified with a constant
	 *                  value, otherwise the increment/decrement value
	 */
	int (*get_sp_bias)(const ir_node *irn);

	/**
	 * Returns an inverse operation which yields the i-th argument
	 * of the given node as result.
	 *
	 * @param irn       The original operation
419
420
	 * @param i         Index of the argument we want the inverse operation to
	 *                  yield
421
	 * @param inverse   struct to be filled with the resulting inverse op
422
423
	 * @param obstack   The obstack to use for allocation of the returned nodes
	 *                  array
424
425
	 * @return          The inverse operation or NULL if operation invertible
	 */
426
427
428
	arch_inverse_t *(*get_inverse)(const ir_node *irn, int i,
	                               arch_inverse_t *inverse,
	                               struct obstack *obstack);
429
430
431
432
433
434
435
436
437
438

	/**
	 * Get the estimated cycle count for @p irn.
	 *
	 * @param irn  The node.
	 * @return     The estimated cycle count for this operation
	 */
	int (*get_op_estimated_cost)(const ir_node *irn);

	/**
439
440
	 * Asks the backend whether operand @p i of @p irn can be loaded form memory
	 * internally
441
442
	 *
	 * @param irn  The node.
443
444
	 * @param i    Index of the argument we would like to know whether @p irn
	 *             can load it form memory internally
445
446
447
448
449
450
451
452
453
454
455
	 * @return     nonzero if argument can be loaded or zero otherwise
	 */
	int (*possible_memory_operand)(const ir_node *irn, unsigned int i);

	/**
	 * Ask the backend to assimilate @p reload of operand @p i into @p irn.
	 *
	 * @param irn    The node.
	 * @param spill  The spill.
	 * @param i      The position of the reload.
	 */
456
457
	void (*perform_memory_operand)(ir_node *irn, ir_node *spill,
	                               unsigned int i);
458
459
460
461
462
463
464
465
466
467
468
};

/**
 * Architecture interface.
 */
struct arch_isa_if_t {
	/**
	 * Initialize the isa interface.
	 * @param file_handle  the file handle to write the output to
	 * @return a new isa instance
	 */
469
	arch_env_t *(*init)(const be_main_env_t *env);
470

471
472
473
474
475
476
	/**
	 * lowers current program for target. See the documentation for
	 * be_lower_for_target() for details.
	 */
	void (*lower_for_target)(void);

477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
	/**
	 * Free the isa instance.
	 */
	void (*done)(void *self);

	/**
	 * Called directly after initialization. Backend should handle all
	 * intrinsics here.
	 */
	void (*handle_intrinsics)(void);

	/**
	 * Get the ABI restrictions for procedure calls.
	 * @param self        The this pointer.
	 * @param call_type   The call type of the method (procedure) in question.
	 * @param p           The array of parameter locations to be filled.
	 */
494
495
	void (*get_call_abi)(const void *self, ir_type *call_type,
	                     be_abi_call_t *abi);
496
497
498
499
500
501
502
503
504
505

	/**
	 * A "static" function, returns the frontend settings
	 * needed for this backend.
	 */
	const backend_params *(*get_params)(void);

	/**
	 * mark node as rematerialized
	 */
506
	void (*mark_remat)(ir_node *node);
507
508
509
510
511
512

	/**
	 * parse an assembler constraint part and set flags according to its nature
	 * advances the *c pointer to point to the last parsed character (so if you
	 * parse a single character don't advance c)
	 */
513
	asm_constraint_flags_t (*parse_asm_constraint)(const char **c);
514
515
516
517
518

	/**
	 * returns true if the string is a valid clobbered (register) in this
	 * backend
	 */
519
	int (*is_valid_clobber)(const char *clobber);
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559

	/**
	 * Initialize the code generator.
	 * @param irg  A graph
	 * @return     A newly created code generator.
	 */
	void (*init_graph)(ir_graph *irg);

	/**
	 * return node used as base in pic code addresses
	 */
	ir_node* (*get_pic_base)(ir_graph *irg);

	/**
	 * Called before abi introduce.
	 */
	void (*before_abi)(ir_graph *irg);

	/**
	 * Called, when the graph is being normalized.
	 */
	void (*prepare_graph)(ir_graph *irg);

	/**
	 * Called before register allocation.
	 */
	void (*before_ra)(ir_graph *irg);

	/**
	 * Called directly before done is called. This should be the last place
	 * where the irg is modified.
	 */
	void (*finish)(ir_graph *irg);

	/**
	 * Called after everything happened. This call should emit the final
	 * assembly code but avoid changing the irg.
	 * The code generator must also be de-allocated here.
	 */
	void (*emit)(ir_graph *irg);
560
561
562

	/**
	 * Checks if the given register is callee/caller saved.
563
	 * @deprecated, only necessary if backend still uses beabi functions
564
565
	 */
	int (*register_saved_by)(const arch_register_t *reg, int callee);
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586

	/**
	 * Create a spill instruction. We assume that spill instructions
	 * do not need any additional registers and do not affect cpu-flags in any
	 * way.
	 * Construct a sequence of instructions after @p after (the resulting nodes
	 * are already scheduled).
	 * Returns a mode_M value which is used as input for a reload instruction.
	 */
	ir_node *(*new_spill)(ir_node *value, ir_node *after);

	/**
	 * Create a reload instruction. We assume that reload instructions do not
	 * need any additional registers and do not affect cpu-flags in any way.
	 * Constructs a sequence of instruction before @p before (the resulting
	 * nodes are already scheduled). A rewiring of users is not performed in
	 * this function.
	 * Returns a value representing the restored value.
	 */
	ir_node *(*new_reload)(ir_node *value, ir_node *spilled_value,
	                       ir_node *before);
587
588
589
590
591
592
593
};

#define arch_env_done(env)                             ((env)->impl->done(env))
#define arch_env_handle_intrinsics(env)                \
	do { if((env)->impl->handle_intrinsics != NULL) (env)->impl->handle_intrinsics(); } while(0)
#define arch_env_get_call_abi(env,tp,abi)              ((env)->impl->get_call_abi((env), (tp), (abi)))
#define arch_env_get_params(env)                       ((env)->impl->get_params())
594
#define arch_env_get_allowed_execution_units(env,irn)  ((env)->impl->get_allowed_execution_units((irn)))
595
#define arch_env_get_machine(env)                      ((env)->impl->get_machine(env))
596
597
#define arch_env_parse_asm_constraint(env,c)           ((env)->impl->parse_asm_constraint((c))
#define arch_env_is_valid_clobber(env,clobber)         ((env)->impl->is_valid_clobber((clobber))
598
#define arch_env_mark_remat(env,node) \
599
	do { if ((env)->impl->mark_remat != NULL) (env)->impl->mark_remat((node)); } while(0)
600

601
602
603
#define arch_env_new_spill(env,value,after)            ((env)->impl->new_spill(value, after))
#define arch_env_new_reload(env,value,spilled,before)  ((env)->impl->new_reload(value, spilled, before))

604
605
606
607
608
/**
 * ISA base class.
 */
struct arch_env_t {
	const arch_isa_if_t   *impl;
609
610
	unsigned               n_registers;      /**< number of registers */
	const arch_register_t *registers;        /**< register array */
611
612
	unsigned               n_register_classes; /**< number of register classes*/
	const arch_register_class_t *register_classes; /**< register classes */
613
614
615
616
617
618
619
620
	const arch_register_t *sp;               /**< The stack pointer register. */
	const arch_register_t *bp;               /**< The base pointer register. */
	const arch_register_class_t *link_class; /**< The static link pointer
	                                              register class. */
	int                    stack_alignment;  /**< power of 2 stack alignment */
	const be_main_env_t   *main_env;         /**< the be main environment */
	int                    spill_cost;       /**< cost for a be_Spill node */
	int                    reload_cost;      /**< cost for a be_Reload node */
621
	bool                   custom_abi : 1;   /**< backend does all abi handling
622
623
	                                              and does not need the generic
	                                              stuff from beabi.h/.c */
624
625
626
627
};

static inline bool arch_irn_is_ignore(const ir_node *irn)
{
628
629
	const arch_register_req_t *req = arch_get_irn_register_req(irn);
	return req->type & arch_register_req_type_ignore;
630
631
}

632
633
static inline bool arch_irn_consider_in_reg_alloc(
		const arch_register_class_t *cls, const ir_node *node)
634
{
635
	const arch_register_req_t *req = arch_get_irn_register_req(node);
636
637
638
	return
		req->cls == cls &&
		!(req->type & arch_register_req_type_ignore);
639
640
}

641
642
643
644
645
646
/**
 * Iterate over all values defined by an instruction.
 * Only looks at values in a certain register class where the requirements
 * are not marked as ignore.
 * Executes @p code for each definition.
 */
647
#define be_foreach_definition_(node, cls, value, code)                     \
648
649
650
651
652
653
	do {                                                                   \
	if (get_irn_mode(node) == mode_T) {                                    \
		const ir_edge_t *edge_;                                            \
		foreach_out_edge(node, edge_) {                                    \
			const arch_register_req_t *req_;                               \
			value = get_edge_src_irn(edge_);                               \
654
			req_  = arch_get_irn_register_req(value);                      \
655
656
657
658
659
			if (req_->cls != cls)                                          \
				continue;                                                  \
			code                                                           \
		}                                                                  \
	} else {                                                               \
660
		const arch_register_req_t *req_ = arch_get_irn_register_req(node); \
661
		value = node;                                                      \
662
		if (req_->cls == cls) {                                            \
663
664
665
666
667
			code                                                           \
		}                                                                  \
	}                                                                      \
	} while (0)

668
669
670
671
672
673
674
#define be_foreach_definition(node, cls, value, code)                      \
	be_foreach_definition_(node, cls, value,                               \
		if (req_->type & arch_register_req_type_ignore)                    \
			continue;                                                      \
		code                                                               \
	)

675
676
677
678
679
680
681
682
683
684
static inline const arch_register_class_t *arch_get_irn_reg_class(
		const ir_node *node)
{
	const arch_register_req_t *req = arch_get_irn_register_req(node);
	return req->cls;
}

bool arch_reg_is_allocatable(const arch_register_req_t *req,
                             const arch_register_t *reg);

685
#endif