Implement the first builtin function: exp().
[mesa.git] / builtin_function.cpp
1 /*
2 * Copyright © 2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include <stdlib.h>
25 #include "glsl_symbol_table.h"
26 #include "glsl_parser_extras.h"
27 #include "glsl_types.h"
28 #include "ir.h"
29
30 static void
31 generate_exp(exec_list *instructions,
32 ir_variable **declarations,
33 const glsl_type *type)
34 {
35 ir_dereference *const retval = new ir_dereference(declarations[16]);
36 ir_dereference *const arg = new ir_dereference(declarations[0]);
37 ir_rvalue *result;
38
39 result = new ir_expression(ir_unop_exp, type, arg, NULL);
40
41 ir_instruction *inst = new ir_assignment(retval, result, NULL);
42 instructions->push_tail(inst);
43 }
44
45 void
46 generate_function_instance(ir_function *f,
47 const char *name,
48 exec_list *instructions,
49 void (*generate)(exec_list *instructions,
50 ir_variable **declarations,
51 const glsl_type *type),
52 const glsl_type *type)
53 {
54 ir_variable *declarations[17];
55
56 ir_function_signature *const sig = new ir_function_signature(type);
57 f->signatures.push_tail(sig);
58
59 ir_label *const label = new ir_label(name);
60 instructions->push_tail(label);
61 sig->definition = label;
62
63 ir_variable *var = new ir_variable(type, "arg");
64
65 var->mode = ir_var_in;
66 sig->parameters.push_tail(var);
67
68 var = new ir_variable(type, "arg");
69
70 declarations[0] = var;
71
72 ir_variable *retval = new ir_variable(type, "__retval");
73 instructions->push_tail(retval);
74
75 declarations[16] = retval;
76
77 generate(instructions, declarations, type);
78 }
79
80 void
81 make_gentype_function(glsl_symbol_table *symtab, exec_list *instructions,
82 const char *name,
83 void (*generate)(exec_list *instructions,
84 ir_variable **declarations,
85 const glsl_type *type))
86 {
87 ir_function *const f = new ir_function(name);
88 const glsl_type *vec2_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 2, 1);
89 const glsl_type *vec3_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 3, 1);
90 const glsl_type *vec4_type = glsl_type::get_instance(GLSL_TYPE_FLOAT, 4, 1);
91
92 bool added = symtab->add_function(name, f);
93 assert(added);
94
95 generate_function_instance(f, name, instructions, generate, glsl_type::float_type);
96 generate_function_instance(f, name, instructions, generate, vec2_type);
97 generate_function_instance(f, name, instructions, generate, vec3_type);
98 generate_function_instance(f, name, instructions, generate, vec4_type);
99 }
100
101 void
102 generate_110_functions(glsl_symbol_table *symtab, exec_list *instructions)
103 {
104 /* FINISHME: radians() */
105 /* FINISHME: degrees() */
106 /* FINISHME: sin() */
107 /* FINISHME: cos() */
108 /* FINISHME: tan() */
109 /* FINISHME: asin() */
110 /* FINISHME: acos() */
111 /* FINISHME: atan(y,x) */
112 /* FINISHME: atan(y/x) */
113 /* FINISHME: pow() */
114 make_gentype_function(symtab, instructions, "exp", generate_exp);
115 /* FINISHME: log() */
116 /* FINISHME: exp2() */
117 /* FINISHME: log2() */
118 /* FINISHME: sqrt() */
119 /* FINISHME: inversesqrt() */
120 /* FINISHME: abs() */
121 /* FINISHME: sign() */
122 /* FINISHME: floor() */
123 /* FINISHME: ceil() */
124 /* FINISHME: fract() */
125 /* FINISHME: mod(x, float y) */
126 /* FINISHME: mod(x, y) */
127 /* FINISHME: min() */
128 /* FINISHME: max() */
129 /* FINISHME: clamp() */
130 /* FINISHME: clamp() */
131 /* FINISHME: mix() */
132 /* FINISHME: mix() */
133 /* FINISHME: step() */
134 /* FINISHME: step() */
135 /* FINISHME: smoothstep() */
136 /* FINISHME: smoothstep() */
137 /* FINISHME: floor() */
138 /* FINISHME: step() */
139 /* FINISHME: length() */
140 /* FINISHME: distance() */
141 /* FINISHME: dot() */
142 /* FINISHME: cross() */
143 /* FINISHME: normalize() */
144 /* FINISHME: ftransform() */
145 /* FINISHME: faceforward() */
146 /* FINISHME: reflect() */
147 /* FINISHME: refract() */
148 /* FINISHME: matrixCompMult() */
149 /* FINISHME: lessThan() */
150 /* FINISHME: lessThanEqual() */
151 /* FINISHME: greaterThan() */
152 /* FINISHME: greaterThanEqual() */
153 /* FINISHME: equal() */
154 /* FINISHME: notEqual() */
155 /* FINISHME: any() */
156 /* FINISHME: all() */
157 /* FINISHME: not() */
158 /* FINISHME: texture*() */
159 /* FINISHME: shadow*() */
160 /* FINISHME: dFd[xy]() */
161 /* FINISHME: fwidth() */
162 }
163
164 void
165 _mesa_glsl_initialize_functions(exec_list *instructions,
166 struct _mesa_glsl_parse_state *state)
167 {
168 generate_110_functions(state->symbols, instructions);
169 }