bearch_t.h 18.1 KB
Newer Older
Christian Würdig's avatar
Christian Würdig committed
1
/*
Michael Beck's avatar
Michael Beck committed
2
 * Copyright (C) 1995-2008 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
27
/**
 * @file
 * @brief       Processor architecture specification - internal data structures.
 * @author      Sebastian Hack
 * @version     $Id$
 */
#ifndef FIRM_BE_BEARCH_T_H
#define FIRM_BE_BEARCH_T_H
Matthias Braun's avatar
Matthias Braun committed
28
29
30
31
32
33
34
35

#include "bearch.h"

#include "belistsched.h"
#include "beilpsched.h"
#include "bemachine.h"
#include "beirg.h"
#include "beabi.h"
Matthias Braun's avatar
Matthias Braun committed
36
#include "raw_bitset.h"
Matthias Braun's avatar
Matthias Braun committed
37
38
39
40
41
42
43

/**
 * A register.
 */
struct arch_register_t {
	const char                  *name;        /**< The name of the register. */
	const arch_register_class_t *reg_class;   /**< The class the register belongs to. */
44
	unsigned                    index;        /**< The index of the register in the class. */
Matthias Braun's avatar
Matthias Braun committed
45
46
47
48
49
50
51
52
53
54
	arch_register_type_t        type;         /**< The type of the register. */
	void                        *data;        /**< Custom data. */
};

static INLINE const arch_register_class_t *
_arch_register_get_class(const arch_register_t *reg)
{
	return reg->reg_class;
}

55
static INLINE
56
unsigned _arch_register_get_index(const arch_register_t *reg)
Matthias Braun's avatar
Matthias Braun committed
57
58
59
60
{
	return reg->index;
}

61
62
static INLINE
const char *_arch_register_get_name(const arch_register_t *reg)
Matthias Braun's avatar
Matthias Braun committed
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
{
	return reg->name;
}

#define arch_register_get_class(reg)      _arch_register_get_class(reg)
#define arch_register_get_index(reg)      _arch_register_get_index(reg)
#define arch_register_get_name(reg)       _arch_register_get_name(reg)

/**
 * Convenience macro to check for register type.
 * @param req   A pointer to register.
 * @param kind  The kind of type to check for (see arch_register_type_t).
 * @return      1, If register is of given kind, 0 if not.
 */
#define arch_register_type_is(reg, kind) \
  (((reg)->type & arch_register_type_ ## kind) != 0)

/**
 * A class of registers.
 * Like general purpose or floating point.
 */
struct arch_register_class_t {
85
	unsigned                     index;  /**< index of this register class */
Matthias Braun's avatar
Matthias Braun committed
86
	const char                  *name;   /**< The name of the register class.*/
87
	unsigned                     n_regs; /**< Number of registers in this
Matthias Braun's avatar
Matthias Braun committed
88
89
90
	                                          class. */
	ir_mode                     *mode;   /**< The mode of the register class.*/
	const arch_register_t       *regs;   /**< The array of registers. */
Matthias Braun's avatar
Matthias Braun committed
91
	arch_register_class_flags_t  flags;  /**< register class flags. */
Matthias Braun's avatar
Matthias Braun committed
92
93
94
95
96
97
98
99
100
101
102
};

/** 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)

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

Matthias Braun's avatar
Matthias Braun committed
106
107
108
/** return the register class flags */
#define arch_register_class_flags(cls) ((cls)->flags)

Matthias Braun's avatar
Matthias Braun committed
109
static INLINE const arch_register_t *
110
_arch_register_for_index(const arch_register_class_t *cls, unsigned idx)
Matthias Braun's avatar
Matthias Braun committed
111
{
112
	assert(idx < cls->n_regs);
Matthias Braun's avatar
Matthias Braun committed
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
	return &cls->regs[idx];
}

#define arch_register_for_index(cls, idx)   _arch_register_for_index(cls, idx)

/**
 * Convenience macro to check for set constraints.
 * @param req   A pointer to register requirements.
 * @param kind  The kind of constraint to check for (see arch_register_req_type_t).
 * @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 {
	arch_register_req_type_t type;      /**< The type of the constraint. */
	const arch_register_class_t *cls;   /**< The register class this constraint belongs to. */

	const unsigned *limited;            /**< allowed register bitset */

136
137
138
139
140
	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) */
Matthias Braun's avatar
Matthias Braun committed
141
142
};

