e413c48e37b9fc745ceb78a2d7de7a3e531d5b9d
[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 } i_call_record;
48
49 /**
50  * An intrinsic instruction record.
51  */
52 typedef struct _i_instr_record {
53   enum ikind    kind;       /**< must be INTRINSIC_INSTR */
54   ir_op         *op;        /**< the opcode that must be mapped. */
55   i_mapper_func i_mapper;   /**< the mapper function to call */
56   void          *ctx;       /**< mapper context */
57 } i_instr_record;
58
59 /**
60  * An intrinsic record.
61  */
62 typedef union _i_record {
63   i_call_record  i_call;
64   i_instr_record i_instr;
65 } i_record;
66
67 /**
68  * Go through all graphs and map calls to intrinsic functions and instructions.
69  *
70  * Every call or instruction is reported to its mapper function,
71  * which is responsible for rebuilding the graph.
72  *
73  * current_ir_graph is always set.
74  *
75  * @param list    an array of intrinsic map records
76  * @param length  the length of the array
77  *
78  * @return number of found intrinsics.
79  */
80 unsigned lower_intrinsics(const i_record *list, int length);
81
82 /**
83  * A mapper for the integer absolute value: inttype abs(inttype v).
84  * Replaces the call by a Abs node.
85  *
86  * @return always 1
87  */
88 int i_mapper_Abs(ir_node *call, void *ctx);
89
90 /**
91  * A mapper for the alloca() function: pointer alloca(inttype size)
92  * Replaces the call by a Alloca(stack_alloc) node.
93  *
94  * @return always 1
95  */
96 int i_mapper_Alloca(ir_node *call, void *ctx);
97
98 /**
99  * A runtime routine description.
100  */
101 typedef struct _runtime_rt {
102   entity  *ent;            /**< The entity representing the runtime routine. */
103   ir_mode *mode;           /**< The operation mode of the mapped instruction. */
104   long    mem_proj_nr;      /**< if >= 0, create a memory ProjM() */
105   long    exc_proj_nr;      /**< if >= 0, create a exception ProjX() */
106   long    exc_mem_proj_nr;  /**< if >= 0, create a exception memory ProjM() */
107   long    res_proj_nr;      /**< if >= 0, first result projection number */
108 } runtime_rt;
109
110 /**
111  * A mapper for mapping unsupported instructions to runtime calls.
112  * Maps a op(arg_0, ..., arg_n) into a call to a runtime function
113  * rt(arg_0, ..., arg_n).
114  *
115  * The mapping is only done, if the modes of all arguments matches the
116  * modes of rt's argument.
117  * Further, if op has a memory input, the generated Call uses it, else
118  * it gets a NoMem.
119  * The pinned state of the Call will be set to the pinned state of op.
120  *
121  * Note that i_mapper_RuntimeCall() must be used with a i_instr_record.
122  *
123  * @return 1 if an op was mapped, 0 else
124  *
125  * Some examples:
126  *
127  * - Maps Div nodes to calls to rt_Div():
128    @code
129   runtime_rt rt_Div = {
130     ent("int rt_Div(int, int)"),
131     mode_T,
132     pn_Div_M,
133     pn_Div_X_except,
134     pn_Div_M,
135     pn_Div_res
136   };
137   i_instr_record map_Div = {
138     INTRINSIC_INSTR,
139     op_Div,
140     i_mapper_RuntimeCall,
141     &rt_Div
142   };
143   @endcode
144  *
145  * - Maps ConvD(F) to calls to rt_Float2Div():
146   @code
147   runtime_rt rt_Float2Double = {
148     ent("double rt_Float2Div(float)"),
149     get_type_mode("double"),
150     -1,
151     -1,
152     -1,
153     -1
154   };
155   i_instr_record map_Float2Double = {
156     INTRINSIC_INSTR,
157     op_Conv,
158     i_mapper_RuntimeCall,
159     &rt_Float2Double
160   };
161   @endcode
162  */
163 int i_mapper_RuntimeCall(ir_node *node, runtime_rt *rt);
164
165 #endif /* _LOWER_INTRINSICS_H_ */