X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Flower%2Flower_dw.h;h=19792bf32f30fd72b095d5d66e28ac546132ee9c;hb=f8ead9acbe48af00885e64a6f2f895d1b6cae434;hp=1422c72ec2f5f7fee874ec684ea0ba42bdd0087a;hpb=31a8aba016d554d5c35fb5d62add6e9d28831646;p=libfirm diff --git a/ir/lower/lower_dw.h b/ir/lower/lower_dw.h index 1422c72ec..19792bf32 100644 --- a/ir/lower/lower_dw.h +++ b/ir/lower/lower_dw.h @@ -1,42 +1,120 @@ -/** - * @file irlwrdw.h - * @date 8.10.2004 - * @author Michael Beck - * @brief Lower Double word operations, ie Mode L -> I +/* + * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved. + * + * 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. * - * $Id$ + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. */ -#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" /** - * A callback type for creating an intrinsic entity for a given opcode. */ -typedef entity *(create_intrinsic_fkt)(ir_type *method, const ir_op *op, const ir_mode *mode, void *context); + * 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; + -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 */ +/** + * A callback type for creating an intrinsic entity for a given opcode. + * + * @param method the method type of the emulation function entity + * @param op the emulated ir_op + * @param imode the input mode of the emulated opcode + * @param omode the output mode of the emulated 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); - /** callback that creates the intrinsic entity */ - create_intrinsic_fkt *create_intrinsic; - void *ctx; /**< context parameter for the creator function */ +/** + * The lowering parameter description. + */ +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. + * Default implementation. Context is unused. */ -entity *def_create_intrinsic_fkt(ir_type *method, const ir_op *op, const ir_mode *mode, void *context); +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