Matthias Braun's avatar
Matthias Braun committed
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
static INLINE int reg_reqs_equal(const arch_register_req_t *req1,
                                 const arch_register_req_t *req2)
{
	if (req1 == req2)
		return 1;

	if (req1->type != req2->type
			|| req1->cls != req2->cls
			|| req1->other_same != req2->other_same
			|| req1->other_different != req2->other_different)
		return 0;

	if (req1->limited != NULL) {
		size_t n_regs;

		if (req2->limited == NULL)
			return 0;

		n_regs = arch_register_class_n_regs(req1->cls);
		if (!rbitset_equal(req1->limited, req2->limited, n_regs))
			return 0;
	}

	return 1;
}

Matthias Braun's avatar
Matthias Braun committed
169
170
171
172
173
174
175
176
177
178
179
180
181
/**
 * 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 */

	/**< nodes for this inverse operation. shall be in
	 *  schedule order. last element is the target value
	 */
	ir_node  **nodes;
};

Matthias Braun's avatar
Matthias Braun committed
182
struct arch_irn_ops_t {
Matthias Braun's avatar
Matthias Braun committed
183
184
185
186
187
188
189
190
191
192

	/**
  	 * Get the register requirements for a given operand.
	 * @param self The self pointer.
	 * @param irn The node.
	 * @param pos The operand's position
	 *        (-1 for the result of the node, 0..n for the input operands).
	 * @return    The register requirements for the selected operand.
	 *            The pointer returned is never NULL.
	 */
193
	const arch_register_req_t *(*get_irn_reg_req)(const ir_node *irn, int pos);
Matthias Braun's avatar
Matthias Braun committed
194
195
196
197
198
199
200
201

	/**
	 * Set the register for an output operand.
	 * @param irn The node.
	 * @param reg The register allocated to that operand.
	 * @note      If the operand is not a register operand,
	 *            the call is ignored.
	 */
202
	void (*set_irn_reg)(ir_node *irn, const arch_register_t *reg);
Matthias Braun's avatar
Matthias Braun committed
203
204
205
206
207
208
209
210
211

	/**
	 * Get the register allocated for an output operand.
	 * @param irn The node.
	 * @return    The register allocated at that operand. NULL, if
	 *            the operand was no register operand or
	 *            @c arch_register_invalid, if no register has yet been
	 *            allocated for this node.
	 */
212
	const arch_register_t *(*get_irn_reg)(const ir_node *irn);
Matthias Braun's avatar
Matthias Braun committed
213
214
215
216
217
218

	/**
	 * Classify the node.
	 * @param irn The node.
	 * @return A classification.
	 */
219
	arch_irn_class_t (*classify)(const ir_node *irn);
Matthias Braun's avatar
Matthias Braun committed
220
221
222
223
224
225
226

	/**
	 * Get the flags of a node.
	 * @param self The irn ops themselves.
	 * @param irn The node.
	 * @return A set of flags.
	 */
227
	arch_irn_flags_t (*get_flags)(const ir_node *irn);
Matthias Braun's avatar
Matthias Braun committed
228
229
230
231
232
233
234
235

	/**
	 * Get the entity on the stack frame this node depends on.
	 * @param self The this pointer.
	 * @param irn  The node in question.
	 * @return The entity on the stack frame or NULL, if the node does not have a
	 *         stack frame entity.
	 */
236
	ir_entity *(*get_frame_entity)(const ir_node *irn);
Matthias Braun's avatar
Matthias Braun committed
237
238
239
240
241
242
243

	/**
	 * Set the entity on the stack frame this node depends on.
	 * @param self The this pointer.
	 * @param irn  The node in question.
	 * @param ent  The entity to set
	 */
244
	void (*set_frame_entity)(ir_node *irn, ir_entity *ent);
Matthias Braun's avatar
Matthias Braun committed
245
246
247
248
249
250
251

