1 /************************************************************************
2 ************************************************************************
3 FAUST compiler
4 Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
5 ---------------------------------------------------------------------
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 ************************************************************************
20 ************************************************************************/
21
22 #include <stdlib.h>
23 #include <iostream>
24 #include <sstream>
25
26 #include "floats.hh"
27 #include "global.hh"
28
29 using namespace std;
30
31 //-----------------------------------------------
32 // float size coding :
33 //-----------------------------------------------
34 // 0: external float (macro name)
35 // 1: single precision float
36 // 2: double precision float
37 // 3: long double precision float
38 // 4: fixed-point
39
40 static const char* mathsuffix[5]; // suffix for math functions
41 static const char* numsuffix[5]; // suffix for numeric constants
42 static const char* floatname[5]; // float types
43 static const char* floatptrname[5]; // float ptr types
44 static const char* floatptrptrname[5]; // float ptr ptr types
45 static const char* castname[5]; // float castings
46 static double floatmin[5]; // minimum float values before denormals
47
initFaustFloat()48 void initFaustFloat()
49 {
50 // Using in FIR code generation to code math functions type (float/double/quad), same for Rust and C/C++ backends
51 mathsuffix[0] = "";
52 mathsuffix[1] = "f";
53 mathsuffix[2] = "";
54 mathsuffix[3] = "l";
55 mathsuffix[4] = "";
56
57 // Specific for Rust backend
58 if (gGlobal->gOutputLang == "rust") {
59 numsuffix[0] = "";
60 numsuffix[1] = "";
61 numsuffix[2] = "";
62 numsuffix[3] = "";
63 numsuffix[4] = "";
64
65 floatname[0] = FLOATMACRO;
66 floatname[1] = "F32";
67 floatname[2] = "F64";
68 floatname[3] = "dummy";
69 floatname[4] = "dummy";
70
71 floatptrname[0] = FLOATMACROPTR;
72 floatptrname[1] = "F32*";
73 floatptrname[2] = "F64*";
74 floatptrname[3] = "dummy*";
75 floatptrname[4] = "dummy*";
76
77 floatptrptrname[0] = FLOATMACROPTRPTR;
78 floatptrptrname[1] = "F32**";
79 floatptrptrname[2] = "F64**";
80 floatptrptrname[3] = "dummy**";
81 floatptrptrname[4] = "dummy**";
82
83 castname[0] = FLOATCASTER;
84 castname[1] = "as F32";
85 castname[2] = "as F64";
86 castname[3] = "(dummy)";
87 castname[4] = "(dummy)";
88
89 floatmin[0] = 0;
90 floatmin[1] = FLT_MIN;
91 floatmin[2] = DBL_MIN;
92 floatmin[3] = LDBL_MIN;
93 floatmin[4] = FLT_MIN;
94
95 // Specific for Julia backend
96 } else if (gGlobal->gOutputLang == "julia") {
97 numsuffix[0] = "";
98 numsuffix[1] = "f0";
99 numsuffix[2] = "";
100 numsuffix[3] = "";
101 numsuffix[4] = "";
102
103 floatname[0] = FLOATMACRO;
104 floatname[1] = "Float32";
105 floatname[2] = "Float64";
106 floatname[3] = "dummy";
107 floatname[4] = "dummy";
108
109 floatptrname[0] = FLOATMACROPTR;
110 floatptrname[1] = "Float32*";
111 floatptrname[2] = "Float64*";
112 floatptrname[3] = "dummy*";
113 floatptrname[4] = "dummy*";
114
115 floatptrptrname[0] = FLOATMACROPTRPTR;
116 floatptrptrname[1] = "Float32**";
117 floatptrptrname[2] = "Float64**";
118 floatptrptrname[3] = "dummy**";
119 floatptrptrname[4] = "dummy**";
120
121 castname[0] = FLOATCASTER;
122 castname[1] = "(Float32)";
123 castname[2] = "(Float64)";
124 castname[3] = "(dummy)";
125 castname[4] = "(dummy)";
126
127 floatmin[0] = 0;
128 floatmin[1] = FLT_MIN;
129 floatmin[2] = DBL_MIN;
130 floatmin[3] = LDBL_MIN;
131 floatmin[4] = FLT_MIN;
132
133 // Specific for D backend
134 } else if (gGlobal->gOutputLang == "dlang") {
135 numsuffix[0] = "";
136 numsuffix[1] = "";
137 numsuffix[2] = "";
138 numsuffix[3] = "";
139 numsuffix[4] = "";
140
141 floatname[0] = FLOATMACRO;
142 floatname[1] = "float";
143 floatname[2] = "double";
144 floatname[3] = "real";
145 floatname[4] = "dummy";
146
147 floatptrname[0] = FLOATMACROPTR;
148 floatptrname[1] = "float*";
149 floatptrname[2] = "double*";
150 floatptrname[3] = "real*";
151 floatptrname[4] = "dummy*";
152
153 floatptrptrname[0] = FLOATMACROPTRPTR;
154 floatptrptrname[1] = "float**";
155 floatptrptrname[2] = "double**";
156 floatptrptrname[3] = "real**";
157 floatptrptrname[4] = "dummy**";
158
159 castname[0] = FLOATCASTER;
160 castname[1] = "cast(float)";
161 castname[2] = "cast(double)";
162 castname[3] = "cast(real)";
163 castname[4] = "cast(dummy)";
164
165 floatmin[0] = 0;
166 floatmin[1] = FLT_MIN;
167 floatmin[2] = DBL_MIN;
168 floatmin[3] = LDBL_MIN;
169 floatmin[4] = FLT_MIN;
170
171 // Specific for C/C++ backends
172 } else {
173 numsuffix[0] = "";
174 numsuffix[1] = "f";
175 numsuffix[2] = "";
176 numsuffix[3] = "L";
177 numsuffix[4] = "";
178
179 floatname[0] = FLOATMACRO;
180 floatname[1] = "float";
181 floatname[2] = "double";
182 floatname[3] = "quad";
183 floatname[4] = "fixpoint_t";
184
185 floatptrname[0] = FLOATMACROPTR;
186 floatptrname[1] = "float*";
187 floatptrname[2] = "double*";
188 floatptrname[3] = "quad*";
189 floatptrname[4] = "fixpoint_t*";
190
191 floatptrptrname[0] = FLOATMACROPTRPTR;
192 floatptrptrname[1] = "float**";
193 floatptrptrname[2] = "double**";
194 floatptrptrname[3] = "quad**";
195 floatptrptrname[4] = "fixpoint_t**";
196
197 castname[0] = FLOATCASTER;
198 castname[1] = "(float)";
199 castname[2] = "(double)";
200 castname[3] = "(quad)";
201 castname[4] = "(fixpoint_t)";
202
203 floatmin[0] = 0;
204 floatmin[1] = FLT_MIN;
205 floatmin[2] = DBL_MIN;
206 floatmin[3] = LDBL_MIN;
207 floatmin[4] = FLT_MIN;
208 }
209 }
210
211 ///< suffix for math functions
isuffix()212 const char* isuffix()
213 {
214 return mathsuffix[gGlobal->gFloatSize];
215 }
216
217 ///< suffix for numeric constants
inumix()218 const char* inumix()
219 {
220 return numsuffix[gGlobal->gFloatSize];
221 }
222
ifloat()223 const char* ifloat()
224 {
225 return floatname[gGlobal->gFloatSize];
226 }
227
ifloatptr()228 const char* ifloatptr()
229 {
230 return floatptrname[gGlobal->gFloatSize];
231 }
232
ifloatptrptr()233 const char* ifloatptrptr()
234 {
235 return floatptrptrname[gGlobal->gFloatSize];
236 }
237
icast()238 const char* icast()
239 {
240 return castname[gGlobal->gFloatSize];
241 }
242
inummin()243 double inummin()
244 {
245 return floatmin[gGlobal->gFloatSize];
246 }
247
xfloat()248 const char* xfloat()
249 {
250 return floatname[0];
251 }
252
xcast()253 const char* xcast()
254 {
255 return castname[0];
256 }
257
ifloatsize()258 int ifloatsize()
259 {
260 switch (gGlobal->gFloatSize) {
261 case 1:
262 return 4;
263 case 2:
264 return 8;
265 case 3:
266 return 16;
267 case 4:
268 return 4;
269 default:
270 faustassert(false);
271 return 0;
272 }
273 }
274
itfloat()275 Typed::VarType itfloat()
276 {
277 switch (gGlobal->gFloatSize) {
278 case 1:
279 return Typed::kFloat;
280 case 2:
281 return Typed::kDouble;
282 case 3:
283 return Typed::kQuad;
284 case 4:
285 return Typed::kFixedPoint;
286 default:
287 faustassert(false);
288 return Typed::kNoType;
289 }
290 }
291
itfloatptr()292 Typed::VarType itfloatptr()
293 {
294 switch (gGlobal->gFloatSize) {
295 case 1:
296 return Typed::kFloat_ptr;
297 case 2:
298 return Typed::kDouble_ptr;
299 case 3:
300 return Typed::kQuad_ptr;
301 case 4:
302 return Typed::kFixedPoint_ptr;
303 default:
304 faustassert(false);
305 return Typed::kNoType;
306 }
307 }
308
itfloatptrptr()309 Typed::VarType itfloatptrptr()
310 {
311 switch (gGlobal->gFloatSize) {
312 case 1:
313 return Typed::kFloat_ptr_ptr;
314 case 2:
315 return Typed::kDouble_ptr_ptr;
316 case 3:
317 return Typed::kQuad_ptr_ptr;
318 case 4:
319 return Typed::kFixedPoint_ptr_ptr;
320 default:
321 faustassert(false);
322 return Typed::kNoType;
323 }
324 }
325
printfloatdef(std::ostream & fout)326 void printfloatdef(std::ostream& fout)
327 {
328 fout << "#ifndef " << FLOATMACRO << std::endl;
329 fout << "#define " << FLOATMACRO << " float" << std::endl;
330 fout << "#endif " << std::endl;
331 fout << std::endl;
332 if (gGlobal->gFloatSize == 3) {
333 fout << "typedef long double quad;" << std::endl;
334 }
335 }
336