draft for register width specifications
[libfirm] / ir / be / bearch.h
index b6ffb7f..462ab08 100644 (file)
 #include "beinfo.h"
 #include "be.h"
 #include "beirg.h"
+#include "error.h"
 
 typedef enum arch_register_class_flags_t {
        arch_register_class_flag_none      = 0,
-       /**< don't do automatic register allocation for this class */
-       arch_register_class_flag_manual_ra = 1U << 0,
-       /**< the register models an abstract state (example: fpu rounding mode) */
+       /** don't do automatic register allocation for this class */
+       arch_register_class_flag_manual_ra = 1U << 0,
+       /** the register models an abstract state (example: fpu rounding mode) */
        arch_register_class_flag_state     = 1U << 1
 } arch_register_class_flags_t;
 
@@ -74,7 +75,7 @@ typedef enum arch_register_type_t {
  */
 typedef enum arch_register_req_type_t {
        /** No register requirement. */
-       arch_register_req_type_none              = 0,
+       arch_register_req_type_none              = 0,
        /** All registers in the class are allowed. */
        arch_register_req_type_normal            = 1U << 0,
        /** Only a real subset of the class is allowed. */
@@ -83,12 +84,14 @@ typedef enum arch_register_req_type_t {
        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,
+       /** The registernumber should be aligned (in case of multiregister values)*/
+       arch_register_req_type_must_be_aligned   = 1U << 4,
        /** ignore while allocating registers */
-       arch_register_req_type_ignore            = 1U << 4,
+       arch_register_req_type_ignore            = 1U << 5,
        /** 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) */
-       arch_register_req_type_produces_sp       = 1U << 5,
+       arch_register_req_type_produces_sp       = 1U << 6,
 } arch_register_req_type_t;
 
 extern const arch_register_req_t *arch_no_register_req;
@@ -105,7 +108,7 @@ void arch_dump_register_reqs(FILE *F, const ir_node *node);
 void arch_dump_reqs_and_registers(FILE *F, const ir_node *node);
 
 /**
- * Node classification. Used for statistics.
+ * Node classification. Used for statistics and for detecting reload nodes.
  */
 typedef enum arch_irn_class_t {
        arch_irn_class_spill  = 1 << 0,
@@ -118,7 +121,6 @@ typedef enum arch_irn_class_t {
 void arch_set_frame_offset(ir_node *irn, int bias);
 
 ir_entity *arch_get_frame_entity(const ir_node *irn);
-void       arch_set_frame_entity(ir_node *irn, ir_entity *ent);
 int        arch_get_sp_bias(ir_node *irn);
 
 int             arch_get_op_estimated_cost(const ir_node *irn);
@@ -199,8 +201,6 @@ void arch_irn_set_register(ir_node *irn, int pos, const arch_register_t *reg);
  */
 arch_irn_class_t arch_irn_classify(const ir_node *irn);
 
-#define arch_irn_class_is(irn, irn_class) ((arch_irn_classify(irn) & arch_irn_class_ ## irn_class) != 0)
-
 /**
  * Get the flags of a node.
  * @param irn The node.
@@ -339,6 +339,8 @@ struct arch_register_req_t {
        unsigned other_different;           /**< Bitmask of ins which shall use a
                                                 different register
                                                 (must_be_different) */
+       unsigned char width;                /**< specifies how many sequential
+                                                registers are required */
 };
 
 static inline int reg_reqs_equal(const arch_register_req_t *req1,
@@ -382,7 +384,7 @@ struct arch_inverse_t {
 struct arch_irn_ops_t {
 
        /**
-        * Get the register requirements for a given operand.
+        * Get the register requirements for a given operand.
         * @param irn The node.
         * @param pos The operand's position
         * @return    The register requirements for the selected operand.
@@ -406,13 +408,6 @@ struct arch_irn_ops_t {
         */
        ir_entity *(*get_frame_entity)(const ir_node *irn);
 
-       /**
-        * Set the entity on the stack frame this node depends on.
-        * @param irn  The node in question.
-        * @param ent  The entity to set
-        */
-       void (*set_frame_entity)(ir_node *irn, ir_entity *ent);
-
        /**
         * Set the offset of a node carrying an entity on the stack frame.
         * @param irn  The node.
@@ -485,10 +480,10 @@ struct arch_irn_ops_t {
 struct arch_code_generator_if_t {
        /**
         * Initialize the code generator.
-        * @param birg A backend IRG session.
+        * @param irg  A graph
         * @return     A newly created code generator.
         */
-       void *(*init)(be_irg_t *birg);
+       void *(*init)(ir_graph *irg);
 
        /**
         * return node used as base in pic code addresses
@@ -509,7 +504,7 @@ struct arch_code_generator_if_t {
         * Backend may provide an own spiller.
         * This spiller needs to spill all register classes.
         */
-       void (*spill)(void *self, be_irg_t *birg);
+       void (*spill)(void *self, ir_graph *irg);
 
        /**
         * Called before register allocation.
@@ -557,7 +552,7 @@ do { \
 #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_spill(cg, irg)      _arch_cg_call_env(cg, irg, spill)
 #define arch_code_generator_has_spiller(cg)     ((cg)->impl->spill != NULL)
 #define arch_code_generator_get_pic_base(cg)    \
        ((cg)->impl->get_pic_base != NULL ? (cg)->impl->get_pic_base(cg) : NULL)
@@ -751,6 +746,9 @@ struct arch_env_t {
        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 */
+       bool                   custom_abi : 1;   /**< backend does all abi handling
+                                                     and does not need the generic stuff
+                                                     from beabi.h/.c */
 };
 
 static inline unsigned arch_irn_get_n_outs(const ir_node *node)
@@ -776,13 +774,16 @@ static inline const arch_register_req_t *arch_get_register_req_out(
        int             pos = 0;
        backend_info_t *info;
 
+       /* you have to query the Proj nodes for the constraints (or use
+        * arch_get_out_register_req. Querying a mode_T node and expecting
+        * arch_no_register_req is a bug in your code! */
+       assert(get_irn_mode(irn) != mode_T);
+
        if (is_Proj(irn)) {
                pos = get_Proj_proj(irn);
                irn = get_Proj_pred(irn);
-       } else if (get_irn_mode(irn) == mode_T) {
-               /* TODO: find out who does this and fix the caller! */
-               return arch_no_register_req;
        }
+
        info = be_get_info(irn);
        if (info->out_infos == NULL)
                return arch_no_register_req;