	/**
	 * Set the offset of a node carrying an entity on the stack frame.
	 * @param self The this pointer.
	 * @param irn  The node.
	 * @param offset The offset of the node's stack frame entity.
	 */
252
	void (*set_frame_offset)(ir_node *irn, int offset);
Matthias Braun's avatar
Matthias Braun committed
253
254
255
256
257
258
259
260
261
262
263
264
265

	/**
	 * 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 self      The this pointer
	 * @param irn       The node
	 * @return          0 if the stackpointer is not modified with a constant
	 *                  value, otherwise the increment/decrement value
	 */
266
	int (*get_sp_bias)(const ir_node *irn);
Matthias Braun's avatar
Matthias Braun committed
267
268
269
270
271
272
273
274
275
276
277
278

	/**
	 * Returns an inverse operation which yields the i-th argument
	 * of the given node as result.
	 *
	 * @param self      The this pointer.
	 * @param irn       The original operation
	 * @param i         Index of the argument we want the inverse operation to yield
	 * @param inverse   struct to be filled with the resulting inverse op
	 * @param obstack   The obstack to use for allocation of the returned nodes array
	 * @return          The inverse operation or NULL if operation invertible
	 */
279
	arch_inverse_t *(*get_inverse)(const ir_node *irn, int i, arch_inverse_t *inverse, struct obstack *obstack);
Matthias Braun's avatar
Matthias Braun committed
280
281
282
283
284
285
286
287
288

	/**
	 * Get the estimated cycle count for @p irn.
	 *
	 * @param self The this pointer.
	 * @param irn  The node.
	 *
	 * @return     The estimated cycle count for this operation
	 */
289
	int (*get_op_estimated_cost)(const ir_node *irn);
Matthias Braun's avatar
Matthias Braun committed
290
291
292
293
294
295
296
297
298
299

	/**
	 * Asks the backend whether operand @p i of @p irn can be loaded form memory internally
	 *
	 * @param self The this pointer.
	 * @param irn  The node.
	 * @param i    Index of the argument we would like to know whether @p irn can load it form memory internally
	 *
	 * @return     nonzero if argument can be loaded or zero otherwise
	 */
300
	int (*possible_memory_operand)(const ir_node *irn, unsigned int i);
Matthias Braun's avatar
Matthias Braun committed
301
302
303
304
305
306
307
308
309

	/**
	 * Ask the backend to assimilate @p reload of operand @p i into @p irn.
	 *
	 * @param self   The this pointer.
	 * @param irn    The node.
	 * @param spill  The spill.
	 * @param i      The position of the reload.
	 */
310
	void (*perform_memory_operand)(ir_node *irn, ir_node *spill, unsigned int i);
Matthias Braun's avatar
Matthias Braun committed
311
312
313
314
315
316
317
318
319
320
321
322
323
};

/**
 * The code generator interface.
 */
struct arch_code_generator_if_t {
	/**
	 * Initialize the code generator.
	 * @param birg A backend IRG session.
	 * @return     A newly created code generator.
	 */
	void *(*init)(be_irg_t *birg);

324
325
326
327
328
	/**
	 * return node used as base in pic code addresses
	 */
	ir_node* (*get_pic_base)(void *self);

Matthias Braun's avatar
Matthias Braun committed
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
	/**
	 * Called before abi introduce.
	 */
	void (*before_abi)(void *self);

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

	/**
	 * Backend may provide an own spiller.
	 * This spiller needs to spill all register classes.
	 */
	void (*spill)(void *self, be_irg_t *birg);

	/**
	 * Called before scheduling.
	 */
	void (*before_sched)(void *self);

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

	/**
	 * Called after register allocation.
	 */
	void (*after_ra)(void *self);

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

