-
#ifndef _FIRM_BEARCH_H
#define _FIRM_BEARCH_H
#include "irnode.h"
#include "irmode.h"
+#include "bitset.h"
#include "hashptr.h"
#include "fourcc.h"
#include "set.h"
#include "list.h"
#include "ident.h"
-struct _bitset_t;
-
typedef struct _arch_register_class_t arch_register_class_t;
typedef struct _arch_register_t arch_register_t;
typedef struct _arch_enum_t arch_enum_t;
struct _be_node_factory_t;
typedef enum _arch_register_type_t {
- arch_register_type_none = 0,
+ arch_register_type_none = 0,
arch_register_type_write_invariant,
- arch_register_type_caller_saved, /**< The register must be saved by the caller
- upon a function call. It thus can be overwritten
- in the called function. */
- arch_register_type_callee_saved, /**< The register must be saved by the called function,
- it thus survives a function call. */
- arch_register_type_ignore /**< Do not consider this register when allocating. */
+ arch_register_type_caller_saved, /**< The register must be saved by the caller
+ upon a function call. It thus can be overwritten
+ in the called function. */
+ arch_register_type_callee_saved, /**< The register must be saved by the called function,
+ it thus survives a function call. */
+ arch_register_type_ignore /**< Do not consider this register when allocating. */
} arch_register_type_t;
/**
*/
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. */
- int index; /**< The index of the register in the class. */
- arch_register_type_t type; /**< The type of the register. */
+ const arch_register_class_t *reg_class; /**< The class the register belongs to. */
+ int index; /**< The index of the register in the class. */
+ arch_register_type_t type; /**< The type of the register. */
void *data; /**< Custom data. */
};
* Like general purpose or floating point.
*/
struct _arch_register_class_t {
- const char *name; /**< The name of the register. */
- int n_regs; /**< Number of registers in this class. */
- const arch_register_t *regs; /**< The array of registers. */
+ const char *name; /**< The name of the register class. */
+ int n_regs; /**< Number of registers in this class. */
+ const arch_register_t *regs; /**< The array of registers. */
};
#define arch_register_class_n_regs(cls) ((cls)->n_regs)
* @param bs The bitset. May be NULL.
* @return The number of registers in the class.
*/
-extern int arch_register_class_put(const arch_register_class_t *cls,
- struct _bitset_t *bs);
+extern int arch_register_class_put(const arch_register_class_t *cls, bitset_t *bs);
static INLINE const arch_register_t *
_arch_register_for_index(const arch_register_class_t *cls, int idx)
{
- assert(0 <= idx && idx < cls->n_regs);
- return &cls->regs[idx];
+ assert(0 <= idx && idx < cls->n_regs);
+ return &cls->regs[idx];
}
#define arch_register_for_index(cls, idx) \
*/
struct _arch_immediate_t {
const char *name; /**< The name of the immediate. */
- ir_mode *mode; /**< The mode of the immediate. */
+ ir_mode *mode; /**< The mode of the immediate. */
};
/**
* The member of an enum.
*/
struct _arch_enum_member_t {
- arch_enum_t *enm; /**< The enum, this member belongs to. */
+ arch_enum_t *enm; /**< The enum, this member belongs to. */
};
/**
* eq, ...) some other special attributes of an instruction.
*/
struct _arch_enum_t {
- int n_members; /**< The number of members in this enum. */
- arch_enum_member_t *members[1]; /**< The array of members. */
+ int n_members; /**< The number of members in this enum. */
+ arch_enum_member_t *members[1]; /**< The array of members. */
};
typedef enum _arch_operand_type_t {
arch_operand_type_register,
arch_operand_type_immediate,
arch_operand_type_symconst,
- arch_operand_type_last
+ arch_operand_type_last
} arch_operand_type_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_none = 0, /**< No register requirement. */
- arch_register_req_type_normal = 1, /** All registers in the class
- are allowed. */
+ 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_limited = 2, /**< Only a real subset of
+ the class is allowed. */
- arch_register_req_type_equal = 4, /** The register must equal
- another one at the node. */
+ arch_register_req_type_equal = 4, /**< The register must equal
+ another one at the node. */
- arch_register_req_type_unequal = 8, /** The register must be unequal
- to some other at the node. */
+ arch_register_req_type_unequal = 8, /**< The register must be unequal
+ to some other at the node. */
- arch_register_req_type_pair = 16 /** The register is part of a
- register pair. */
+ arch_register_req_type_pair = 16 /**< The register is part of a
+ register pair. */
} arch_register_req_type_t;
#define arch_register_req_is_constr(x) \
* Expresses requirements to register allocation for an operand.
*/
typedef 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. */
+ arch_register_req_type_t type; /**< The type of the constraint. */
+ const arch_register_class_t *cls; /**< The register class this
+ constraint belongs to. */
union {
- int (*limited)(const ir_node *irn, int pos, struct _bitset_t *bs);
- /** In case of the 'limited'
+ int (*limited)(const ir_node *irn, int pos, bitset_t *bs);
+ /**< In case of the 'limited'
constraint, this function
must put all allowable
registers in the bitset and
return the number of registers
in the bitset. */
- int pos; /** In case of the equal constraint,
+ int pos; /**< In case of the equal constraint,
this gives the position of the
operand to which the register of
this should be equal to. Same for
arch_irn_class_branch
} arch_irn_class_t;
+/**
+ * Some flags describing a node in more detail.
+ */
+typedef enum _arch_irn_flags_t {
+ arch_irn_flags_spillable = 1,
+ arch_irn_flags_rematerializable = 2
+} arch_irn_flags_t;
+
/*
* Some words about positions and indices:
*
*/
arch_irn_class_t (*classify)(const arch_irn_ops_t *self, const ir_node *irn);
+ /**
+ * Get the flags of a node.
+ * @param self The irn ops themselves.
+ * @param irn The node.
+ * @return A set of flags.
+ */
+ arch_irn_flags_t (*get_flags)(const arch_irn_ops_t *self, const ir_node *irn);
+
};
+extern int
+arch_get_n_operands(const arch_env_t *env, const ir_node *irm, int in_out);
+
/**
* Get the register requirements for a node.
* @param env The architecture environment.
* @return The amount of registers allocatable for that operand.
*/
extern int arch_get_allocatable_regs(const arch_env_t *env, const ir_node *irn,
- int pos, const arch_register_class_t *cls, struct _bitset_t *bs);
+ int pos, const arch_register_class_t *cls, bitset_t *bs);
/**
* Check, if a register is assignable to an operand of a node.
* Get the register class of an operand of a node.
* @param env The architecture environment.
* @param irn The node.
- * @param idx The position of the operand.
+ * @param pos The position of the operand.
* @return The register class of the operand or NULL, if
* operand is a non-register operand.
*/
*/
extern arch_irn_class_t arch_irn_classify(const arch_env_t *env, const ir_node *irn);
+/**
+ * Get the flags of a node.
+ * @param env The architecture environment.
+ * @param irn The node.
+ * @return The flags.
+ */
+extern arch_irn_flags_t arch_irn_get_flags(const arch_env_t *env, const ir_node *irn);
+
#define arch_irn_has_reg_class(env, irn, pos, cls) \
((cls) == arch_get_irn_reg_class(env, irn, pos))
*/
const arch_register_class_t *(*get_reg_class)(int i);
+ /**
+ * Prepare a graph.
+ * This function is called each time, the back end starts running over
+ * a graph.
+ * @param irg The graph.
+ */
+ void (*prepare_graph)(ir_graph *irg);
+
+ /**
+ * 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 *irn_handler;
+
+ /**
+ * The code generation function for this architecture.
+ * (May be NULL)
+ * @param out The output file
+ */
+ void (*codegen)(FILE *out);
};
#define ARCH_MAX_HANDLERS 8