#include "firm_config.h"
-#ifdef WITH_LIBCORE
-#include <libcore/lc_opts.h>
-#endif
-
#include "firm_types.h"
#include "bitset.h"
#include "bearch_t.h"
#include "be_t.h"
#include "bemachine.h"
+#include "beirg.h"
struct _be_node_factory_t;
* Different types of register allocation requirements.
*/
typedef enum _arch_register_req_type_t {
- arch_register_req_type_none = 0, /**< No register requirement. */
-
- arch_register_req_type_normal = 1, /**< All registers in the class
- are allowed. */
-
- arch_register_req_type_limited = 2, /**< Only a real subset of
- the class is allowed. */
-
- arch_register_req_type_should_be_same = 4, /**< The register should be equal
- another one at the node. */
-
- arch_register_req_type_should_be_different = 8, /**< The register must be unequal
- to some other at the node. */
-
- arch_register_req_type_should_be_different_from_all = 16, /**< The register must be different from
- all in's at the node */
+ arch_register_req_type_none = 0, /**< No register requirement. */
+ arch_register_req_type_normal = 1, /**< All registers in the class are allowed. */
+ arch_register_req_type_limited = 2, /**< Only a real subset of the class is allowed. */
+ arch_register_req_type_should_be_same = 4, /**< The register should be equal another one at the node. */
+ arch_register_req_type_should_be_different = 8, /**< The register must be unequal to some other at the node. */
+ arch_register_req_type_should_be_different_from_all = 16, /**< The register must be different from all in's at the node */
} arch_register_req_type_t;
/**
* Certain node classes which are relevant for the register allocator.
*/
typedef enum _arch_irn_class_t {
- arch_irn_class_normal = 1 << 0,
- arch_irn_class_spill = 1 << 1,
- arch_irn_class_reload = 1 << 2,
- arch_irn_class_copy = 1 << 3,
- arch_irn_class_perm = 1 << 4,
- arch_irn_class_branch = 1 << 5,
- arch_irn_class_call = 1 << 6,
- arch_irn_class_const = 1 << 7,
- arch_irn_class_load = 1 << 8,
- arch_irn_class_store = 1 << 9,
- arch_irn_class_stackparam = 1 << 10,
+ arch_irn_class_normal = 1 << 0,
+ arch_irn_class_spill = 1 << 1,
+ arch_irn_class_reload = 1 << 2,
+ arch_irn_class_copy = 1 << 3,
+ arch_irn_class_perm = 1 << 4,
+ arch_irn_class_branch = 1 << 5,
+ arch_irn_class_call = 1 << 6,
+ arch_irn_class_const = 1 << 7,
+ arch_irn_class_load = 1 << 8,
+ arch_irn_class_store = 1 << 9,
+ arch_irn_class_stackparam = 1 << 10,
} arch_irn_class_t;
/**
* @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).
+ * (-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.
*/
* 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 has a stack frame entity.
+ * @return The entity on the stack frame or NULL, if the node does not have a
+ * stack frame entity.
*/
ir_entity *(*get_frame_entity)(const void *self, const ir_node *irn);
#define arch_irn_is(env, irn, flag) ((arch_irn_get_flags(env, irn) & arch_irn_flags_ ## flag) != 0)
#define arch_irn_has_reg_class(env, irn, pos, cls) \
- ((cls) == arch_get_irn_reg_class(env, irn, pos))
+ ((cls) == arch_get_irn_reg_class(env, irn, pos))
#define arch_irn_consider_in_reg_alloc(env, cls, irn) \
(arch_irn_has_reg_class(env, irn, -1, cls) && !arch_irn_is(env, irn, ignore))
* @param birg A backend IRG session.
* @return A newly created code generator.
*/
- void *(*init)(const be_irg_t *birg);
+ void *(*init)(be_irg_t *birg);
/**
* Called before abi introduce.
* Backend may provide an own spiller.
* This spiller needs to spill all register classes.
*/
- void (*spill)(void *self, void *env);
+ void (*spill)(void *self, be_irg_t *birg);
/**
* Called before scheduling.
#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, env) _arch_cg_call_env(cg, env, spill)
+#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)
/**
* 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
+ */
+ void *(*init)(FILE *file_handle);
- /**
- * 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
- */
- void *(*init)(FILE *file_handle);
-
- /**
- * Free the isa instance.
- */
- void (*done)(void *self);
+ /**
+ * Free the isa instance.
+ */
+ void (*done)(void *self);
- /**
- * Get the the number of register classes in the isa.
- * @return The number of register classes.
- */
- int (*get_n_reg_class)(const void *self);
+ /**
+ * Get the the number of register classes in the isa.
+ * @return The number of register classes.
+ */
+ int (*get_n_reg_class)(const void *self);
- /**
- * Get the i-th register class.
- * @param i The number of the register class.
- * @return The register class.
- */
- const arch_register_class_t *(*get_reg_class)(const void *self, int i);
+ /**
+ * Get the i-th register class.
+ * @param i The number of the register class.
+ * @return The register class.
+ */
+ const arch_register_class_t *(*get_reg_class)(const void *self, int i);
- /**
- * 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 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.
- * @param method_type The type of the method (procedure) in question.
- * @param p The array of parameter locations to be filled.
- */
- void (*get_call_abi)(const void *self, ir_type *method_type, be_abi_call_t *abi);
+ /**
+ * Get the ABI restrictions for procedure calls.
+ * @param self The this pointer.
+ * @param method_type The type of the method (procedure) in question.
+ * @param p The array of parameter locations to be filled.
+ */
+ void (*get_call_abi)(const void *self, ir_type *method_type, be_abi_call_t *abi);
- /**
- * The irn handler for this architecture.
- * The irn handler is registered by the Firm back end
- * when the architecture is initialized.
- * (May be NULL).
- */
- const arch_irn_handler_t *(*get_irn_handler)(const void *self);
+ /**
+ * The irn handler for this architecture.
+ * The irn handler is registered by the Firm back end
+ * when the architecture is initialized.
+ * (May be NULL).
+ */
+ const arch_irn_handler_t *(*get_irn_handler)(const void *self);
- /**
- * 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 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 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 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);
+ /**
+ * 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);
+ /**
+ * 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.
- * The first dimension is the type, the second the allowed units of this type.
- * 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);
+ /**
+ * Returns an 2-dim array of execution units, @p irn can be executed on.
+ * The first dimension is the type, the second the allowed units of this type.
+ * 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 the abstract machine for this isa.
+ * @param self The isa object.
+ */
+ const be_machine_t *(*get_machine)(const void *self);
-#ifdef WITH_LIBCORE
- /**
- * Register command line options for this backend.
- * @param grp The root group.
- */
- void (*register_options)(lc_opt_entry_t *grp);
-#endif
+ /**
+ * Return an ordered list of irgs where code should be generated for.
+ * If NULL is returned, all irg will be taken into account and they will be
+ * generated in an arbitrary order.
+ * @param self The isa object.
+ * @param irgs A flexible array ARR_F of length 0 where the backend cann append the desired irgs.
+ * @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);
};
#define arch_isa_get_n_reg_class(isa) ((isa)->impl->get_n_reg_class(isa))
#define arch_isa_get_reg_class_alignment(isa, cls) ((isa)->impl->get_reg_class_alignment((isa), (cls)))
#define arch_isa_get_allowed_execution_units(isa, irn) ((isa)->impl->get_allowed_execution_units((isa), (irn)))
#define arch_isa_get_machine(isa) ((isa)->impl->get_machine((isa)))
+#define arch_isa_get_backend_irg_list(isa, irgs) ((isa)->impl->get_backend_irg_list((isa), (irgs)))
#define ARCH_MAX_HANDLERS 8
*/
extern const arch_irn_handler_t *arch_env_pop_irn_handler(arch_env_t *env);
+/**
+ * Register an instruction set architecture
+ */
+void be_register_isa_if(const char *name, const arch_isa_if_t *isa);
+
#endif /* _FIRM_BEARCH_H */