	/**
	 * 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 (*done)(void *self);
};

/**
 * helper macro: call function func from the code generator
 * if it's implemented.
 */
#define _arch_cg_call(cg, func) \
do { \
	if((cg)->impl->func) \
		(cg)->impl->func(cg); \
} while(0)

#define _arch_cg_call_env(cg, env, func) \
do { \
	if((cg)->impl->func) \
		(cg)->impl->func(cg, env); \
} while(0)

#define arch_code_generator_before_abi(cg)      _arch_cg_call(cg, before_abi)
#define arch_code_generator_prepare_graph(cg)   _arch_cg_call(cg, prepare_graph)
#define arch_code_generator_before_sched(cg)    _arch_cg_call(cg, before_sched)
#define arch_code_generator_before_ra(cg)       _arch_cg_call(cg, before_ra)
#define arch_code_generator_after_ra(cg)        _arch_cg_call(cg, after_ra)
#define arch_code_generator_finish(cg)          _arch_cg_call(cg, finish)
#define arch_code_generator_done(cg)            _arch_cg_call(cg, done)
#define arch_code_generator_spill(cg, birg)     _arch_cg_call_env(cg, birg, spill)
#define arch_code_generator_has_spiller(cg)     ((cg)->impl->spill != NULL)
399
400
#define arch_code_generator_get_pic_base(cg)    \
	((cg)->impl->get_pic_base != NULL ? (cg)->impl->get_pic_base(cg) : NULL)
Matthias Braun's avatar
Matthias Braun committed
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418

/**
 * Code generator base class.
 */
struct arch_code_generator_t {
	const arch_code_generator_if_t *impl;
};

/**
 * Architecture interface.
 */
struct arch_isa_if_t {
	/**
	 * Initialize the isa interface.
	 * @param file_handle  the file handle to write the output to
	 * @param main_env     the be main environment
	 * @return a new isa instance
	 */
419
	arch_env_t *(*init)(FILE *file_handle);
Matthias Braun's avatar
Matthias Braun committed
420
421
422
423
424
425
426
427
428
429

	/**
	 * Free the isa instance.
	 */
	void (*done)(void *self);

	/**
	 * Get the the number of register classes in the isa.
	 * @return The number of register classes.
	 */
430
	unsigned (*get_n_reg_class)(const void *self);
Matthias Braun's avatar
Matthias Braun committed
431
432
433
434
435
436

	/**
	 * Get the i-th register class.
	 * @param i The number of the register class.
	 * @return The register class.
	 */
437
	const arch_register_class_t *(*get_reg_class)(const void *self, unsigned i);
Matthias Braun's avatar
Matthias Braun committed
438
439
440
441
442
443
444
445
446
447
448
449

	/**
	 * Get the register class which shall be used to store a value of a given mode.
	 * @param self The this pointer.
	 * @param mode The mode in question.
	 * @return A register class which can hold values of the given mode.
	 */
	const arch_register_class_t *(*get_reg_class_for_mode)(const void *self, const ir_mode *mode);

	/**
	 * Get the ABI restrictions for procedure calls.
	 * @param self        The this pointer.
450
	 * @param call_type   The call type of the method (procedure) in question.
Matthias Braun's avatar
Matthias Braun committed
451
452
	 * @param p           The array of parameter locations to be filled.
	 */
453
	void (*get_call_abi)(const void *self, ir_type *call_type, be_abi_call_t *abi);
Matthias Braun's avatar
Matthias Braun committed
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494

	/**
	 * Get the code generator interface.
	 * @param self The this pointer.
	 * @return     Some code generator interface.
	 */
	const arch_code_generator_if_t *(*get_code_generator_if)(void *self);

	/**
	 * Get the list scheduler to use. There is already a selector given, the
	 * backend is free to modify and/or ignore it.
	 *
	 * @param self     The isa object.
	 * @param selector The selector given by options.
	 * @return         The list scheduler selector.
	 */
	const list_sched_selector_t *(*get_list_sched_selector)(const void *self, list_sched_selector_t *selector);

	/**
	 * Get the ILP scheduler to use.
	 * @param self  The isa object.
	 * @return      The ILP scheduler selector
	 */
	const ilp_sched_selector_t *(*get_ilp_sched_selector)(const void *self);

