beloopana: Remove duplicate comments.
[libfirm] / ir / lower / lower_dw.h
index 51fae34..4d36a85 100644 (file)
@@ -1,17 +1,28 @@
-/**
- * @file irlwrdw.h
- * @date 8.10.2004
- * @author Michael Beck
- * @brief Lower Double word operations, ie Mode L -> I
- *
- * $Id$
+/*
+ * This file is part of libFirm.
+ * Copyright (C) 2012 University of Karlsruhe.
  */
 
-#ifndef _FIRM_LOWER_DW_H
-#define _FIRM_LOWER_DW_H
+/**
+ * @file
+ * @brief   doubleword lowering operations
+ * @author  Michael Beck, Matthias Braun
+ */
+#ifndef FIRM_LOWER_LOWER_DW_H
+#define FIRM_LOWER_LOWER_DW_H
 
 #include "firm_types.h"
 
+/**
+ * Every double word node will be replaced,
+ * we need some store to hold the replacement:
+ */
+typedef struct lower64_entry_t {
+       ir_node *low_word;    /**< the low word */
+       ir_node *high_word;   /**< the high word */
+} lower64_entry_t;
+
+
 /**
  * A callback type for creating an intrinsic entity for a given opcode.
  *
  * @param context  the context parameter
  */
 typedef ir_entity *(create_intrinsic_fkt)(ir_type *method, const ir_op *op,
-                                          const ir_mode *imode, const ir_mode *omode,
-                                          void *context);
+                                          const ir_mode *imode,
+                                          const ir_mode *omode, void *context);
 
 /**
  * The lowering parameter description.
  */
-typedef struct _lwrdw_param_t {
-       int enable;                   /**< if true lowering is enabled */
-       int little_endian;            /**< if true should be lowered for little endian, else big endian */
-       ir_mode *high_signed;         /**< the double word signed mode to be lowered, typically Ls */
-       ir_mode *high_unsigned;       /**< the double word unsigned mode to be lowered, typically Lu */
-       ir_mode *low_signed;          /**< the word signed mode to be used, typically Is */
-       ir_mode *low_unsigned;        /**< the word unsigned mode to be used, typically Iu */
-
-       /** callback that creates the intrinsic entity */
-       create_intrinsic_fkt *create_intrinsic;
-       void *ctx;                    /**< context parameter for the creator function */
+typedef struct lwrdw_param_t {
+       unsigned              little_endian : 1; /**< if true should be lowered for little endian, else big endian */
+       unsigned              doubleword_size;   /**< bitsize of the doubleword mode */
+       create_intrinsic_fkt *create_intrinsic;  /**< callback that creates the intrinsic entity */
+       void                 *ctx;               /**< context parameter for the creator function */
 } lwrdw_param_t;
 
 /**
- * Lower all double word operations.
+ * Prepare the doubleword lowering algorithm. Creates an environment
+ * which can be used to register custom lowering functions
+ */
+void ir_prepare_dw_lowering(const lwrdw_param_t *param);
+
+/**
+ * Lower all doubleword operations in the program.
+ * Must be called after ir_prepare_dw_lowering()
+ */
+void ir_lower_dw_ops(void);
+
+typedef void (*lower_dw_func)(ir_node *node, ir_mode *mode);
+
+/**
+ * register a custom lowering function.
+ * After lowering the custom function should call ir_set_dw_lowered()
+ */
+void ir_register_dw_lower_function(ir_op *op, lower_dw_func func);
+
+/**
+ * After lowering a node a custom doubleword lowering function has to call this.
+ * It registers 2 new values for the high and low part of the lowered value.
+ */
+void ir_set_dw_lowered(ir_node *old, ir_node *new_low,
+                                ir_node *new_high);
+
+/**
+ * Query lowering results of a node. In a lowering callback you can use this
+ * on all predecessors of a node. The only exception are block and phi nodes.
+ * Their predecessors are not necessarily transformed yet.
+ */
+lower64_entry_t *get_node_entry(ir_node *node);
+
+static inline ir_node *get_lowered_low(ir_node *node)
+{
+       return get_node_entry(node)->low_word;
+}
+
+static inline ir_node *get_lowered_high(ir_node *node)
+{
+       return get_node_entry(node)->high_word;
+}
+
+/**
+ * Return the unsigned variant of the lowered mode
+ * Note: you must only call this during a dw_lowering (= in a lowering callback)
  */
-void lower_dw_ops(const lwrdw_param_t *param);
+ir_mode *ir_get_low_unsigned_mode(void);
 
 /**
  * Default implementation. Context is unused.
@@ -53,4 +103,4 @@ ir_entity *def_create_intrinsic_fkt(ir_type *method, const ir_op *op,
                                     const ir_mode *imode, const ir_mode *omode,
                                     void *context);
 
-#endif /* _FIRM_LOWER_DW_H */
+#endif