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