	/**
	 * Get the necessary alignment for storing a register of given class.
	 * @param self  The isa object.
	 * @param cls   The register class.
	 * @return      The alignment in bytes.
	 */
	int (*get_reg_class_alignment)(const void *self, const arch_register_class_t *cls);

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

	/**
	 * Returns an 2-dim array of execution units, @p irn can be executed on.
495
496
	 * The first dimension is the type, the second the allowed units of this
	 * type.
Matthias Braun's avatar
Matthias Braun committed
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
	 * Each dimension is a NULL terminated list.
	 * @param self  The isa object.
	 * @param irn   The node.
	 * @return An array of allowed execution units.
	 *         exec_unit = {
	 *                       { unit1_of_tp1, ..., unitX1_of_tp1, NULL },
	 *                       ...,
	 *                       { unit1_of_tpY, ..., unitXn_of_tpY, NULL },
	 *                       NULL
	 *                     };
	 */
	const be_execution_unit_t ***(*get_allowed_execution_units)(const void *self, const ir_node *irn);

	/**
	 * Return the abstract machine for this isa.
	 * @param self  The isa object.
	 */
	const be_machine_t *(*get_machine)(const void *self);

	/**
	 * Return an ordered list of irgs where code should be generated for.
518
519
	 * If NULL is returned, all irg will be taken into account and they will be
	 * generated in an arbitrary order.
Matthias Braun's avatar
Matthias Braun committed
520
	 * @param self   The isa object.
Michael Beck's avatar
Michael Beck committed
521
	 * @param irgs   A flexible array ARR_F of length 0 where the backend can append the desired irgs.
Matthias Braun's avatar
Matthias Braun committed
522
523
524
525
526
	 * @return A flexible array ARR_F containing all desired irgs in the desired order.
	 */
	ir_graph **(*get_backend_irg_list)(const void *self, ir_graph ***irgs);
};

Michael Beck's avatar
Michael Beck committed
527
#define arch_env_done(env)                             ((env)->impl->done(env))
528
529
530
#define arch_env_get_n_reg_class(env)                  ((env)->impl->get_n_reg_class(env))
#define arch_env_get_reg_class(env,i)                  ((env)->impl->get_reg_class(env, i))
#define arch_env_get_reg_class_for_mode(env,mode)      ((env)->impl->get_reg_class_for_mode((env), (mode)))
Michael Beck's avatar
Michael Beck committed
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
#define arch_env_get_call_abi(env,tp,abi)              ((env)->impl->get_call_abi((env), (tp), (abi)))
#define arch_env_get_code_generator_if(env)            ((env)->impl->get_code_generator_if((env)))
#define arch_env_get_list_sched_selector(env,selector) ((env)->impl->get_list_sched_selector((env), (selector)))
#define arch_env_get_ilp_sched_selector(env)           ((env)->impl->get_ilp_sched_selector(env))
#define arch_env_get_reg_class_alignment(env,cls)      ((env)->impl->get_reg_class_alignment((env), (cls)))
#define arch_env_get_params(env)                       ((env)->impl->get_params())
#define arch_env_get_allowed_execution_units(env,irn)  ((env)->impl->get_allowed_execution_units((env), (irn)))
#define arch_env_get_machine(env)                      ((env)->impl->get_machine(env))
#define arch_env_get_backend_irg_list(env,irgs)        ((env)->impl->get_backend_irg_list((env), (irgs)))

/**
 * ISA base class.
 */
struct arch_env_t {
	const arch_isa_if_t   *impl;
546
547
548
549
550
551
552
	const arch_register_t *sp;              /** The stack pointer register. */
	const arch_register_t *bp;              /** The base pointer register. */
	int                    stack_dir;       /** -1 for decreasing, 1 for increasing. */
	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 */
Michael Beck's avatar
Michael Beck committed
553
554
555
556
557
};

#define arch_env_stack_dir(env)  ((env)->stack_dir)
#define arch_env_sp(env)         ((env)->sp)
#define arch_env_bp(env)         ((env)->bp)
Matthias Braun's avatar
Matthias Braun committed
558

Christian Würdig's avatar
Christian Würdig committed
559
#endif /* FIRM_BE_BEARCH_T_H */