2 * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
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.
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.
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
22 * @brief lowering of Calls of intrinsic functions
23 * @author Michael Beck
26 #ifndef FIRM_LOWER_LOWER_INTRINSICS_H
27 #define FIRM_LOWER_LOWER_INTRINSICS_H
29 #include "firm_types.h"
32 * An intrinsic mapper function.
34 * @param node the IR-node that will be mapped
35 * @param ctx a context
37 * @return non-zero if the call was mapped
39 typedef int (*i_mapper_func)(ir_node *node, void *ctx);
42 INTRINSIC_CALL = 0, /**< the record represents an intrinsic call */
43 INTRINSIC_INSTR /**< the record represents an intrinsic instruction */
47 * An intrinsic record.
49 typedef struct _i_call_record {
50 enum ikind kind; /**< must be INTRINSIC_CALL */
51 ir_entity *i_ent; /**< the entity representing an intrinsic call */
52 i_mapper_func i_mapper; /**< the mapper function to call */
53 void *ctx; /**< mapper context */
54 void *link; /**< used in the construction algorithm, must be NULL */
58 * An intrinsic instruction record.
60 typedef struct _i_instr_record {
61 enum ikind kind; /**< must be INTRINSIC_INSTR */
62 ir_op *op; /**< the opcode that must be mapped. */
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 */
69 * An intrinsic record.
71 typedef union _i_record {
73 i_instr_record i_instr;
77 * Go through all graphs and map calls to intrinsic functions and instructions.
79 * Every call or instruction is reported to its mapper function,
80 * which is responsible for rebuilding the graph.
82 * current_ir_graph is always set.
84 * @param list an array of intrinsic map records
85 * @param length the length of the array
87 * @return number of found intrinsics.
89 unsigned lower_intrinsics(i_record *list, int length);
92 * A mapper for the integer absolute value: inttype abs(inttype v).
93 * Replaces the call by a Abs node.
97 int i_mapper_Abs(ir_node *call, void *ctx);
100 * A mapper for the alloca() function: pointer alloca(inttype size)
101 * Replaces the call by a Alloca(stack_alloc) node.
105 int i_mapper_Alloca(ir_node *call, void *ctx);
108 * A runtime routine description.
110 typedef struct _runtime_rt {
111 ir_entity *ent; /**< The entity representing the runtime routine. */
112 ir_mode *mode; /**< The operation mode of the mapped instruction. */
113 long mem_proj_nr; /**< if >= 0, create a memory ProjM() */
114 long exc_proj_nr; /**< if >= 0, create a exception ProjX() */
115 long exc_mem_proj_nr; /**< if >= 0, create a exception memory ProjM() */
116 long res_proj_nr; /**< if >= 0, first result projection number */
120 * A mapper for mapping unsupported instructions to runtime calls.
121 * Maps a op(arg_0, ..., arg_n) into a call to a runtime function
122 * rt(arg_0, ..., arg_n).
124 * The mapping is only done, if the modes of all arguments matches the
125 * modes of rt's argument.
126 * Further, if op has a memory input, the generated Call uses it, else
128 * The pinned state of the Call will be set to the pinned state of op.
130 * Note that i_mapper_RuntimeCall() must be used with a i_instr_record.
132 * @return 1 if an op was mapped, 0 else
136 * - Maps Div nodes to calls to rt_Div():
138 runtime_rt rt_Div = {
139 ent("int rt_Div(int, int)"),
146 i_instr_record map_Div = {
149 i_mapper_RuntimeCall,
155 * - Maps ConvD(F) to calls to rt_Float2Div():
157 runtime_rt rt_Float2Double = {
158 ent("double rt_Float2Div(float)"),
159 get_type_mode("double"),
165 i_instr_record map_Float2Double = {
168 i_mapper_RuntimeCall,
174 int i_mapper_RuntimeCall(ir_node *node, runtime_rt *rt);
176 #endif /* FIRM_LOWER_LOWER_INTRINSICS_H */