added new licence header
[libfirm] / ir / lower / lower_intrinsics.h
1 /*
2  * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /*
21  * Project:     libFIRM
22  * File name:   ir/lower/lower_intrinsics.h
23  * Purpose:     lowering of Calls of intrinsic functions
24  * Author:      Michael Beck
25  * Created:
26  * CVS-ID:      $Id$
27  * Copyright:   (c) 1998-2005 Universität Karlsruhe
28  */
29
30 /**
31  * @file lower_intrinsics.h
32  *
33  * Lowering of Calls of intrinsic functions.
34  *
35  * @author Michael Beck
36  */
37 #ifndef _LOWER_INTRINSICS_H_
38 #define _LOWER_INTRINSICS_H_
39
40 #include "firm_types.h"
41
42 /**
43  * An intrinsic mapper function.
44  *
45  * @param node   the IR-node that will be mapped
46  * @param ctx    a context
47  *
48  * @return  non-zero if the call was mapped
49  */
50 typedef int (*i_mapper_func)(ir_node *node, void *ctx);
51
52 enum ikind {
53   INTRINSIC_CALL  = 0,  /**< the record represents an intrinsic call */
54   INTRINSIC_INSTR       /**< the record represents an intrinsic instruction */
55 };
56
57 /**
58  * An intrinsic record.
59  */
60 typedef struct _i_call_record {
61   enum ikind    kind;       /**< must be INTRINSIC_CALL */
62   ir_entity     *i_ent;     /**< the entity representing an intrinsic call */
63   i_mapper_func i_mapper;   /**< the mapper function to call */
64   void          *ctx;       /**< mapper context */
65   void          *link;      /**< used in the construction algorithm, must be NULL */
66 } i_call_record;
67
68 /**
69  * An intrinsic instruction record.
70  */
71 typedef struct _i_instr_record {
72   enum ikind    kind;       /**< must be INTRINSIC_INSTR */
73   ir_op         *op;        /**< the opcode that must be mapped. */
74   i_mapper_func i_mapper;   /**< the mapper function to call */
75   void          *ctx;       /**< mapper context */
76   void          *link;      /**< used in the construction algorithm, must be NULL */
77 } i_instr_record;
78
79 /**
80  * An intrinsic record.
81  */
82 typedef union _i_record {
83   i_call_record  i_call;
84   i_instr_record i_instr;
85 } i_record;
86
87 /**
88  * Go through all graphs and map calls to intrinsic functions and instructions.
89  *
90  * Every call or instruction is reported to its mapper function,
91  * which is responsible for rebuilding the graph.
92  *
93  * current_ir_graph is always set.
94  *
95  * @param list    an array of intrinsic map records
96  * @param length  the length of the array
97  *
98  * @return number of found intrinsics.
99  */
100 unsigned lower_intrinsics(i_record *list, int length);
101
102 /**
103  * A mapper for the integer absolute value: inttype abs(inttype v).
104  * Replaces the call by a Abs node.
105  *
106  * @return always 1
107  */
108 int i_mapper_Abs(ir_node *call, void *ctx);
109
110 /**
111  * A mapper for the alloca() function: pointer alloca(inttype size)
112  * Replaces the call by a Alloca(stack_alloc) node.
113  *
114  * @return always 1
115  */
116 int i_mapper_Alloca(ir_node *call, void *ctx);
117
118 /**
119  * A runtime routine description.
120  */
121 typedef struct _runtime_rt {
122   ir_entity *ent;            /**< The entity representing the runtime routine. */
123   ir_mode   *mode;           /**< The operation mode of the mapped instruction. */
124   long      mem_proj_nr;     /**< if >= 0, create a memory ProjM() */
125   long      exc_proj_nr;     /**< if >= 0, create a exception ProjX() */
126   long      exc_mem_proj_nr; /**< if >= 0, create a exception memory ProjM() */
127   long      res_proj_nr;     /**< if >= 0, first result projection number */
128 } runtime_rt;
129
130 /**
131  * A mapper for mapping unsupported instructions to runtime calls.
132  * Maps a op(arg_0, ..., arg_n) into a call to a runtime function
133  * rt(arg_0, ..., arg_n).
134  *
135  * The mapping is only done, if the modes of all arguments matches the
136  * modes of rt's argument.
137  * Further, if op has a memory input, the generated Call uses it, else
138  * it gets a NoMem.
139  * The pinned state of the Call will be set to the pinned state of op.
140  *
141  * Note that i_mapper_RuntimeCall() must be used with a i_instr_record.
142  *
143  * @return 1 if an op was mapped, 0 else
144  *
145  * Some examples:
146  *
147  * - Maps Div nodes to calls to rt_Div():
148    @code
149   runtime_rt rt_Div = {
150     ent("int rt_Div(int, int)"),
151     mode_T,
152     pn_Div_M,
153     pn_Div_X_except,
154     pn_Div_M,
155     pn_Div_res
156   };
157   i_instr_record map_Div = {
158     INTRINSIC_INSTR,
159     op_Div,
160     i_mapper_RuntimeCall,
161     &rt_Div,
162     NULL
163   };
164   @endcode
165  *
166  * - Maps ConvD(F) to calls to rt_Float2Div():
167   @code
168   runtime_rt rt_Float2Double = {
169     ent("double rt_Float2Div(float)"),
170     get_type_mode("double"),
171     -1,
172     -1,
173     -1,
174     -1
175   };
176   i_instr_record map_Float2Double = {
177     INTRINSIC_INSTR,
178     op_Conv,
179     i_mapper_RuntimeCall,
180     &rt_Float2Double,
181     NULL
182   };
183   @endcode
184  */
185 int i_mapper_RuntimeCall(ir_node *node, runtime_rt *rt);
186
187 #endif /* _LOWER_INTRINSICS_H_ */