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 #ifndef _FBC_INTERPRETER_H
23 #define _FBC_INTERPRETER_H
24 
25 #include <string.h>
26 #include <cmath>
27 #include <iostream>
28 #include <map>
29 #include <sstream>
30 #include <string>
31 #include <functional>
32 
33 #include "exception.hh"
34 #include "fbc_executor.hh"
35 #include "interpreter_bytecode.hh"
36 
37 /*
38  Interpreter using 'computed goto' technique: https://eli.thegreenplace.net/2012/07/12/computed-goto-for-efficient-dispatch-tables
39 
40  Trace mode: only check 'non-optimized' interpreter operations, since the code is not optimized in this case.
41 
42  1 : collect FP_SUBNORMAL only
43  2 : collect FP_SUBNORMAL, FP_INFINITE and FP_NAN
44  3 : collect FP_SUBNORMAL, FP_INFINITE, FP_NAN, INTEGER_OVERFLOW and DIV_BY_ZERO
45  4 : collect FP_SUBNORMAL, FP_INFINITE, FP_NAN, INTEGER_OVERFLOW, DIV_BY_ZERO, fails at first FP_INFINITE or FP_NAN
46  5 : collect FP_SUBNORMAL, FP_INFINITE, FP_NAN, INTEGER_OVERFLOW, DIV_BY_ZERO, continue after FP_INFINITE or FP_NAN
47 
48 */
49 
50 #define INTEGER_OVERFLOW -1
51 #define DIV_BY_ZERO_REAL -2
52 #define DIV_BY_ZERO_INT -3
53 #define CAST_INT_OVERFLOW -4
54 #define DUMMY_REAL 0.12233344445555
55 #define DUMMY_INT 1223334444
56 
57 //#define assertInterp(exp) faustassert(exp)
58 #define assertInterp(exp)
59 
60 template <class REAL, int TRACE>
61 struct interpreter_dsp_factory_aux;
62 
63 // FBC interpreter
64 template <class REAL, int TRACE>
65 class FBCInterpreter : public FBCExecutor<REAL> {
66    protected:
67 
68     typedef std::function<void(double)> ReflectFunction;
69     typedef std::function<double()> ModifyFunction;
70 
71     struct ZoneParam {
72 
73         FAUSTFLOAT fZone;
74         ReflectFunction fReflect;
75         ModifyFunction fModify;
76 
77     #if defined(TARGET_OS_IPHONE) || defined(WIN32)
ZoneParamFBCInterpreter::ZoneParam78         ZoneParam(ReflectFunction reflect = nullptr, ModifyFunction modify = nullptr)
79         :fReflect(reflect), fModify(modify)
80         {}
reflectZoneFBCInterpreter::ZoneParam81         void reflectZone() { if (fReflect) fReflect(fZone); }
modifyZoneFBCInterpreter::ZoneParam82         void modifyZone() { if (fModify) fZone = fModify(); }
83     #else
__anon5c502fc60202FBCInterpreter::ZoneParam84         ZoneParam(ReflectFunction reflect = [](REAL value) {}, ModifyFunction modify = []() { return REAL(-1); })
85         :fReflect(reflect), fModify(modify)
86         {}
reflectZoneFBCInterpreter::ZoneParam87         void reflectZone() { fReflect(fZone); }
modifyZoneFBCInterpreter::ZoneParam88         void modifyZone() { fZone = fModify(); }
89     #endif
90 
setReflectZoneFunFBCInterpreter::ZoneParam91         void setReflectZoneFun(ReflectFunction reflect) { fReflect = reflect; }
setModifyZoneFunFBCInterpreter::ZoneParam92         void setModifyZoneFun(ModifyFunction modify) { fModify = modify; }
93 
94     };
95 
96     typedef std::map<int, ZoneParam*> controlMap;
97 
98     controlMap fPathInputTable;     // [path, ZoneParam]
99     controlMap fPathOutputTable;    // [path, ZoneParam]
100 
101     interpreter_dsp_factory_aux<REAL, TRACE>* fFactory;
102 
103     int*        fIntHeap;
104     REAL*       fRealHeap;
105     Soundfile** fSoundHeap;
106 
107     REAL** fInputs;
108     REAL** fOutputs;
109 
110     std::map<int, int64_t> fRealStats;
111 
112     /*
113      Keeps the latest TRACE_STACK_SIZE executed instructions, to be displayed when an error occurs.
114      */
115     struct InterpreterTrace {
116 #define TRACE_STACK_SIZE 16
117 
118         std::vector<std::string> fExecTrace;
119         int                      fWriteIndex;
120         std::stringstream        fMessage;
121 
InterpreterTraceFBCInterpreter::InterpreterTrace122         InterpreterTrace()
123         {
124             for (int i = 0; i < TRACE_STACK_SIZE; i++) {
125                 fExecTrace.push_back("");
126             }
127             fWriteIndex = 0;
128         }
129 
pushFBCInterpreter::InterpreterTrace130         void push(const std::string& message)
131         {
132             fExecTrace[fWriteIndex] = message;
133             fWriteIndex             = (fWriteIndex + 1) % TRACE_STACK_SIZE;
134         }
135 
writeFBCInterpreter::InterpreterTrace136         void write(std::ostream* out)
137         {
138             for (int i = fWriteIndex - 1; i >= 0; i--) {
139                 *out << fExecTrace[i];
140             }
141             for (int i = int(fExecTrace.size()) - 1; i >= fWriteIndex; i--) {
142                 *out << fExecTrace[i];
143             }
144         }
145 
traceInstructionFBCInterpreter::InterpreterTrace146         void traceInstruction(InstructionIT it)
147         {
148             (*it)->write(&fMessage, false, false, false);  // Last param = false means no recursion in branches
149             push(fMessage.str());
150             fMessage.str("");
151         }
152 
traceInstructionFBCInterpreter::InterpreterTrace153         void traceInstruction(InstructionIT it, int int_value, REAL real_value)
154         {
155             (*it)->write(&fMessage, false, false, false);  // Last param = false means no recursion in branches
156             push(fMessage.str());
157             push("Stack [Int: " + std::to_string(int_value) + " ] [REAL: " + std::to_string(real_value) + " ]\n");
158             fMessage.str("");
159         }
160     };
161 
162     InterpreterTrace fTraceContext;
163 
traceInstruction(InstructionIT it)164     inline void traceInstruction(InstructionIT it)
165     {
166         fTraceContext.traceInstruction(it);
167     }
168 
traceInstruction(InstructionIT it,int int_value,REAL real_value)169     inline void traceInstruction(InstructionIT it, int int_value, REAL real_value)
170     {
171         fTraceContext.traceInstruction(it, int_value, real_value);
172     }
173 
printStats()174     void printStats()
175     {
176         if (TRACE > 0 && TRACE < 6) {
177             std::cout << "-------------------------------" << std::endl;
178             std::cout << "Interpreter statistics" << std::endl;
179             if (TRACE >= 1) {
180                 std::cout << "FP_SUBNORMAL: " << fRealStats[FP_SUBNORMAL] << std::endl;
181             }
182             if (TRACE >= 2) {
183                 std::cout << "FP_INFINITE: " << fRealStats[FP_INFINITE] << std::endl;
184                 std::cout << "FP_NAN: " << fRealStats[FP_NAN] << std::endl;
185             }
186             if (TRACE >= 3) {
187                 std::cout << "INTEGER_OVERFLOW: " << fRealStats[INTEGER_OVERFLOW] << std::endl;
188                 std::cout << "DIV_BY_ZERO_REAL: " << fRealStats[DIV_BY_ZERO_REAL] << std::endl;
189                 std::cout << "DIV_BY_ZERO_INT: " << fRealStats[DIV_BY_ZERO_INT] << std::endl;
190                 std::cout << "CAST_INT_OVERFLOW: " << fRealStats[CAST_INT_OVERFLOW] << std::endl;
191             }
192             std::cout << "-------------------------------" << std::endl;
193         }
194     }
195 
warningOverflow(InstructionIT it)196     inline void warningOverflow(InstructionIT it)
197     {
198         if (TRACE >= 6) return;
199 
200         if (TRACE >= 3) {
201             fRealStats[INTEGER_OVERFLOW]++;
202         }
203 
204         if (TRACE >= 5) {
205             std::cout << "-------- Interpreter 'Overflow' warning trace start --------" << std::endl;
206             traceInstruction(it);
207             fTraceContext.write(&std::cout);
208             std::cout << "-------- Interpreter 'Overflow' warning trace end --------\n\n";
209         }
210     }
211 
checkCastIntOverflow(InstructionIT it,REAL val)212     inline REAL checkCastIntOverflow(InstructionIT it, REAL val)
213     {
214         if (val > std::numeric_limits<int>::max() || val < std::numeric_limits<int>::min()) {
215 
216             if (TRACE >= 3) {
217                 fRealStats[CAST_INT_OVERFLOW]++;
218             }
219 
220             if (TRACE >= 4) {
221                 std::cout << "-------- Interpreter 'CastIntOverflow' trace start --------" << std::endl;
222                 traceInstruction(it);
223                 fTraceContext.write(&std::cout);
224                 std::cout << "-------- Interpreter 'CastIntOverflow' trace end --------\n\n";
225                 // Fails at first error...
226                 if (TRACE == 4) {
227                     throw faustexception("Interpreter exit\n");
228                 }
229             }
230         }
231 
232         return val;
233     }
234 
checkDivZero(InstructionIT it,REAL val)235     inline void checkDivZero(InstructionIT it, REAL val)
236     {
237         if (TRACE >= 6) return;
238 
239         if ((TRACE >= 3) && (val == REAL(0))) {
240             fRealStats[DIV_BY_ZERO_REAL]++;
241         }
242 
243         if ((TRACE >= 4) && (val == REAL(0))) {
244             std::cout << "-------- Interpreter 'REAL div by zero' trace start --------" << std::endl;
245             traceInstruction(it);
246             fTraceContext.write(&std::cout);
247             std::cout << "-------- Interpreter 'REAL div by zero' trace end ----------\n\n";
248         }
249     }
250 
checkDivZero(InstructionIT it,int val)251     inline void checkDivZero(InstructionIT it, int val)
252     {
253         if (TRACE >= 6) return;
254 
255         if ((TRACE >= 3) && (val == 0)) {
256             fRealStats[DIV_BY_ZERO_INT]++;
257         }
258 
259         if ((TRACE >= 4) && (val == 0)) {
260             std::cout << "-------- Interpreter 'Int div by zero' trace start --------" << std::endl;
261             traceInstruction(it);
262             fTraceContext.write(&std::cout);
263             std::cout << "-------- Interpreter 'Int div by zero' trace end ----------\n\n";
264         }
265     }
266 
checkRealAux(InstructionIT it,REAL val)267     inline REAL checkRealAux(InstructionIT it, REAL val)
268     {
269         if (TRACE >= 6) return val;
270 
271         if (TRACE >= 1) {
272             if (std::fpclassify(val) == FP_SUBNORMAL) {
273                 fRealStats[FP_SUBNORMAL]++;
274             }
275         }
276 
277         if (TRACE >= 2) {
278             if (std::isnan(val)) {
279                 fRealStats[FP_NAN]++;
280             } else if (std::isinf(val)) {
281                 fRealStats[FP_INFINITE]++;
282             }
283         }
284 
285         if (TRACE >= 4) {
286             if (std::isnan(val)) {
287                 std::cout << "-------- Interpreter 'Nan' trace start --------" << std::endl;
288                 traceInstruction(it);
289                 fTraceContext.write(&std::cout);
290                 std::cout << "-------- Interpreter 'Nan' trace end --------\n\n";
291                 // Fails at first error...
292                 if (TRACE == 4) {
293                     throw faustexception("Interpreter exit\n");
294                 }
295             } else if (std::isinf(val)) {
296                 std::cout << "-------- Interpreter 'Inf' trace start --------" << std::endl;
297                 traceInstruction(it);
298                 fTraceContext.write(&std::cout);
299                 std::cout << "-------- Interpreter 'Inf' trace end --------\n\n";
300                 // Fails at first error...
301                 if (TRACE == 4) {
302                     throw faustexception("Interpreter exit\n");
303                 }
304             }
305         }
306         return val;
307     }
308 
assertAudioBuffer(InstructionIT it,int index)309     inline int assertAudioBuffer(InstructionIT it, int index)
310     {
311         if (TRACE >= 6) return index;
312 
313         if (TRACE >= 4 && ((index < 0) || (index >= fIntHeap[fFactory->fCountOffset]))) {
314             std::cout << "-------- Interpreter crash trace start --------" << std::endl;
315             std::cout << "assertAudioBuffer : count " << fIntHeap[fFactory->fCountOffset];
316             std::cout << " index " << index << std::endl;
317             fTraceContext.write(&std::cout);
318             std::cout << "-------- Interpreter crash trace end --------\n\n";
319             if (TRACE == 4) {
320                 throw faustexception("Interpreter exit\n");
321             }
322         }
323         return index;
324     }
325 
assertStoreIntHeap(InstructionIT it,int index,int size=-1)326     inline int assertStoreIntHeap(InstructionIT it, int index, int size = -1)
327     {
328         if (TRACE >= 4 &&
329             ((index < 0) || (index >= fFactory->fIntHeapSize) || (size > 0 && (index >= ((*it)->fOffset1 + size))))) {
330             std::cout << "-------- Interpreter crash trace start --------" << std::endl;
331             if (size > 0) {
332                 std::cout << "assertStoreIntHeap array: fIntHeapSize ";
333                 std::cout << fFactory->fIntHeapSize << " index " << (index - (*it)->fOffset1);
334                 std::cout << " size " << size;
335                 std::cout << " name " << (*it)->fName << std::endl;
336             } else {
337                 std::cout << "assertStoreIntHeap scalar: fIntHeapSize ";
338                 std::cout << fFactory->fIntHeapSize << " index " << index;
339                 std::cout << " name " << (*it)->fName << std::endl;
340             }
341             fTraceContext.write(&std::cout);
342             std::cout << "-------- Interpreter crash trace end --------\n\n";
343             if (TRACE == 4 || TRACE == 7) {
344                 throw faustexception("Interpreter exit\n");
345             }
346         }
347         return index;
348     }
349 
assertStoreRealHeap(InstructionIT it,int index,int size=-1)350     inline int assertStoreRealHeap(InstructionIT it, int index, int size = -1)
351     {
352         if (TRACE >= 4 &&
353             ((index < 0) || (index >= fFactory->fRealHeapSize) || (size > 0 && (index >= ((*it)->fOffset1 + size))))) {
354             std::cout << "-------- Interpreter crash trace start --------" << std::endl;
355             if (size > 0) {
356                 std::cout << "assertStoreRealHeap array: fIntHeapSize ";
357                 std::cout << fFactory->fRealHeapSize << " index " << (index - (*it)->fOffset1);
358                 std::cout << " size " << size;
359                 std::cout << " name " << (*it)->fName << std::endl;
360             } else {
361                 std::cout << "assertStoreRealHeap scalar: fIntHeapSize ";
362                 std::cout << fFactory->fRealHeapSize << " index " << index;
363                 std::cout << " name " << (*it)->fName << std::endl;
364             }
365             fTraceContext.write(&std::cout);
366             std::cout << "-------- Interpreter crash trace end --------\n\n";
367             if (TRACE == 4 || TRACE == 7) {
368                 throw faustexception("Interpreter exit\n");
369             }
370         }
371         return index;
372     }
373 
assertSoundHeap(InstructionIT it,int index,int size=-1)374     inline int assertSoundHeap(InstructionIT it, int index, int size = -1)
375     {
376         if (TRACE >= 4 && ((index < 0) || (index >= fFactory->fSoundHeapSize) || (size > 0 && index >= size))) {
377             std::cout << "-------- Interpreter crash trace start --------" << std::endl;
378             std::cout << "assertSoundHeap : fSoundHeapSize "
379                       << fFactory->fSoundHeapSize << " index " << index
380                       << " size " << size << std::endl;
381             fTraceContext.write(&std::cout);
382             std::cout << "-------- Interpreter crash trace end --------\n\n";
383             if (TRACE == 4 || TRACE == 7) {
384                 throw faustexception("Interpreter exit\n");
385             }
386         }
387         return index;
388     }
389 
assertLoadIntHeap(InstructionIT it,int index,int size=-1)390     inline int assertLoadIntHeap(InstructionIT it, int index, int size = -1)
391     {
392         if ((TRACE >= 4) &&
393             ((index < 0)
394              || (index >= fFactory->fIntHeapSize)
395              || (size > 0 && (index >= ((*it)->fOffset1 + size)))
396              || (fIntHeap[index] == DUMMY_INT))) {
397             std::cout << "-------- Interpreter crash trace start --------" << std::endl;
398             if (size > 0) {
399                 std::cout << "assertLoadIntHeap array: fIntHeapSize ";
400                 std::cout << fFactory->fIntHeapSize << " index " << (index - (*it)->fOffset1);
401                 std::cout << " size " << size;
402                 std::cout << " value " << fIntHeap[index];
403                 std::cout << " name " << (*it)->fName << std::endl;
404             } else {
405                 std::cout << "assertLoadIntHeap scalar: fIntHeapSize ";
406                 std::cout << fFactory->fIntHeapSize << " index " << index;
407                 std::cout << " name " << (*it)->fName << std::endl;
408             }
409             fTraceContext.write(&std::cout);
410             std::cout << "-------- Interpreter crash trace end --------\n\n";
411             if (TRACE == 4 || TRACE == 7) {
412                 throw faustexception("Interpreter exit\n");
413             }
414         }
415         return index;
416     }
417 
assertLoadRealHeap(InstructionIT it,int index,int size=-1)418     inline int assertLoadRealHeap(InstructionIT it, int index, int size = -1)
419     {
420         if ((TRACE >= 4) &&
421             ((index < 0)
422              || (index >= fFactory->fRealHeapSize)
423              || (size > 0 && (index >= ((*it)->fOffset1 + size)))
424              || (fRealHeap[index] == REAL(DUMMY_REAL)))) {
425             std::cout << "-------- Interpreter crash trace start --------" << std::endl;
426             if (size > 0) {
427                 std::cout << "assertLoadRealHeap array: fRealHeapSize ";
428                 std::cout << fFactory->fRealHeapSize << " index " << (index - (*it)->fOffset1);
429                 std::cout << " size " << size;
430                 std::cout << " value " << fRealHeap[index];
431                 std::cout << " name " << (*it)->fName << std::endl;
432             } else {
433                 std::cout << "assertLoadRealHeap scalar: fRealHeapSize ";
434                 std::cout << fFactory->fRealHeapSize << " index " << index;
435                 std::cout << " name " << (*it)->fName << std::endl;
436             }
437             fTraceContext.write(&std::cout);
438             std::cout << "-------- Interpreter crash trace end --------\n\n";
439             if (TRACE == 4 || TRACE == 7) {
440                 throw faustexception("Interpreter exit\n");
441             }
442         }
443         return index;
444     }
445 
assertIndex(InstructionIT it,int index,int size=-1)446     inline void assertIndex(InstructionIT it, int index, int size = -1)
447     {
448         if ((TRACE >= 4) && ((index < 0) || (index >= size))) {
449             std::cout << "-------- Interpreter crash trace start --------" << std::endl;
450             std::cout << "index " << index << " size " << size << std::endl;
451             traceInstruction(it);
452             fTraceContext.write(&std::cout);
453             throw faustexception("Interpreter exit\n");
454         }
455         if (TRACE == 4 || TRACE == 7) {
456             throw faustexception("Interpreter exit\n");
457         }
458     }
459 
checkReal(InstructionIT it,REAL val)460     inline REAL checkReal(InstructionIT it, REAL val) { return (TRACE > 0) ? checkRealAux(it, val) : val; }
461 
updateInputControls()462     void updateInputControls()
463     {
464         for (const auto& i : fPathInputTable) {
465             i.second->reflectZone();
466         }
467 
468     }
updateOutputControls()469     void updateOutputControls()
470     {
471         for (const auto& i : fPathOutputTable) {
472             i.second->modifyZone();
473         }
474     }
475 
476 #define pushInt(val) (int_stack[int_stack_index++] = val)
477 #define popInt() (int_stack[--int_stack_index])
478 
479 #define pushReal(it, val) (real_stack[real_stack_index++] = checkReal(it, val))
480 #define popReal(it) checkReal(it, real_stack[--real_stack_index])
481 
482 #define pushSound(val) (sound_stack[sound_stack_index++] = val)
483 #define popSound() (sound_stack[--sound_stack_index])
484 
485 #define pushAddr_(addr) (address_stack[addr_stack_index++] = addr)
486 #define popAddr_() (address_stack[--addr_stack_index])
487 
getZoneParam(controlMap & map,ZoneParam * cur_param,int offset)488     ZoneParam* getZoneParam(controlMap& map, ZoneParam* cur_param, int offset)
489     {
490         if (cur_param) {
491             map[offset] = cur_param;
492             return cur_param;
493         } else if (map.find(offset) == map.end()) {
494             ZoneParam* param = new ZoneParam();
495             map[offset] = param;
496             return param;
497         } else {
498              return map[offset];
499         }
500     }
501 
getZoneParam(int offset)502     ZoneParam* getZoneParam(int offset)
503     {
504         if (fPathInputTable.find(offset) != fPathInputTable.end()) {
505             return fPathInputTable[offset];
506         } else if (fPathOutputTable.find(offset) != fPathOutputTable.end()) {
507             return fPathOutputTable[offset];
508         } else {
509             return new ZoneParam();
510         }
511     }
512 
ExecuteBuildUserInterface(FIRUserInterfaceBlockInstruction<REAL> * block,UITemplate * glue)513     void ExecuteBuildUserInterface(FIRUserInterfaceBlockInstruction<REAL>* block, UITemplate* glue)
514     {
515         // UI may have to be adapted if REAL and FAUSTFLOAT size do not match
516         bool need_proxy = (sizeof(REAL) == 8 && reinterpret_cast<UI*>(glue->fCPPInterface)->sizeOfFAUSTFLOAT() == 4);
517         ZoneParam* cur_param = nullptr;
518 
519         for (const auto& it : block->fInstructions) {
520             // it->write(&std::cout);
521 
522             switch (it->fOpcode) {
523                 case FBCInstruction::kOpenVerticalBox:
524                     glue->openVerticalBox(it->fLabel.c_str());
525                     break;
526 
527                 case FBCInstruction::kOpenHorizontalBox:
528                     glue->openHorizontalBox(it->fLabel.c_str());
529                     break;
530 
531                 case FBCInstruction::kOpenTabBox:
532                     glue->openTabBox(it->fLabel.c_str());
533                     break;
534 
535                 case FBCInstruction::kCloseBox:
536                     glue->closeBox();
537                     break;
538 
539                 case FBCInstruction::kAddButton:
540                     if (need_proxy) {
541                         ZoneParam* param = getZoneParam(fPathInputTable, cur_param, it->fOffset);
542                         param->setReflectZoneFun([=](REAL value) { fRealHeap[it->fOffset] = value; });
543                         glue->addButton(it->fLabel.c_str(), &param->fZone);
544                         cur_param = nullptr;
545                     } else {
546                         glue->addButton(it->fLabel.c_str(), &fRealHeap[it->fOffset]);
547                     }
548                     break;
549 
550                 case FBCInstruction::kAddCheckButton:
551                     if (need_proxy) {
552                         ZoneParam* param = getZoneParam(fPathInputTable, cur_param, it->fOffset);
553                         param->setReflectZoneFun([=](REAL value) { fRealHeap[it->fOffset] = value; });
554                         glue->addCheckButton(it->fLabel.c_str(), &param->fZone);
555                         cur_param = nullptr;
556                     } else {
557                         glue->addCheckButton(it->fLabel.c_str(), &fRealHeap[it->fOffset]);
558                     }
559                     break;
560 
561                 case FBCInstruction::kAddHorizontalSlider:
562                     if (need_proxy) {
563                         ZoneParam* param = getZoneParam(fPathInputTable, cur_param, it->fOffset);
564                         param->setReflectZoneFun([=](REAL value) { fRealHeap[it->fOffset] = value; });
565                         glue->addHorizontalSlider(it->fLabel.c_str(), &param->fZone,
566                                                   it->fInit, it->fMin,it->fMax, it->fStep);
567                         cur_param = nullptr;
568                     } else {
569                         glue->addHorizontalSlider(it->fLabel.c_str(), &fRealHeap[it->fOffset],
570                                                   it->fInit, it->fMin,it->fMax, it->fStep);
571                     }
572                     break;
573 
574                 case FBCInstruction::kAddVerticalSlider:
575                     if (need_proxy) {
576                         ZoneParam* param = getZoneParam(fPathInputTable, cur_param, it->fOffset);
577                         param->setReflectZoneFun([=](REAL value) { fRealHeap[it->fOffset] = value; });
578                         glue->addVerticalSlider(it->fLabel.c_str(), &param->fZone,
579                                                   it->fInit, it->fMin,it->fMax, it->fStep);
580                         cur_param = nullptr;
581                     } else {
582                         glue->addVerticalSlider(it->fLabel.c_str(), &fRealHeap[it->fOffset],
583                                                 it->fInit, it->fMin, it->fMax, it->fStep);
584                     }
585                     break;
586 
587                 case FBCInstruction::kAddNumEntry:
588                     if (need_proxy) {
589                         ZoneParam* param = getZoneParam(fPathInputTable, cur_param, it->fOffset);
590                         param->setReflectZoneFun([=](REAL value) { fRealHeap[it->fOffset] = value; });
591                         glue->addNumEntry(it->fLabel.c_str(), &param->fZone,
592                                           it->fInit, it->fMin,it->fMax, it->fStep);
593                         cur_param = nullptr;
594                     } else {
595                         glue->addNumEntry(it->fLabel.c_str(), &fRealHeap[it->fOffset],
596                                           it->fInit, it->fMin, it->fMax, it->fStep);
597                     }
598                     break;
599 
600                 case FBCInstruction::kAddSoundfile:
601                     glue->addSoundfile(it->fLabel.c_str(), it->fKey.c_str(), &fSoundHeap[it->fOffset]);
602                     break;
603 
604                 case FBCInstruction::kAddHorizontalBargraph:
605                     if (need_proxy) {
606                         ZoneParam* param = getZoneParam(fPathOutputTable, cur_param, it->fOffset);
607                         param->setModifyZoneFun([=]() { return fRealHeap[it->fOffset]; });
608                         glue->addHorizontalBargraph(it->fLabel.c_str(), &param->fZone, it->fMin, it->fMax);
609                         cur_param = nullptr;
610                     } else {
611                         glue->addHorizontalBargraph(it->fLabel.c_str(), &fRealHeap[it->fOffset], it->fMin, it->fMax);
612                     }
613                     break;
614 
615                 case FBCInstruction::kAddVerticalBargraph:
616                     if (need_proxy) {
617                         ZoneParam* param = getZoneParam(fPathOutputTable, cur_param, it->fOffset);
618                         param->setModifyZoneFun([=]() { return fRealHeap[it->fOffset]; });
619                         glue->addVerticalBargraph(it->fLabel.c_str(), &param->fZone, it->fMin, it->fMax);
620                         cur_param = nullptr;
621                     } else {
622                         glue->addVerticalBargraph(it->fLabel.c_str(), &fRealHeap[it->fOffset], it->fMin, it->fMax);
623                     }
624                     break;
625 
626                 case FBCInstruction::kDeclare:
627                     // Special case for "0" zone
628                     if (it->fOffset == -1) {
629                         glue->declare(static_cast<REAL*>(nullptr), it->fKey.c_str(), it->fValue.c_str());
630                     } else {
631                         if (need_proxy) {
632                             if (!cur_param) cur_param = getZoneParam(it->fOffset);
633                             glue->declare(&cur_param->fZone, it->fKey.c_str(), it->fValue.c_str());
634                         } else {
635                             glue->declare(&fRealHeap[it->fOffset], it->fKey.c_str(), it->fValue.c_str());
636                         }
637                     }
638                     break;
639 
640                 default:
641                     break;
642             }
643         }
644     }
645 
646 #if defined(_WIN32)
ExecuteBlock(FBCBlockInstruction<REAL> * block,bool compile=false)647     void ExecuteBlock(FBCBlockInstruction<REAL>* block, bool compile = false)
648     {
649         int real_stack_index  = 0;
650         int int_stack_index   = 0;
651         int sound_stack_index = 0;
652         int addr_stack_index  = 0;
653 
654         REAL          real_stack[512];
655         int           int_stack[512];
656         Soundfile*    sound_stack[512];
657         InstructionIT address_stack[64];
658 
659         memset(real_stack, 0, sizeof(REAL)*512);
660         memset(int_stack, 0, sizeof(int)*512);
661         memset(sound_stack, 0, sizeof(Soundfile*)*512);
662         memset(address_stack, 0, sizeof(InstructionIT)*64);
663 
664         if (TRACE > 0) {
665             // Check block coherency
666             block->check();
667         }
668 
669 #define dispatchFirstScal() \
670     {                       \
671         goto loop;          \
672     }
673 #define dispatchNextScal()    \
674     {                         \
675         if (TRACE >= 4) {     \
676             traceInstruction(it, int_stack[int_stack_index], real_stack[real_stack_index]); \
677         }                     \
678         it++;                 \
679         dispatchFirstScal()   \
680     }
681 
682 #define dispatchBranch1Scal()                        \
683     {                                                \
684         it = (*it)->fBranch1->fInstructions.begin(); \
685         dispatchFirstScal();                         \
686     }
687 #define dispatchBranch2Scal()                        \
688     {                                                \
689         it = (*it)->fBranch2->fInstructions.begin(); \
690         dispatchFirstScal();                         \
691     }
692 
693 #define pushBranch1Scal()                                  \
694     {                                                      \
695         pushAddr_((*it)->fBranch1->fInstructions.begin()); \
696     }
697 #define pushBranch2Scal()                                  \
698     {                                                      \
699         pushAddr_((*it)->fBranch2->fInstructions.begin()); \
700     }
701 
702 #define dispatchReturnScal() \
703     {                        \
704         it = popAddr_();     \
705         dispatchFirstScal(); \
706     }
707 #define saveReturnScal()   \
708     {                      \
709         pushAddr_(it + 1); \
710     }
711 #define emptyReturnScal() (addr_stack_index == 0)
712 
713         InstructionIT it = block->fInstructions.begin();
714 
715         loop:
716             // (*it)->write(&std::cout);
717             switch ((*it)->fOpcode) {
718 
719                 // Number operations
720                 case FBCInstruction::kRealValue : {
721                     pushReal(it, (*it)->fRealValue);
722                     dispatchNextScal();
723                 }
724 
725                 case FBCInstruction::kInt32Value : {
726                     pushInt((*it)->fIntValue);
727                     dispatchNextScal();
728                 }
729 
730                 // Memory operations
731                 case FBCInstruction::kLoadReal : {
732                     if (TRACE > 0) {
733                         pushReal(it, fRealHeap[assertLoadRealHeap(it, (*it)->fOffset1)]);
734                     } else {
735                         pushReal(it, fRealHeap[(*it)->fOffset1]);
736                     }
737                     dispatchNextScal();
738                 }
739 
740                 case FBCInstruction::kLoadInt : {
741                     if (TRACE > 0) {
742                         pushInt(fIntHeap[assertLoadIntHeap(it, (*it)->fOffset1)]);
743                     } else {
744                         pushInt(fIntHeap[(*it)->fOffset1]);
745                     }
746                     dispatchNextScal();
747                 }
748 
749                 case FBCInstruction::kLoadSound : {
750                     if (TRACE > 0) {
751                         pushSound(fSoundHeap[assertSoundHeap(it, (*it)->fOffset1)]);
752                     } else {
753                         pushSound(fSoundHeap[(*it)->fOffset1]);
754                     }
755                     dispatchNextScal();
756                 }
757 
758                 case FBCInstruction::kLoadSoundField : {
759                     // TODO
760                     dispatchNextScal();
761                 }
762 
763                 case FBCInstruction::kStoreReal : {
764                     if (TRACE > 0) {
765                         fRealHeap[assertStoreRealHeap(it, (*it)->fOffset1)] = popReal(it);
766                     } else {
767                         fRealHeap[(*it)->fOffset1] = popReal(it);
768                     }
769                     dispatchNextScal();
770                 }
771 
772                 case FBCInstruction::kStoreInt : {
773                     if (TRACE > 0) {
774                         fIntHeap[assertStoreIntHeap(it, (*it)->fOffset1)] = popInt();
775                     } else {
776                         fIntHeap[(*it)->fOffset1] = popInt();
777                     }
778                     dispatchNextScal();
779                 }
780 
781                 case FBCInstruction::kStoreSound : {
782                     // TODO
783                     dispatchNextScal();
784                 }
785 
786                 // Directly store a value
787                 case FBCInstruction::kStoreRealValue : {
788                     if (TRACE > 0) {
789                         fRealHeap[assertStoreRealHeap(it, (*it)->fOffset1)] = (*it)->fRealValue;
790                     } else {
791                         fRealHeap[(*it)->fOffset1] = (*it)->fRealValue;
792                     }
793                     dispatchNextScal();
794                 }
795 
796                 case FBCInstruction::kStoreIntValue : {
797                     if (TRACE > 0) {
798                         fIntHeap[assertStoreIntHeap(it, (*it)->fOffset1)] = (*it)->fIntValue;
799                     } else {
800                         fIntHeap[(*it)->fOffset1] = (*it)->fIntValue;
801                     }
802                     dispatchNextScal();
803                 }
804 
805                 case FBCInstruction::kLoadIndexedReal : {
806                     int offset = popInt();
807                     if (TRACE > 0) {
808                         // DEBUG
809                         // assertIndex(it, offset, (*it)->fOffset2);
810                         pushReal(it, fRealHeap[assertLoadRealHeap(it, (*it)->fOffset1 + offset, (*it)->fOffset2)]);
811                     } else {
812                         pushReal(it, fRealHeap[(*it)->fOffset1 + offset]);
813                     }
814                     dispatchNextScal();
815                 }
816 
817                 case FBCInstruction::kLoadIndexedInt : {
818                     int offset = popInt();
819                     if (TRACE > 0) {
820                         // DEBUG
821                         // assertIndex(it, offset, (*it)->fOffset2);
822                         pushInt(fIntHeap[assertLoadIntHeap(it, (*it)->fOffset1 + offset, (*it)->fOffset2)]);
823                     } else {
824                         pushInt(fIntHeap[(*it)->fOffset1 + offset]);
825                     }
826                     dispatchNextScal();
827                 }
828 
829                 case FBCInstruction::kStoreIndexedReal : {
830                     int offset = popInt();
831                     if (TRACE > 0) {
832                         // DEBUG
833                         // assertIndex(it, offset, (*it)->fOffset2);
834                         fRealHeap[assertStoreRealHeap(it, (*it)->fOffset1 + offset, (*it)->fOffset2)] = popReal(it);
835                     } else {
836                         fRealHeap[(*it)->fOffset1 + offset] = popReal(it);
837                     }
838                     dispatchNextScal();
839                 }
840 
841                 case FBCInstruction::kStoreIndexedInt : {
842                     int offset = popInt();
843                     if (TRACE > 0) {
844                         // DEBUG
845                         // assertIndex(it, offset, (*it)->fOffset2);
846                         fIntHeap[assertStoreIntHeap(it, (*it)->fOffset1 + offset, (*it)->fOffset2)] = popInt();
847                     } else {
848                         fIntHeap[(*it)->fOffset1 + offset] = popInt();
849                     }
850                     dispatchNextScal();
851                 }
852 
853                 case FBCInstruction::kBlockStoreReal : {
854                     FIRBlockStoreRealInstruction<REAL>* inst = static_cast<FIRBlockStoreRealInstruction<REAL>*>(*it);
855                     assertInterp(inst);
856                     for (int i = 0; i < inst->fOffset2; i++) {
857                         fRealHeap[inst->fOffset1 + i] = inst->fNumTable[i];
858                     }
859                     dispatchNextScal();
860                 }
861 
862                 case FBCInstruction::kBlockStoreInt : {
863                     FIRBlockStoreIntInstruction<REAL>* inst = static_cast<FIRBlockStoreIntInstruction<REAL>*>(*it);
864                     assertInterp(inst);
865                     for (int i = 0; i < inst->fOffset2; i++) {
866                         fIntHeap[inst->fOffset1 + i] = inst->fNumTable[i];
867                     }
868                     dispatchNextScal();
869                 }
870 
871                 case FBCInstruction::kMoveReal : {
872                     fRealHeap[(*it)->fOffset1] = fRealHeap[(*it)->fOffset2];
873                     dispatchNextScal();
874                 }
875 
876                 case FBCInstruction::kMoveInt : {
877                     fIntHeap[(*it)->fOffset1] = fIntHeap[(*it)->fOffset2];
878                     dispatchNextScal();
879                 }
880 
881                 case FBCInstruction::kPairMoveReal : {
882                     fRealHeap[(*it)->fOffset1] = fRealHeap[(*it)->fOffset1 - 1];
883                     fRealHeap[(*it)->fOffset2] = fRealHeap[(*it)->fOffset2 - 1];
884                     dispatchNextScal();
885                 }
886 
887                 case FBCInstruction::kPairMoveInt : {
888                     fIntHeap[(*it)->fOffset1] = fIntHeap[(*it)->fOffset1 - 1];
889                     fIntHeap[(*it)->fOffset2] = fIntHeap[(*it)->fOffset2 - 1];
890                     dispatchNextScal();
891                 }
892 
893                 case FBCInstruction::kBlockPairMoveReal : {
894                     for (int i = (*it)->fOffset1; i < (*it)->fOffset2; i += 2) {
895                         fRealHeap[i + 1] = fRealHeap[i];
896                     }
897                     dispatchNextScal();
898                 }
899 
900                 case FBCInstruction::kBlockPairMoveInt : {
901                     for (int i = (*it)->fOffset1; i < (*it)->fOffset2; i += 2) {
902                         fIntHeap[i + 1] = fIntHeap[i];
903                     }
904                     dispatchNextScal();
905                 }
906 
907                 case FBCInstruction::kBlockShiftReal : {
908                     for (int i = (*it)->fOffset1; i > (*it)->fOffset2; i -= 1) {
909                         fRealHeap[i] = fRealHeap[i - 1];
910                     }
911                     dispatchNextScal();
912                 }
913 
914                 case FBCInstruction::kBlockShiftInt : {
915                     for (int i = (*it)->fOffset1; i > (*it)->fOffset2; i -= 1) {
916                         fIntHeap[i] = fIntHeap[i - 1];
917                     }
918                     dispatchNextScal();
919                 }
920 
921                 // Input/output access
922                 case FBCInstruction::kLoadInput : {
923                     if (TRACE > 0) {
924                         pushReal(it, fInputs[(*it)->fOffset1][assertAudioBuffer(it, popInt())]);
925                     } else {
926                         /*
927                          int index = popInt();
928                          pushReal(it, fInputs[(*it)->fOffset1][index]);
929                          std::cout << "do_kLoadInput " << index << std::endl;
930                          */
931                         pushReal(it, fInputs[(*it)->fOffset1][popInt()]);
932                     }
933                     dispatchNextScal();
934                 }
935 
936                 case FBCInstruction::kStoreOutput : {
937                     if (TRACE > 0) {
938                         fOutputs[(*it)->fOffset1][assertAudioBuffer(it, popInt())] = popReal(it);
939                     } else {
940                         /*
941                          int index = popInt();
942                          std::cout << "do_kStoreOutput " << index << std::endl;
943                          fOutputs[(*it)->fOffset1][index] = popReal(it);
944                          */
945                         fOutputs[(*it)->fOffset1][popInt()] = popReal(it);
946                     }
947                     dispatchNextScal();
948                 }
949 
950                 // Cast operations
951                 case FBCInstruction::kCastReal : {
952                     pushReal(it, REAL(popInt()));
953                     dispatchNextScal();
954                 }
955 
956                 case FBCInstruction::kCastRealHeap : {
957                     pushReal(it, REAL(fIntHeap[(*it)->fOffset1]));
958                     dispatchNextScal();
959                 }
960 
961                 case FBCInstruction::kCastInt : {
962                     if (TRACE >= 3) {
963                         pushInt(int(checkCastIntOverflow(it, popReal(it))));
964                     } else {
965                         pushInt(int(popReal(it)));
966                     }
967                     dispatchNextScal();
968                 }
969 
970                 case FBCInstruction::kCastIntHeap : {
971                     if (TRACE >= 3) {
972                         pushInt(int(checkCastIntOverflow(it, fRealHeap[(*it)->fOffset1])));
973                     } else {
974                         pushInt(int(fRealHeap[(*it)->fOffset1]));
975                     }
976                     dispatchNextScal();
977                 }
978 
979                 // Bitcast operations
980                 case FBCInstruction::kBitcastInt : {
981                     REAL v1 = popReal(it);
982                     int  v2 = *reinterpret_cast<int*>(&v1);
983                     pushInt(v2);
984                     dispatchNextScal();
985                 }
986 
987                 case FBCInstruction::kBitcastReal : {
988                     int  v1 = popInt();
989                     REAL v2 = *reinterpret_cast<REAL*>(&v1);
990                     pushReal(it, v2);
991                     dispatchNextScal();
992                 }
993 
994                 //-------------------------------------------------------
995                 // Standard math operations : 'stack' OP 'stack' version
996                 //-------------------------------------------------------
997 
998                 case FBCInstruction::kAddReal : {
999                     REAL v1 = popReal(it);
1000                     REAL v2 = popReal(it);
1001                     pushReal(it, v1 + v2);
1002                     dispatchNextScal();
1003                 }
1004 
1005                 case FBCInstruction::kAddInt : {
1006                     int v1 = popInt();
1007                     int v2 = popInt();
1008                     if (TRACE > 0) {
1009                         int res;
1010                         if (__builtin_sadd_overflow(v1, v2, &res)) {
1011                             warningOverflow(it);
1012                         }
1013                         pushInt(res);
1014                     } else {
1015                         pushInt(v1 + v2);
1016                     }
1017                     dispatchNextScal();
1018                 }
1019 
1020                 case FBCInstruction::kSubReal : {
1021                     REAL v1 = popReal(it);
1022                     REAL v2 = popReal(it);
1023                     pushReal(it, v1 - v2);
1024                     dispatchNextScal();
1025                 }
1026 
1027                 case FBCInstruction::kSubInt : {
1028                     int v1 = popInt();
1029                     int v2 = popInt();
1030                     if (TRACE > 0) {
1031                         int res;
1032                         if (__builtin_ssub_overflow(v1, v2, &res)) {
1033                             warningOverflow(it);
1034                         }
1035                         pushInt(res);
1036                     } else {
1037                         pushInt(v1 - v2);
1038                     }
1039                     dispatchNextScal();
1040                 }
1041 
1042                 case FBCInstruction::kMultReal : {
1043                     REAL v1 = popReal(it);
1044                     REAL v2 = popReal(it);
1045                     pushReal(it, v1 * v2);
1046                     dispatchNextScal();
1047                 }
1048 
1049                 case FBCInstruction::kMultInt : {
1050                     int v1 = popInt();
1051                     int v2 = popInt();
1052                     if (TRACE > 0) {
1053                         int res;
1054                         if (__builtin_smul_overflow(v1, v2, &res)) {
1055                             warningOverflow(it);
1056                         }
1057                         pushInt(res);
1058                     } else {
1059                         pushInt(v1 * v2);
1060                     }
1061                     dispatchNextScal();
1062                 }
1063 
1064                 case FBCInstruction::kDivReal : {
1065                     REAL v1 = popReal(it);
1066                     REAL v2 = popReal(it);
1067                     if (TRACE > 0) {
1068                         checkDivZero(it, v2);
1069                     }
1070                     pushReal(it, v1 / v2);
1071                     dispatchNextScal();
1072                 }
1073 
1074                 case FBCInstruction::kDivInt : {
1075                     int v1 = popInt();
1076                     int v2 = popInt();
1077                     if (TRACE > 0) {
1078                         checkDivZero(it, v2);
1079                     }
1080                     pushInt(v1 / v2);
1081                     dispatchNextScal();
1082                     dispatchNextScal();
1083                 }
1084 
1085                 //-------------------------------------------------------
1086                 // Standard math operations : 'stack' OP 'stack' version
1087                 //-------------------------------------------------------
1088 
1089                 case FBCInstruction::kRemReal : {
1090                     REAL v1 = popReal(it);
1091                     REAL v2 = popReal(it);
1092                     if (TRACE > 0) {
1093                         checkDivZero(it, v2);
1094                     }
1095                     pushReal(it, std::remainder(v1, v2));
1096                     dispatchNextScal();
1097                 }
1098 
1099                 case FBCInstruction::kRemInt : {
1100                     int v1 = popInt();
1101                     int v2 = popInt();
1102                     if (TRACE > 0) {
1103                         checkDivZero(it, v2);
1104                     }
1105                     pushInt(v1 % v2);
1106                     dispatchNextScal();
1107                 }
1108 
1109                 // Shift operation
1110                 case FBCInstruction::kLshInt : {
1111                     int v1 = popInt();
1112                     int v2 = popInt();
1113                     pushInt(v1 << v2);
1114                     dispatchNextScal();
1115                 }
1116 
1117                 case FBCInstruction::kARshInt : {
1118                     int v1 = popInt();
1119                     int v2 = popInt();
1120                     pushInt(v1 >> v2);
1121                     dispatchNextScal();
1122                 }
1123 
1124                case FBCInstruction::kLRshInt : {
1125                     // TODO
1126                     int v1 = popInt();
1127                     int v2 = popInt();
1128                     pushInt(v1 >> v2);
1129                     dispatchNextScal();
1130                 }
1131 
1132                 // Comparaison Int
1133                 case FBCInstruction::kGTInt : {
1134                     int v1 = popInt();
1135                     int v2 = popInt();
1136                     pushInt(v1 > v2);
1137                     dispatchNextScal();
1138                 }
1139 
1140                 case FBCInstruction::kLTInt : {
1141                     int v1 = popInt();
1142                     int v2 = popInt();
1143                     pushInt(v1 < v2);
1144                     dispatchNextScal();
1145                 }
1146 
1147                 case FBCInstruction::kGEInt : {
1148                     int v1 = popInt();
1149                     int v2 = popInt();
1150                     pushInt(v1 >= v2);
1151                     dispatchNextScal();
1152                 }
1153 
1154                 case FBCInstruction::kLEInt : {
1155                     int v1 = popInt();
1156                     int v2 = popInt();
1157                     pushInt(v1 <= v2);
1158                     dispatchNextScal();
1159                 }
1160 
1161                 case FBCInstruction::kEQInt : {
1162                     int v1 = popInt();
1163                     int v2 = popInt();
1164                     pushInt(v1 == v2);
1165                     dispatchNextScal();
1166                 }
1167 
1168                 case FBCInstruction::kNEInt : {
1169                     int v1 = popInt();
1170                     int v2 = popInt();
1171                     pushInt(v1 != v2);
1172                     dispatchNextScal();
1173                 }
1174 
1175                 // Comparaison Real
1176                 case FBCInstruction::kGTReal : {
1177                     REAL v1 = popReal(it);
1178                     REAL v2 = popReal(it);
1179                     pushInt(v1 > v2);
1180                     dispatchNextScal();
1181                 }
1182 
1183                 case FBCInstruction::kLTReal : {
1184                     REAL v1 = popReal(it);
1185                     REAL v2 = popReal(it);
1186                     pushInt(v1 < v2);
1187                     dispatchNextScal();
1188                 }
1189 
1190                 case FBCInstruction::kGEReal : {
1191                     REAL v1 = popReal(it);
1192                     REAL v2 = popReal(it);
1193                     pushInt(v1 >= v2);
1194                     dispatchNextScal();
1195                 }
1196 
1197                 case FBCInstruction::kLEReal : {
1198                     REAL v1 = popReal(it);
1199                     REAL v2 = popReal(it);
1200                     pushInt(v1 <= v2);
1201                     dispatchNextScal();
1202                 }
1203 
1204                 case FBCInstruction::kEQReal : {
1205                     REAL v1 = popReal(it);
1206                     REAL v2 = popReal(it);
1207                     pushInt(v1 == v2);
1208                     dispatchNextScal();
1209                 }
1210 
1211                 case FBCInstruction::kNEReal : {
1212                     REAL v1 = popReal(it);
1213                     REAL v2 = popReal(it);
1214                     pushInt(v1 != v2);
1215                     dispatchNextScal();
1216                 }
1217 
1218                 // Logical operations
1219                 case FBCInstruction::kANDInt : {
1220                     int v1 = popInt();
1221                     int v2 = popInt();
1222                     pushInt(v1 & v2);
1223                     dispatchNextScal();
1224                 }
1225 
1226                 case FBCInstruction::kORInt : {
1227                     int v1 = popInt();
1228                     int v2 = popInt();
1229                     pushInt(v1 | v2);
1230                     dispatchNextScal();
1231                 }
1232 
1233                 case FBCInstruction::kXORInt : {
1234                     int v1 = popInt();
1235                     int v2 = popInt();
1236                     pushInt(v1 ^ v2);
1237                     dispatchNextScal();
1238                 }
1239 
1240                 //-----------------------------------------------------
1241                 // Standard math operations : 'heap' OP 'heap' version
1242                 //-----------------------------------------------------
1243 
1244                 case FBCInstruction::kAddRealHeap : {
1245                     pushReal(it, fRealHeap[(*it)->fOffset1] + fRealHeap[(*it)->fOffset2]);
1246                     dispatchNextScal();
1247                 }
1248 
1249                 case FBCInstruction::kAddIntHeap : {
1250                     pushInt(fIntHeap[(*it)->fOffset1] + fIntHeap[(*it)->fOffset2]);
1251                     dispatchNextScal();
1252                 }
1253 
1254                 case FBCInstruction::kSubRealHeap : {
1255                     pushReal(it, fRealHeap[(*it)->fOffset1] - fRealHeap[(*it)->fOffset2]);
1256                     dispatchNextScal();
1257                 }
1258 
1259                 case FBCInstruction::kSubIntHeap : {
1260                     pushInt(fIntHeap[(*it)->fOffset1] - fIntHeap[(*it)->fOffset2]);
1261                     dispatchNextScal();
1262                 }
1263 
1264                 case FBCInstruction::kMultRealHeap : {
1265                     pushReal(it, fRealHeap[(*it)->fOffset1] * fRealHeap[(*it)->fOffset2]);
1266                     dispatchNextScal();
1267                 }
1268 
1269                 case FBCInstruction::kMultIntHeap : {
1270                     pushInt(fIntHeap[(*it)->fOffset1] * fIntHeap[(*it)->fOffset2]);
1271                     dispatchNextScal();
1272                 }
1273 
1274                 case FBCInstruction::kDivRealHeap : {
1275                     pushReal(it, fRealHeap[(*it)->fOffset1] / fRealHeap[(*it)->fOffset2]);
1276                     dispatchNextScal();
1277                 }
1278 
1279                 case FBCInstruction::kDivIntHeap : {
1280                     pushInt(fIntHeap[(*it)->fOffset1] / fIntHeap[(*it)->fOffset2]);
1281                     dispatchNextScal();
1282                 }
1283 
1284                 case FBCInstruction::kRemRealHeap : {
1285                     pushReal(it, std::remainder(fRealHeap[(*it)->fOffset1], fRealHeap[(*it)->fOffset2]));
1286                     dispatchNextScal();
1287                 }
1288 
1289                 case FBCInstruction::kRemIntHeap : {
1290                     pushInt(fIntHeap[(*it)->fOffset1] % fIntHeap[(*it)->fOffset2]);
1291                     dispatchNextScal();
1292                 }
1293 
1294                 // Shift operation
1295                 case FBCInstruction::kLshIntHeap : {
1296                     pushInt(fIntHeap[(*it)->fOffset1] << fIntHeap[(*it)->fOffset2]);
1297                     dispatchNextScal();
1298                 }
1299 
1300                 case FBCInstruction::kARshIntHeap : {
1301                     pushInt(fIntHeap[(*it)->fOffset1] >> fIntHeap[(*it)->fOffset2]);
1302                     dispatchNextScal();
1303                 }
1304 
1305                 case FBCInstruction::kLRshIntHeap : {
1306                     // TODO
1307                     pushInt(fIntHeap[(*it)->fOffset1] >> fIntHeap[(*it)->fOffset2]);
1308                     dispatchNextScal();
1309                 }
1310 
1311                 // Comparaison Int
1312                 case FBCInstruction::kGTIntHeap : {
1313                     pushInt(fIntHeap[(*it)->fOffset1] > fIntHeap[(*it)->fOffset2]);
1314                     dispatchNextScal();
1315                 }
1316 
1317                 case FBCInstruction::kLTIntHeap : {
1318                     pushInt(fIntHeap[(*it)->fOffset1] < fIntHeap[(*it)->fOffset2]);
1319                     dispatchNextScal();
1320                 }
1321 
1322                 case FBCInstruction::kGEIntHeap : {
1323                     pushInt(fIntHeap[(*it)->fOffset1] >= fIntHeap[(*it)->fOffset2]);
1324                     dispatchNextScal();
1325                 }
1326 
1327                 case FBCInstruction::kLEIntHeap : {
1328                     pushInt(fIntHeap[(*it)->fOffset1] <= fIntHeap[(*it)->fOffset2]);
1329                     dispatchNextScal();
1330                 }
1331 
1332                 case FBCInstruction::kEQIntHeap : {
1333                     pushInt(fIntHeap[(*it)->fOffset1] == fIntHeap[(*it)->fOffset2]);
1334                     dispatchNextScal();
1335                 }
1336 
1337                 case FBCInstruction::kNEIntHeap : {
1338                     pushInt(fIntHeap[(*it)->fOffset1] != fIntHeap[(*it)->fOffset2]);
1339                     dispatchNextScal();
1340                 }
1341 
1342                 // Comparaison Real
1343                 case FBCInstruction::kGTRealHeap : {
1344                     pushInt(fRealHeap[(*it)->fOffset1] > fRealHeap[(*it)->fOffset2]);
1345                     dispatchNextScal();
1346                 }
1347 
1348                 case FBCInstruction::kLTRealHeap : {
1349                     pushInt(fRealHeap[(*it)->fOffset1] < fRealHeap[(*it)->fOffset2]);
1350                     dispatchNextScal();
1351                 }
1352 
1353                 case FBCInstruction::kGERealHeap : {
1354                     pushInt(fRealHeap[(*it)->fOffset1] >= fRealHeap[(*it)->fOffset2]);
1355                     dispatchNextScal();
1356                 }
1357 
1358                 case FBCInstruction::kLERealHeap : {
1359                     pushInt(fRealHeap[(*it)->fOffset1] <= fRealHeap[(*it)->fOffset2]);
1360                     dispatchNextScal();
1361                 }
1362 
1363                 case FBCInstruction::kEQRealHeap : {
1364                     pushInt(fRealHeap[(*it)->fOffset1] == fRealHeap[(*it)->fOffset2]);
1365                     dispatchNextScal();
1366                 }
1367 
1368                 case FBCInstruction::kNERealHeap : {
1369                     pushInt(fRealHeap[(*it)->fOffset1] != fRealHeap[(*it)->fOffset2]);
1370                     dispatchNextScal();
1371                 }
1372 
1373                 // Logical operations
1374                 case FBCInstruction::kANDIntHeap : {
1375                     pushInt(fIntHeap[(*it)->fOffset1] & fIntHeap[(*it)->fOffset2]);
1376                     dispatchNextScal();
1377                 }
1378 
1379                 case FBCInstruction::kORIntHeap : {
1380                     pushInt(fIntHeap[(*it)->fOffset1] | fIntHeap[(*it)->fOffset2]);
1381                     dispatchNextScal();
1382                 }
1383 
1384                 case FBCInstruction::kXORIntHeap : {
1385                     pushInt(fIntHeap[(*it)->fOffset1] ^ fIntHeap[(*it)->fOffset2]);
1386                     dispatchNextScal();
1387                 }
1388 
1389                 //------------------------------------------------------
1390                 // Standard math operations : 'stack' OP 'heap' version
1391                 //------------------------------------------------------
1392 
1393                 case FBCInstruction::kAddRealStack : {
1394                     REAL v1 = popReal(it);
1395                     pushReal(it, fRealHeap[(*it)->fOffset1] + v1);
1396                     dispatchNextScal();
1397                 }
1398 
1399                 case FBCInstruction::kAddIntStack : {
1400                     int v1 = popInt();
1401                     pushInt(fIntHeap[(*it)->fOffset1] + v1);
1402                     dispatchNextScal();
1403                 }
1404 
1405                 case FBCInstruction::kSubRealStack : {
1406                     REAL v1 = popReal(it);
1407                     pushReal(it, fRealHeap[(*it)->fOffset1] - v1);
1408                     dispatchNextScal();
1409                 }
1410 
1411                 case FBCInstruction::kSubIntStack : {
1412                     int v1 = popInt();
1413                     pushInt(fIntHeap[(*it)->fOffset1] - v1);
1414                     dispatchNextScal();
1415                 }
1416 
1417                 case FBCInstruction::kMultRealStack : {
1418                     REAL v1 = popReal(it);
1419                     pushReal(it, fRealHeap[(*it)->fOffset1] * v1);
1420                     dispatchNextScal();
1421                 }
1422 
1423                 case FBCInstruction::kMultIntStack : {
1424                     int v1 = popInt();
1425                     pushInt(fIntHeap[(*it)->fOffset1] * v1);
1426                     dispatchNextScal();
1427                 }
1428 
1429                 case FBCInstruction::kDivRealStack : {
1430                     REAL v1 = popReal(it);
1431                     pushReal(it, fRealHeap[(*it)->fOffset1] / v1);
1432                     dispatchNextScal();
1433                 }
1434 
1435                 case FBCInstruction::kDivIntStack : {
1436                     int v1 = popInt();
1437                     pushInt(fIntHeap[(*it)->fOffset1] / v1);
1438                     dispatchNextScal();
1439                 }
1440 
1441                 case FBCInstruction::kRemRealStack : {
1442                     REAL v1 = popReal(it);
1443                     pushReal(it, std::remainder(fRealHeap[(*it)->fOffset1], v1));
1444                     dispatchNextScal();
1445                 }
1446 
1447                 case FBCInstruction::kRemIntStack : {
1448                     int v1 = popInt();
1449                     pushInt(fIntHeap[(*it)->fOffset1] % v1);
1450                     dispatchNextScal();
1451                 }
1452 
1453                 // Shift operation
1454                 case FBCInstruction::kLshIntStack : {
1455                     int v1 = popInt();
1456                     pushInt(fIntHeap[(*it)->fOffset1] << v1);
1457                     dispatchNextScal();
1458                 }
1459 
1460                 case FBCInstruction::kARshIntStack : {
1461                     int v1 = popInt();
1462                     pushInt(fIntHeap[(*it)->fOffset1] >> v1);
1463                     dispatchNextScal();
1464                 }
1465 
1466                 case FBCInstruction::kLRshIntStack : {
1467                     // TODO
1468                     int v1 = popInt();
1469                     pushInt(fIntHeap[(*it)->fOffset1] >> v1);
1470                     dispatchNextScal();
1471                 }
1472 
1473                 // Comparaison Int
1474                 case FBCInstruction::kGTIntStack : {
1475                     int v1 = popInt();
1476                     pushInt(fIntHeap[(*it)->fOffset1] > v1);
1477                     dispatchNextScal();
1478                 }
1479 
1480                 case FBCInstruction::kLTIntStack : {
1481                     int v1 = popInt();
1482                     pushInt(fIntHeap[(*it)->fOffset1] < v1);
1483                     dispatchNextScal();
1484                 }
1485 
1486                 case FBCInstruction::kGEIntStack : {
1487                     int v1 = popInt();
1488                     pushInt(fIntHeap[(*it)->fOffset1] >= v1);
1489                     dispatchNextScal();
1490                 }
1491 
1492                 case FBCInstruction::kLEIntStack : {
1493                     int v1 = popInt();
1494                     pushInt(fIntHeap[(*it)->fOffset1] <= v1);
1495                     dispatchNextScal();
1496                 }
1497 
1498                 case FBCInstruction::kEQIntStack : {
1499                     int v1 = popInt();
1500                     pushInt(fIntHeap[(*it)->fOffset1] == v1);
1501                     dispatchNextScal();
1502                 }
1503 
1504                 case FBCInstruction::kNEIntStack : {
1505                     int v1 = popInt();
1506                     pushInt(fIntHeap[(*it)->fOffset1] != v1);
1507                     dispatchNextScal();
1508                 }
1509 
1510                 // Comparaison Real
1511                 case FBCInstruction::kGTRealStack : {
1512                     REAL v1 = popReal(it);
1513                     pushInt(fRealHeap[(*it)->fOffset1] > v1);
1514                     dispatchNextScal();
1515                 }
1516 
1517                 case FBCInstruction::kLTRealStack : {
1518                     REAL v1 = popReal(it);
1519                     pushInt(fRealHeap[(*it)->fOffset1] < v1);
1520                     dispatchNextScal();
1521                 }
1522 
1523                 case FBCInstruction::kGERealStack : {
1524                     REAL v1 = popReal(it);
1525                     pushInt(fRealHeap[(*it)->fOffset1] >= v1);
1526                     dispatchNextScal();
1527                 }
1528 
1529                 case FBCInstruction::kLERealStack : {
1530                     REAL v1 = popReal(it);
1531                     pushInt(fRealHeap[(*it)->fOffset1] <= v1);
1532                     dispatchNextScal();
1533                 }
1534 
1535                 case FBCInstruction::kEQRealStack : {
1536                     REAL v1 = popReal(it);
1537                     pushInt(fRealHeap[(*it)->fOffset1] == v1);
1538                     dispatchNextScal();
1539                 }
1540 
1541                 case FBCInstruction::kNERealStack : {
1542                     REAL v1 = popReal(it);
1543                     pushInt(fRealHeap[(*it)->fOffset1] != v1);
1544                     dispatchNextScal();
1545                 }
1546 
1547                 // Logical operations
1548                 case FBCInstruction::kANDIntStack : {
1549                     int v1 = popInt();
1550                     pushInt(fIntHeap[(*it)->fOffset1] & v1);
1551                     dispatchNextScal();
1552                 }
1553 
1554                 case FBCInstruction::kORIntStack : {
1555                     int v1 = popInt();
1556                     pushInt(fIntHeap[(*it)->fOffset1] | v1);
1557                     dispatchNextScal();
1558                 }
1559 
1560                 case FBCInstruction::kXORIntStack : {
1561                     int v1 = popInt();
1562                     pushInt(fIntHeap[(*it)->fOffset1] ^ v1);
1563                     dispatchNextScal();
1564                 }
1565 
1566                 //-------------------------------------------------------
1567                 // Standard math operations : 'stack' OP 'value' version
1568                 //-------------------------------------------------------
1569 
1570                 case FBCInstruction::kAddRealStackValue : {
1571                     REAL v1 = popReal(it);
1572                     pushReal(it, (*it)->fRealValue + v1);
1573                     dispatchNextScal();
1574                 }
1575 
1576                 case FBCInstruction::kAddIntStackValue : {
1577                     int v1 = popInt();
1578                     pushInt((*it)->fIntValue + v1);
1579                     dispatchNextScal();
1580                 }
1581 
1582                 case FBCInstruction::kSubRealStackValue : {
1583                     REAL v1 = popReal(it);
1584                     pushReal(it, (*it)->fRealValue - v1);
1585                     dispatchNextScal();
1586                 }
1587 
1588                 case FBCInstruction::kSubIntStackValue : {
1589                     int v1 = popInt();
1590                     pushInt((*it)->fIntValue - v1);
1591                     dispatchNextScal();
1592                 }
1593 
1594                 case FBCInstruction::kMultRealStackValue : {
1595                     REAL v1 = popReal(it);
1596                     pushReal(it, (*it)->fRealValue * v1);
1597                     dispatchNextScal();
1598                 }
1599 
1600                 case FBCInstruction::kMultIntStackValue : {
1601                     int v1 = popInt();
1602                     pushInt((*it)->fIntValue * v1);
1603                     dispatchNextScal();
1604                 }
1605 
1606                 case FBCInstruction::kDivRealStackValue : {
1607                     REAL v1 = popReal(it);
1608                     pushReal(it, (*it)->fRealValue / v1);
1609                     dispatchNextScal();
1610                 }
1611 
1612                 case FBCInstruction::kDivIntStackValue : {
1613                     int v1 = popInt();
1614                     pushInt((*it)->fIntValue / v1);
1615                     dispatchNextScal();
1616                 }
1617 
1618                 case FBCInstruction::kRemRealStackValue : {
1619                     REAL v1 = popReal(it);
1620                     pushReal(it, std::remainder((*it)->fRealValue, v1));
1621                     dispatchNextScal();
1622                 }
1623 
1624                 case FBCInstruction::kRemIntStackValue : {
1625                     int v1 = popInt();
1626                     pushInt((*it)->fIntValue % v1);
1627                     dispatchNextScal();
1628                 }
1629 
1630                 // Shift operation
1631                 case FBCInstruction::kLshIntStackValue : {
1632                     int v1 = popInt();
1633                     pushInt((*it)->fIntValue << v1);
1634                     dispatchNextScal();
1635                 }
1636 
1637                 case FBCInstruction::kARshIntStackValue : {
1638                     int v1 = popInt();
1639                     pushInt((*it)->fIntValue >> v1);
1640                     dispatchNextScal();
1641                 }
1642 
1643                 case FBCInstruction::kLRshIntStackValue : {
1644                     // TODO
1645                     int v1 = popInt();
1646                     pushInt((*it)->fIntValue >> v1);
1647                     dispatchNextScal();
1648                 }
1649 
1650                 // Comparaison Int
1651                 case FBCInstruction::kGTIntStackValue : {
1652                     int v1 = popInt();
1653                     pushInt((*it)->fIntValue > v1);
1654                     dispatchNextScal();
1655                 }
1656 
1657                 case FBCInstruction::kLTIntStackValue : {
1658                     int v1 = popInt();
1659                     pushInt((*it)->fIntValue < v1);
1660                     dispatchNextScal();
1661                 }
1662 
1663                 case FBCInstruction::kGEIntStackValue : {
1664                     int v1 = popInt();
1665                     pushInt((*it)->fIntValue >= v1);
1666                     dispatchNextScal();
1667                 }
1668 
1669                 case FBCInstruction::kLEIntStackValue : {
1670                     int v1 = popInt();
1671                     pushInt((*it)->fIntValue <= v1);
1672                     dispatchNextScal();
1673                 }
1674 
1675                 case FBCInstruction::kEQIntStackValue : {
1676                     int v1 = popInt();
1677                     pushInt((*it)->fIntValue == v1);
1678                     dispatchNextScal();
1679                 }
1680 
1681                 case FBCInstruction::kNEIntStackValue : {
1682                     int v1 = popInt();
1683                     pushInt((*it)->fIntValue != v1);
1684                     dispatchNextScal();
1685                 }
1686 
1687                 // Comparaison Real
1688                 case FBCInstruction::kGTRealStackValue : {
1689                     REAL v1 = popReal(it);
1690                     pushInt((*it)->fRealValue > v1);
1691                     dispatchNextScal();
1692                 }
1693 
1694                 case FBCInstruction::kLTRealStackValue : {
1695                     REAL v1 = popReal(it);
1696                     pushInt((*it)->fRealValue < v1);
1697                     dispatchNextScal();
1698                 }
1699 
1700                 case FBCInstruction::kGERealStackValue : {
1701                     REAL v1 = popReal(it);
1702                     pushInt((*it)->fRealValue >= v1);
1703                     dispatchNextScal();
1704                 }
1705 
1706                 case FBCInstruction::kLERealStackValue : {
1707                     REAL v1 = popReal(it);
1708                     pushInt((*it)->fRealValue <= v1);
1709                     dispatchNextScal();
1710                 }
1711 
1712                 case FBCInstruction::kEQRealStackValue : {
1713                     REAL v1 = popReal(it);
1714                     pushInt((*it)->fRealValue == v1);
1715                     dispatchNextScal();
1716                 }
1717 
1718                 case FBCInstruction::kNERealStackValue : {
1719                     REAL v1 = popReal(it);
1720                     pushInt((*it)->fRealValue != v1);
1721                     dispatchNextScal();
1722                 }
1723 
1724                 // Logical operations
1725                 case FBCInstruction::kANDIntStackValue : {
1726                     int v1 = popInt();
1727                     pushInt((*it)->fIntValue & v1);
1728                     dispatchNextScal();
1729                 }
1730 
1731                 case FBCInstruction::kORIntStackValue : {
1732                     int v1 = popInt();
1733                     pushInt((*it)->fIntValue | v1);
1734                     dispatchNextScal();
1735                 }
1736 
1737                 case FBCInstruction::kXORIntStackValue : {
1738                     int v1 = popInt();
1739                     pushInt((*it)->fIntValue ^ v1);
1740                     dispatchNextScal();
1741                 }
1742 
1743                 //------------------------------------------------------
1744                 // Standard math operations : 'value' OP 'heap' version
1745                 //------------------------------------------------------
1746 
1747                 case FBCInstruction::kAddRealValue : {
1748                     pushReal(it, (*it)->fRealValue + fRealHeap[(*it)->fOffset1]);
1749                     dispatchNextScal();
1750                 }
1751 
1752                 case FBCInstruction::kAddIntValue : {
1753                     pushInt((*it)->fIntValue + fIntHeap[(*it)->fOffset1]);
1754                     dispatchNextScal();
1755                 }
1756 
1757                 case FBCInstruction::kSubRealValue : {
1758                     pushReal(it, (*it)->fRealValue - fRealHeap[(*it)->fOffset1]);
1759                     dispatchNextScal();
1760                 }
1761 
1762                 case FBCInstruction::kSubIntValue : {
1763                     pushInt((*it)->fIntValue - fIntHeap[(*it)->fOffset1]);
1764                     dispatchNextScal();
1765                 }
1766 
1767                 case FBCInstruction::kMultRealValue : {
1768                     pushReal(it, (*it)->fRealValue * fRealHeap[(*it)->fOffset1]);
1769                     dispatchNextScal();
1770                 }
1771 
1772                 case FBCInstruction::kMultIntValue : {
1773                     pushInt((*it)->fIntValue * fIntHeap[(*it)->fOffset1]);
1774                     dispatchNextScal();
1775                 }
1776 
1777                 case FBCInstruction::kDivRealValue : {
1778                     pushReal(it, (*it)->fRealValue / fRealHeap[(*it)->fOffset1]);
1779                     dispatchNextScal();
1780                 }
1781 
1782                 case FBCInstruction::kDivIntValue : {
1783                     pushInt((*it)->fIntValue / fIntHeap[(*it)->fOffset1]);
1784                     dispatchNextScal();
1785                 }
1786 
1787                 case FBCInstruction::kRemRealValue : {
1788                     pushReal(it, std::remainder((*it)->fRealValue, fRealHeap[(*it)->fOffset1]));
1789                     dispatchNextScal();
1790                 }
1791 
1792                 case FBCInstruction::kRemIntValue : {
1793                     pushInt((*it)->fIntValue % fIntHeap[(*it)->fOffset1]);
1794                     dispatchNextScal();
1795                 }
1796 
1797                 // Shift operation
1798                 case FBCInstruction::kLshIntValue : {
1799                     pushInt((*it)->fIntValue << fIntHeap[(*it)->fOffset1]);
1800                     dispatchNextScal();
1801                 }
1802 
1803                 case FBCInstruction::kARshIntValue : {
1804                     pushInt((*it)->fIntValue >> fIntHeap[(*it)->fOffset1]);
1805                     dispatchNextScal();
1806                 }
1807 
1808                 case FBCInstruction::kLRshIntValue : {
1809                     // TODO
1810                     pushInt((*it)->fIntValue >> fIntHeap[(*it)->fOffset1]);
1811                     dispatchNextScal();
1812                 }
1813 
1814                 // Comparaison Int
1815                 case FBCInstruction::kGTIntValue : {
1816                     pushInt((*it)->fIntValue > fIntHeap[(*it)->fOffset1]);
1817                     dispatchNextScal();
1818                 }
1819 
1820                 case FBCInstruction::kLTIntValue : {
1821                     pushInt((*it)->fIntValue < fIntHeap[(*it)->fOffset1]);
1822                     dispatchNextScal();
1823                 }
1824 
1825                 case FBCInstruction::kGEIntValue : {
1826                     pushInt((*it)->fIntValue >= fIntHeap[(*it)->fOffset1]);
1827                     dispatchNextScal();
1828                 }
1829 
1830                 case FBCInstruction::kLEIntValue : {
1831                     pushInt((*it)->fIntValue <= fIntHeap[(*it)->fOffset1]);
1832                     dispatchNextScal();
1833                 }
1834 
1835                 case FBCInstruction::kEQIntValue : {
1836                     pushInt((*it)->fIntValue == fIntHeap[(*it)->fOffset1]);
1837                     dispatchNextScal();
1838                 }
1839 
1840                 case FBCInstruction::kNEIntValue : {
1841                     pushInt((*it)->fIntValue != fIntHeap[(*it)->fOffset1]);
1842                     dispatchNextScal();
1843                 }
1844 
1845                 // Comparaison Real
1846                 case FBCInstruction::kGTRealValue : {
1847                     pushInt((*it)->fRealValue > fRealHeap[(*it)->fOffset1]);
1848                     dispatchNextScal();
1849                 }
1850 
1851                 case FBCInstruction::kLTRealValue : {
1852                     pushInt((*it)->fRealValue < fRealHeap[(*it)->fOffset1]);
1853                     dispatchNextScal();
1854                 }
1855 
1856                 case FBCInstruction::kGERealValue : {
1857                     pushInt((*it)->fRealValue >= fRealHeap[(*it)->fOffset1]);
1858                     dispatchNextScal();
1859                 }
1860 
1861                 case FBCInstruction::kLERealValue : {
1862                     pushInt((*it)->fRealValue <= fRealHeap[(*it)->fOffset1]);
1863                     dispatchNextScal();
1864                 }
1865 
1866                 case FBCInstruction::kEQRealValue : {
1867                     pushInt((*it)->fRealValue == fRealHeap[(*it)->fOffset1]);
1868                     dispatchNextScal();
1869                 }
1870 
1871                 case FBCInstruction::kNERealValue : {
1872                     pushInt((*it)->fRealValue != fRealHeap[(*it)->fOffset1]);
1873                     dispatchNextScal();
1874                 }
1875 
1876                 // Logical operations
1877                 case FBCInstruction::kANDIntValue : {
1878                     pushInt((*it)->fIntValue & fIntHeap[(*it)->fOffset1]);
1879                     dispatchNextScal();
1880                 }
1881 
1882                 case FBCInstruction::kORIntValue : {
1883                     pushInt((*it)->fIntValue | fIntHeap[(*it)->fOffset1]);
1884                     dispatchNextScal();
1885                 }
1886 
1887                 case FBCInstruction::kXORIntValue : {
1888                     pushInt((*it)->fIntValue ^ fIntHeap[(*it)->fOffset1]);
1889                     dispatchNextScal();
1890                 }
1891 
1892                 //----------------------------------------------------
1893                 // Standard math operations : Value inverted version
1894                 // (non commutative operations)
1895                 //----------------------------------------------------
1896 
1897                 case FBCInstruction::kSubRealValueInvert : {
1898                     pushReal(it, fRealHeap[(*it)->fOffset1] - (*it)->fRealValue);
1899                     dispatchNextScal();
1900                 }
1901 
1902                 case FBCInstruction::kSubIntValueInvert : {
1903                     pushInt(fIntHeap[(*it)->fOffset1] - (*it)->fIntValue);
1904                     dispatchNextScal();
1905                 }
1906 
1907                 case FBCInstruction::kDivRealValueInvert : {
1908                     pushReal(it, fRealHeap[(*it)->fOffset1] / (*it)->fRealValue);
1909                     dispatchNextScal();
1910                 }
1911 
1912                 case FBCInstruction::kDivIntValueInvert : {
1913                     pushInt(fIntHeap[(*it)->fOffset1] / (*it)->fIntValue);
1914                     dispatchNextScal();
1915                 }
1916 
1917                 case FBCInstruction::kRemRealValueInvert : {
1918                     pushReal(it, std::remainder(fRealHeap[(*it)->fOffset1], (*it)->fRealValue));
1919                     dispatchNextScal();
1920                 }
1921 
1922                 case FBCInstruction::kRemIntValueInvert : {
1923                     pushInt(fIntHeap[(*it)->fOffset1] % (*it)->fIntValue);
1924                     dispatchNextScal();
1925                 }
1926 
1927                 // Shift operation
1928                 case FBCInstruction::kLshIntValueInvert : {
1929                     pushInt(fIntHeap[(*it)->fOffset1] << (*it)->fIntValue);
1930                     dispatchNextScal();
1931                 }
1932 
1933                 case FBCInstruction::kARshIntValueInvert : {
1934                     pushInt(fIntHeap[(*it)->fOffset1] >> (*it)->fIntValue);
1935                     dispatchNextScal();
1936                 }
1937 
1938                 case FBCInstruction::kLRshIntValueInvert : {
1939                     // TODO
1940                     pushInt(fIntHeap[(*it)->fOffset1] >> (*it)->fIntValue);
1941                     dispatchNextScal();
1942                 }
1943 
1944                 // Comparaison Int
1945                 case FBCInstruction::kGTIntValueInvert : {
1946                     pushInt(fIntHeap[(*it)->fOffset1] > (*it)->fIntValue);
1947                     dispatchNextScal();
1948                 }
1949 
1950                 case FBCInstruction::kLTIntValueInvert : {
1951                     pushInt(fIntHeap[(*it)->fOffset1] < (*it)->fIntValue);
1952                     dispatchNextScal();
1953                 }
1954 
1955                 case FBCInstruction::kGEIntValueInvert : {
1956                     pushInt(fIntHeap[(*it)->fOffset1] >= (*it)->fIntValue);
1957                     dispatchNextScal();
1958                 }
1959 
1960                 case FBCInstruction::kLEIntValueInvert : {
1961                     pushInt(fIntHeap[(*it)->fOffset1] <= (*it)->fIntValue);
1962                     dispatchNextScal();
1963                 }
1964 
1965                 // Comparaison Real
1966                 case FBCInstruction::kGTRealValueInvert : {
1967                     pushInt(fRealHeap[(*it)->fOffset1] > (*it)->fRealValue);
1968                     dispatchNextScal();
1969                 }
1970 
1971                 case FBCInstruction::kLTRealValueInvert : {
1972                     pushInt(fRealHeap[(*it)->fOffset1] < (*it)->fRealValue);
1973                     dispatchNextScal();
1974                 }
1975 
1976                 case FBCInstruction::kGERealValueInvert : {
1977                     pushInt(fRealHeap[(*it)->fOffset1] >= (*it)->fRealValue);
1978                     dispatchNextScal();
1979                 }
1980 
1981                 case FBCInstruction::kLERealValueInvert : {
1982                     pushInt(fRealHeap[(*it)->fOffset1] <= (*it)->fRealValue);
1983                     dispatchNextScal();
1984                 }
1985 
1986                 //---------------------
1987                 // Extended unary math
1988                 //---------------------
1989 
1990                 case FBCInstruction::kAbs : {
1991                     int v = popInt();
1992                     pushInt(std::abs(v));
1993                     dispatchNextScal();
1994                 }
1995 
1996                 case FBCInstruction::kAbsf : {
1997                     REAL v = popReal(it);
1998                     pushReal(it, std::fabs(v));
1999                     dispatchNextScal();
2000                 }
2001 
2002                 case FBCInstruction::kAcosf : {
2003                     REAL v = popReal(it);
2004                     pushReal(it, std::acos(v));
2005                     dispatchNextScal();
2006                 }
2007 
2008                 case FBCInstruction::kAcoshf : {
2009                     REAL v = popReal(it);
2010                     pushReal(it, std::acosh(v));
2011                     dispatchNextScal();
2012                 }
2013 
2014                 case FBCInstruction::kAsinf : {
2015                     REAL v = popReal(it);
2016                     pushReal(it, std::asin(v));
2017                     dispatchNextScal();
2018                 }
2019 
2020                 case FBCInstruction::kAsinhf : {
2021                     REAL v = popReal(it);
2022                     pushReal(it, std::asinh(v));
2023                     dispatchNextScal();
2024                 }
2025 
2026                 case FBCInstruction::kAtanf : {
2027                     REAL v = popReal(it);
2028                     pushReal(it, std::atan(v));
2029                     dispatchNextScal();
2030                 }
2031 
2032                 case FBCInstruction::kAtanhf : {
2033                     REAL v = popReal(it);
2034                     pushReal(it, std::atanh(v));
2035                     dispatchNextScal();
2036                 }
2037 
2038                 case FBCInstruction::kCeilf : {
2039                     REAL v = popReal(it);
2040                     pushReal(it, std::ceil(v));
2041                     dispatchNextScal();
2042                 }
2043 
2044                 case FBCInstruction::kCosf : {
2045                     REAL v = popReal(it);
2046                     pushReal(it, std::cos(v));
2047                     dispatchNextScal();
2048                 }
2049 
2050                 case FBCInstruction::kCoshf : {
2051                     REAL v = popReal(it);
2052                     pushReal(it, std::cosh(v));
2053                     dispatchNextScal();
2054                 }
2055 
2056                 case FBCInstruction::kExpf : {
2057                     REAL v = popReal(it);
2058                     pushReal(it, std::exp(v));
2059                     dispatchNextScal();
2060                 }
2061 
2062                 case FBCInstruction::kFloorf : {
2063                     REAL v = popReal(it);
2064                     pushReal(it, std::floor(v));
2065                     dispatchNextScal();
2066                 }
2067 
2068                 case FBCInstruction::kLogf : {
2069                     REAL v = popReal(it);
2070                     pushReal(it, std::log(v));
2071                     dispatchNextScal();
2072                 }
2073 
2074                 case FBCInstruction::kLog10f : {
2075                     REAL v = popReal(it);
2076                     pushReal(it, std::log10(v));
2077                     dispatchNextScal();
2078                 }
2079 
2080                 case FBCInstruction::kRintf : {
2081                     REAL v = popReal(it);
2082                     pushReal(it, std::rint(v));
2083                     dispatchNextScal();
2084                 }
2085 
2086                 case FBCInstruction::kRoundf : {
2087                     REAL v = popReal(it);
2088                     pushReal(it, std::round(v));
2089                     dispatchNextScal();
2090                 }
2091 
2092                 case FBCInstruction::kSinf : {
2093                     REAL v = popReal(it);
2094                     pushReal(it, std::sin(v));
2095                     dispatchNextScal();
2096                 }
2097 
2098                 case FBCInstruction::kSinhf : {
2099                     REAL v = popReal(it);
2100                     pushReal(it, std::sinh(v));
2101                     dispatchNextScal();
2102                 }
2103 
2104                 case FBCInstruction::kSqrtf : {
2105                     REAL v = popReal(it);
2106                     pushReal(it, std::sqrt(v));
2107                     dispatchNextScal();
2108                 }
2109 
2110                 case FBCInstruction::kTanf : {
2111                     REAL v = popReal(it);
2112                     pushReal(it, std::tan(v));
2113                     dispatchNextScal();
2114                 }
2115 
2116                 case FBCInstruction::kTanhf : {
2117                     REAL v = popReal(it);
2118                     pushReal(it, std::tanh(v));
2119                     dispatchNextScal();
2120                 }
2121 
2122                 case FBCInstruction::kIsnanf : {
2123                     REAL v = popReal(it);
2124                     pushInt(std::isnan(v));
2125                     dispatchNextScal();
2126                 }
2127 
2128                 case FBCInstruction::kIsinff : {
2129                     REAL v = popReal(it);
2130                     pushInt(std::isinf(v));
2131                     dispatchNextScal();
2132                 }
2133 
2134                 //------------------------------------
2135                 // Extended unary math (heap version)
2136                 //------------------------------------
2137 
2138                 case FBCInstruction::kAbsHeap : {
2139                     pushInt(std::abs(fIntHeap[(*it)->fOffset1]));
2140                     dispatchNextScal();
2141                 }
2142 
2143                 case FBCInstruction::kAbsfHeap : {
2144                     pushReal(it, std::fabs(fRealHeap[(*it)->fOffset1]));
2145                     dispatchNextScal();
2146                 }
2147 
2148                 case FBCInstruction::kAcosfHeap : {
2149                     pushReal(it, std::acos(fRealHeap[(*it)->fOffset1]));
2150                     dispatchNextScal();
2151                 }
2152 
2153                 case FBCInstruction::kAcoshfHeap : {
2154                     pushReal(it, std::acosh(fRealHeap[(*it)->fOffset1]));
2155                     dispatchNextScal();
2156                 }
2157 
2158                 case FBCInstruction::kAsinfHeap : {
2159                     pushReal(it, std::asin(fRealHeap[(*it)->fOffset1]));
2160                     dispatchNextScal();
2161                 }
2162 
2163                 case FBCInstruction::kAsinhfHeap : {
2164                     pushReal(it, std::asinh(fRealHeap[(*it)->fOffset1]));
2165                     dispatchNextScal();
2166                 }
2167 
2168                 case FBCInstruction::kAtanfHeap : {
2169                     pushReal(it, std::atan(fRealHeap[(*it)->fOffset1]));
2170                     dispatchNextScal();
2171                 }
2172 
2173                 case FBCInstruction::kAtanhfHeap : {
2174                     pushReal(it, std::atanh(fRealHeap[(*it)->fOffset1]));
2175                     dispatchNextScal();
2176                 }
2177 
2178                 case FBCInstruction::kCeilfHeap : {
2179                     pushReal(it, std::ceil(fRealHeap[(*it)->fOffset1]));
2180                     dispatchNextScal();
2181                 }
2182 
2183                 case FBCInstruction::kCosfHeap : {
2184                     pushReal(it, std::cos(fRealHeap[(*it)->fOffset1]));
2185                     dispatchNextScal();
2186                 }
2187 
2188                 case FBCInstruction::kCoshfHeap : {
2189                     pushReal(it, std::cosh(fRealHeap[(*it)->fOffset1]));
2190                     dispatchNextScal();
2191                 }
2192 
2193                 case FBCInstruction::kExpfHeap : {
2194                     pushReal(it, std::exp(fRealHeap[(*it)->fOffset1]));
2195                     dispatchNextScal();
2196                 }
2197 
2198                 case FBCInstruction::kFloorfHeap : {
2199                     pushReal(it, std::floor(fRealHeap[(*it)->fOffset1]));
2200                     dispatchNextScal();
2201                 }
2202 
2203                 case FBCInstruction::kLogfHeap : {
2204                     pushReal(it, std::log(fRealHeap[(*it)->fOffset1]));
2205                     dispatchNextScal();
2206                 }
2207 
2208                 case FBCInstruction::kLog10fHeap : {
2209                     pushReal(it, std::log10(fRealHeap[(*it)->fOffset1]));
2210                     dispatchNextScal();
2211                 }
2212 
2213                 case FBCInstruction::kRintfHeap : {
2214                     pushReal(it, std::rint(fRealHeap[(*it)->fOffset1]));
2215                     dispatchNextScal();
2216                 }
2217 
2218                 case FBCInstruction::kRoundfHeap : {
2219                     pushReal(it, std::round(fRealHeap[(*it)->fOffset1]));
2220                     dispatchNextScal();
2221                 }
2222 
2223                 case FBCInstruction::kSinfHeap : {
2224                     pushReal(it, std::sin(fRealHeap[(*it)->fOffset1]));
2225                     dispatchNextScal();
2226                 }
2227 
2228                 case FBCInstruction::kSinhfHeap : {
2229                     pushReal(it, std::sinh(fRealHeap[(*it)->fOffset1]));
2230                     dispatchNextScal();
2231                 }
2232 
2233                 case FBCInstruction::kSqrtfHeap : {
2234                     pushReal(it, std::sqrt(fRealHeap[(*it)->fOffset1]));
2235                     dispatchNextScal();
2236                 }
2237 
2238                 case FBCInstruction::kTanfHeap : {
2239                     pushReal(it, std::tan(fRealHeap[(*it)->fOffset1]));
2240                     dispatchNextScal();
2241                 }
2242 
2243                 case FBCInstruction::kTanhfHeap : {
2244                     pushReal(it, std::tanh(fRealHeap[(*it)->fOffset1]));
2245                     dispatchNextScal();
2246                 }
2247 
2248                 //----------------------
2249                 // Extended binary math
2250                 //----------------------
2251 
2252                 case FBCInstruction::kAtan2f : {
2253                     REAL v1 = popReal(it);
2254                     REAL v2 = popReal(it);
2255                     pushReal(it, std::atan2(v1, v2));
2256                     dispatchNextScal();
2257                 }
2258 
2259                 case FBCInstruction::kFmodf : {
2260                     REAL v1 = popReal(it);
2261                     REAL v2 = popReal(it);
2262                     pushReal(it, std::fmod(v1, v2));
2263                     dispatchNextScal();
2264                 }
2265 
2266                 case FBCInstruction::kPowf : {
2267                     REAL v1 = popReal(it);
2268                     REAL v2 = popReal(it);
2269                     pushReal(it, std::pow(v1, v2));
2270                     dispatchNextScal();
2271                 }
2272 
2273                 case FBCInstruction::kMax : {
2274                     int v1 = popInt();
2275                     int v2 = popInt();
2276                     pushInt(std::max(v1, v2));
2277                     dispatchNextScal();
2278                 }
2279 
2280                 case FBCInstruction::kMaxf : {
2281                     REAL v1 = popReal(it);
2282                     REAL v2 = popReal(it);
2283                     pushReal(it, std::max(v1, v2));
2284                     dispatchNextScal();
2285                 }
2286 
2287                 case FBCInstruction::kMin : {
2288                     int v1 = popInt();
2289                     int v2 = popInt();
2290                     pushInt(std::min(v1, v2));
2291                     dispatchNextScal();
2292                 }
2293 
2294                 case FBCInstruction::kMinf : {
2295                     REAL v1 = popReal(it);
2296                     REAL v2 = popReal(it);
2297                     pushReal(it, std::min(v1, v2));
2298                     dispatchNextScal();
2299                 }
2300 
2301                 case FBCInstruction::kCopysignf : {
2302                     REAL v1 = popReal(it);
2303                     REAL v2 = popReal(it);
2304                     pushReal(it, std::copysign(v1, v2));
2305                     dispatchNextScal();
2306                 }
2307 
2308                 //-------------------------------------
2309                 // Extended binary math (heap version)
2310                 //-------------------------------------
2311 
2312                 case FBCInstruction::kAtan2fHeap : {
2313                     pushReal(it, std::atan2(fRealHeap[(*it)->fOffset1], fRealHeap[(*it)->fOffset2]));
2314                     dispatchNextScal();
2315                 }
2316 
2317                 case FBCInstruction::kFmodfHeap : {
2318                     pushReal(it, std::fmod(fRealHeap[(*it)->fOffset1], fRealHeap[(*it)->fOffset2]));
2319                     dispatchNextScal();
2320                 }
2321 
2322                 case FBCInstruction::kPowfHeap : {
2323                     pushReal(it, std::pow(fRealHeap[(*it)->fOffset1], fRealHeap[(*it)->fOffset2]));
2324                     dispatchNextScal();
2325                 }
2326 
2327                 case FBCInstruction::kMaxHeap : {
2328                     pushInt(std::max(fIntHeap[(*it)->fOffset1], fIntHeap[(*it)->fOffset2]));
2329                     dispatchNextScal();
2330                 }
2331 
2332                 case FBCInstruction::kMaxfHeap : {
2333                     pushReal(it, std::max(fRealHeap[(*it)->fOffset1], fRealHeap[(*it)->fOffset2]));
2334                     dispatchNextScal();
2335                 }
2336 
2337                 case FBCInstruction::kMinHeap : {
2338                     pushInt(std::min(fIntHeap[(*it)->fOffset1], fIntHeap[(*it)->fOffset2]));
2339                     dispatchNextScal();
2340                 }
2341 
2342                 case FBCInstruction::kMinfHeap : {
2343                     pushReal(it, std::min(fRealHeap[(*it)->fOffset1], fRealHeap[(*it)->fOffset2]));
2344                     dispatchNextScal();
2345                 }
2346 
2347                 //--------------------------------------
2348                 // Extended binary math (stack version)
2349                 //--------------------------------------
2350 
2351                 case FBCInstruction::kAtan2fStack : {
2352                     REAL v1 = popReal(it);
2353                     pushReal(it, std::atan2(fRealHeap[(*it)->fOffset1], v1));
2354                     dispatchNextScal();
2355                 }
2356 
2357                 case FBCInstruction::kFmodfStack : {
2358                     REAL v1 = popReal(it);
2359                     pushReal(it, std::fmod(fRealHeap[(*it)->fOffset1], v1));
2360                     dispatchNextScal();
2361                 }
2362 
2363                 case FBCInstruction::kPowfStack : {
2364                     REAL v1 = popReal(it);
2365                     pushReal(it, std::pow(fRealHeap[(*it)->fOffset1], v1));
2366                     dispatchNextScal();
2367                 }
2368 
2369                 case FBCInstruction::kMaxStack : {
2370                     int v1 = popInt();
2371                     pushInt(std::max(fIntHeap[(*it)->fOffset1], v1));
2372                     dispatchNextScal();
2373                 }
2374 
2375                 case FBCInstruction::kMaxfStack : {
2376                     REAL v1 = popReal(it);
2377                     pushReal(it, std::max(fRealHeap[(*it)->fOffset1], v1));
2378                     dispatchNextScal();
2379                 }
2380 
2381                 case FBCInstruction::kMinStack : {
2382                     int v1 = popInt();
2383                     pushInt(std::min(fIntHeap[(*it)->fOffset1], v1));
2384                     dispatchNextScal();
2385                 }
2386 
2387                 case FBCInstruction::kMinfStack : {
2388                     REAL v1 = popReal(it);
2389                     pushReal(it, std::min(fRealHeap[(*it)->fOffset1], v1));
2390                     dispatchNextScal();
2391                 }
2392 
2393                 //--------------------------------------------
2394                 // Extended binary math (stack/value version)
2395                 //--------------------------------------------
2396 
2397                 case FBCInstruction::kAtan2fStackValue : {
2398                     REAL v1 = popReal(it);
2399                     pushReal(it, std::atan2((*it)->fRealValue, v1));
2400                     dispatchNextScal();
2401                 }
2402 
2403                 case FBCInstruction::kFmodfStackValue : {
2404                     REAL v1 = popReal(it);
2405                     pushReal(it, std::fmod((*it)->fRealValue, v1));
2406                     dispatchNextScal();
2407                 }
2408 
2409                 case FBCInstruction::kPowfStackValue : {
2410                     REAL v1 = popReal(it);
2411                     pushReal(it, std::pow((*it)->fRealValue, v1));
2412                     dispatchNextScal();
2413                 }
2414 
2415                 case FBCInstruction::kMaxStackValue : {
2416                     int v1 = popInt();
2417                     pushInt(std::max((*it)->fIntValue, v1));
2418                     dispatchNextScal();
2419                 }
2420 
2421                 case FBCInstruction::kMaxfStackValue : {
2422                     REAL v1 = popReal(it);
2423                     pushReal(it, std::max((*it)->fRealValue, v1));
2424                     dispatchNextScal();
2425                 }
2426 
2427                 case FBCInstruction::kMinStackValue : {
2428                     int v1 = popInt();
2429                     pushInt(std::min((*it)->fIntValue, v1));
2430                     dispatchNextScal();
2431                 }
2432 
2433                 case FBCInstruction::kMinfStackValue : {
2434                     REAL v1 = popReal(it);
2435                     pushReal(it, std::min((*it)->fRealValue, v1));
2436                     dispatchNextScal();
2437                 }
2438 
2439                 //-------------------------------------
2440                 // Extended binary math (Value version)
2441                 //-------------------------------------
2442 
2443                 case FBCInstruction::kAtan2fValue : {
2444                     pushReal(it, std::atan2((*it)->fRealValue, fRealHeap[(*it)->fOffset1]));
2445                     dispatchNextScal();
2446                 }
2447 
2448                 case FBCInstruction::kFmodfValue : {
2449                     pushReal(it, std::fmod((*it)->fRealValue, fRealHeap[(*it)->fOffset1]));
2450                     dispatchNextScal();
2451                 }
2452 
2453                 case FBCInstruction::kPowfValue : {
2454                     pushReal(it, std::pow((*it)->fRealValue, fRealHeap[(*it)->fOffset1]));
2455                     dispatchNextScal();
2456                 }
2457 
2458                 case FBCInstruction::kMaxValue : {
2459                     pushInt(std::max((*it)->fIntValue, fIntHeap[(*it)->fOffset1]));
2460                     dispatchNextScal();
2461                 }
2462 
2463                 case FBCInstruction::kMaxfValue : {
2464                     pushReal(it, std::max((*it)->fRealValue, fRealHeap[(*it)->fOffset1]));
2465                     dispatchNextScal();
2466                 }
2467 
2468                 case FBCInstruction::kMinValue : {
2469                     pushInt(std::min((*it)->fIntValue, fIntHeap[(*it)->fOffset1]));
2470                     dispatchNextScal();
2471                 }
2472 
2473                 case FBCInstruction::kMinfValue : {
2474                     pushReal(it, std::min((*it)->fRealValue, fRealHeap[(*it)->fOffset1]));
2475                     dispatchNextScal();
2476                 }
2477 
2478                 //-------------------------------------------------------------------
2479                 // Extended binary math (Value version) : non commutative operations
2480                 //-------------------------------------------------------------------
2481 
2482                 case FBCInstruction::kAtan2fValueInvert : {
2483                     pushReal(it, std::atan2(fRealHeap[(*it)->fOffset1], (*it)->fRealValue));
2484                     dispatchNextScal();
2485                 }
2486 
2487                 case FBCInstruction::kFmodfValueInvert : {
2488                     pushReal(it, std::fmod(fRealHeap[(*it)->fOffset1], (*it)->fRealValue));
2489                     dispatchNextScal();
2490                 }
2491 
2492                 case FBCInstruction::kPowfValueInvert : {
2493                     pushReal(it, std::pow(fRealHeap[(*it)->fOffset1], (*it)->fRealValue));
2494                     dispatchNextScal();
2495                 }
2496 
2497                 //---------
2498                 // Control
2499                 //---------
2500 
2501                 case FBCInstruction::kReturn : {
2502                     // Empty addr stack = end of computation
2503                     if (emptyReturnScal()) {
2504                         goto end;
2505                     } else {
2506                         dispatchReturnScal();
2507                     }
2508                 }
2509 
2510                 case FBCInstruction::kIf : {
2511                     // Keep next instruction
2512                     saveReturnScal();
2513 
2514                     if (popInt()) {
2515                         // Execute new block
2516                         assertInterp((*it)->fBranch1);
2517                         dispatchBranch1Scal();
2518                         // No value (If)
2519                     } else {
2520                         // Execute new block
2521                         assertInterp((*it)->fBranch2);
2522                         dispatchBranch2Scal();
2523                         // No value (If)
2524                     }
2525                 }
2526 
2527                 case FBCInstruction::kSelectReal : {
2528                     // Keep next instruction
2529                     saveReturnScal();
2530 
2531                     if (popInt()) {
2532                         // Execute new block
2533                         assertInterp((*it)->fBranch1);
2534                         dispatchBranch1Scal();
2535                         // Real value
2536                     } else {
2537                         // Execute new block
2538                         assertInterp((*it)->fBranch2);
2539                         dispatchBranch2Scal();
2540                         // Real value
2541                     }
2542                 }
2543 
2544                 case FBCInstruction::kSelectInt : {
2545                     // Keep next instruction
2546                     saveReturnScal();
2547 
2548                     if (popInt()) {
2549                         // Execute new block
2550                         assertInterp((*it)->fBranch1);
2551                         dispatchBranch1Scal();
2552                         // Int value
2553                     } else {
2554                         // Execute new block
2555                         assertInterp((*it)->fBranch2);
2556                         dispatchBranch2Scal();
2557                         // Int value
2558                     }
2559                 }
2560 
2561                 case FBCInstruction::kCondBranch : {
2562                     // If condition is true, just branch back on the block beginning
2563                     if (popInt()) {
2564                         assertInterp((*it)->fBranch1);
2565                         dispatchBranch1Scal();
2566                     } else {
2567                         // Just continue after 'loop block' (do the final 'return')
2568                         dispatchNextScal();
2569                     }
2570                 }
2571 
2572                 case FBCInstruction::kLoop : {
2573                     // Keep next instruction
2574                     saveReturnScal();
2575 
2576                     // Push branch2 (loop content)
2577                     assertInterp((*it)->fBranch2);
2578                     pushBranch2Scal();
2579 
2580                     // And start branch1 loop variable declaration block
2581                     assertInterp((*it)->fBranch1);
2582                     dispatchBranch1Scal();
2583                 }
2584 
2585                 default:
2586                     faustassert(false);
2587                     break;
2588             }
2589 
2590     end:
2591         // Check stack coherency
2592         assertInterp(real_stack_index == 0 && int_stack_index == 0 && sound_stack_index == 0);
2593     }
2594    #else
ExecuteBlock(FBCBlockInstruction<REAL> * block,bool compile=false)2595     void ExecuteBlock(FBCBlockInstruction<REAL>* block, bool compile = false)
2596     {
2597         static void* fDispatchTable[] = {
2598 
2599             // Numbers
2600             &&do_kRealValue, &&do_kInt32Value,
2601 
2602             // Memory
2603             &&do_kLoadReal, &&do_kLoadInt, &&do_kLoadSound, &&do_kLoadSoundField, &&do_kStoreReal, &&do_kStoreInt,
2604             &&do_kStoreSound, &&do_kStoreRealValue, &&do_kStoreIntValue, &&do_kLoadIndexedReal, &&do_kLoadIndexedInt,
2605             &&do_kStoreIndexedReal, &&do_kStoreIndexedInt, &&do_kBlockStoreReal, &&do_kBlockStoreInt, &&do_kMoveReal,
2606             &&do_kMoveInt, &&do_kPairMoveReal, &&do_kPairMoveInt, &&do_kBlockPairMoveReal, &&do_kBlockPairMoveInt,
2607             &&do_kBlockShiftReal, &&do_kBlockShiftInt, &&do_kLoadInput, &&do_kStoreOutput,
2608 
2609             // Cast/bitcast
2610             &&do_kCastReal, &&do_kCastInt, &&do_kCastRealHeap, &&do_kCastIntHeap, &&do_kBitcastInt, &&do_kBitcastReal,
2611 
2612             // Standard math (stack OP stack)
2613             &&do_kAddReal, &&do_kAddInt, &&do_kSubReal, &&do_kSubInt, &&do_kMultReal, &&do_kMultInt, &&do_kDivReal,
2614             &&do_kDivInt, &&do_kRemReal, &&do_kRemInt, &&do_kLshInt, &&do_kARshInt, &&do_kLRshInt, &&do_kGTInt, &&do_kLTInt,
2615             &&do_kGEInt, &&do_kLEInt, &&do_kEQInt, &&do_kNEInt, &&do_kGTReal, &&do_kLTReal, &&do_kGEReal, &&do_kLEReal,
2616             &&do_kEQReal, &&do_kNEReal, &&do_kANDInt, &&do_kORInt, &&do_kXORInt,
2617 
2618             // Standard math (heap OP heap)
2619             &&do_kAddRealHeap, &&do_kAddIntHeap, &&do_kSubRealHeap, &&do_kSubIntHeap, &&do_kMultRealHeap,
2620             &&do_kMultIntHeap, &&do_kDivRealHeap, &&do_kDivIntHeap, &&do_kRemRealHeap, &&do_kRemIntHeap,
2621             &&do_kLshIntHeap, &&do_kARshIntHeap, &&do_kLRshIntHeap, &&do_kGTIntHeap, &&do_kLTIntHeap, &&do_kGEIntHeap, &&do_kLEIntHeap,
2622             &&do_kEQIntHeap, &&do_kNEIntHeap, &&do_kGTRealHeap, &&do_kLTRealHeap, &&do_kGERealHeap, &&do_kLERealHeap,
2623             &&do_kEQRealHeap, &&do_kNERealHeap, &&do_kANDIntHeap, &&do_kORIntHeap, &&do_kXORIntHeap,
2624 
2625             // Standard math (heap OP stack)
2626             &&do_kAddRealStack, &&do_kAddIntStack, &&do_kSubRealStack, &&do_kSubIntStack, &&do_kMultRealStack,
2627             &&do_kMultIntStack, &&do_kDivRealStack, &&do_kDivIntStack, &&do_kRemRealStack, &&do_kRemIntStack,
2628             &&do_kLshIntStack, &&do_kARshIntStack, &&do_kLRshIntStack, &&do_kGTIntStack, &&do_kLTIntStack, &&do_kGEIntStack,
2629             &&do_kLEIntStack, &&do_kEQIntStack, &&do_kNEIntStack, &&do_kGTRealStack, &&do_kLTRealStack,
2630             &&do_kGERealStack, &&do_kLERealStack, &&do_kEQRealStack, &&do_kNERealStack, &&do_kANDIntStack,
2631             &&do_kORIntStack, &&do_kXORIntStack,
2632 
2633             // Standard math (value OP stack)
2634             &&do_kAddRealStackValue, &&do_kAddIntStackValue, &&do_kSubRealStackValue, &&do_kSubIntStackValue,
2635             &&do_kMultRealStackValue, &&do_kMultIntStackValue, &&do_kDivRealStackValue, &&do_kDivIntStackValue,
2636             &&do_kRemRealStackValue, &&do_kRemIntStackValue, &&do_kLshIntStackValue, &&do_kARshIntStackValue, &&do_kLRshIntStackValue,
2637             &&do_kGTIntStackValue, &&do_kLTIntStackValue, &&do_kGEIntStackValue, &&do_kLEIntStackValue,
2638             &&do_kEQIntStackValue, &&do_kNEIntStackValue, &&do_kGTRealStackValue, &&do_kLTRealStackValue,
2639             &&do_kGERealStackValue, &&do_kLERealStackValue, &&do_kEQRealStackValue, &&do_kNERealStackValue,
2640             &&do_kANDIntStackValue, &&do_kORIntStackValue, &&do_kXORIntStackValue,
2641 
2642             // Standard math (value OP heap)
2643             &&do_kAddRealValue, &&do_kAddIntValue, &&do_kSubRealValue, &&do_kSubIntValue, &&do_kMultRealValue,
2644             &&do_kMultIntValue, &&do_kDivRealValue, &&do_kDivIntValue, &&do_kRemRealValue, &&do_kRemIntValue,
2645             &&do_kLshIntValue, &&do_kARshIntValue, &&do_kLRshIntValue, &&do_kGTIntValue, &&do_kLTIntValue, &&do_kGEIntValue,
2646             &&do_kLEIntValue, &&do_kEQIntValue, &&do_kNEIntValue, &&do_kGTRealValue, &&do_kLTRealValue,
2647             &&do_kGERealValue, &&do_kLERealValue, &&do_kEQRealValue, &&do_kNERealValue, &&do_kANDIntValue,
2648             &&do_kORIntValue, &&do_kXORIntValue,
2649 
2650             // Standard math (value OP heap) : non commutative operations
2651             &&do_kSubRealValueInvert, &&do_kSubIntValueInvert, &&do_kDivRealValueInvert, &&do_kDivIntValueInvert,
2652             &&do_kRemRealValueInvert, &&do_kRemIntValueInvert, &&do_kLshIntValueInvert, &&do_kARshIntValueInvert, &&do_kLRshIntValueInvert,
2653             &&do_kGTIntValueInvert, &&do_kLTIntValueInvert, &&do_kGEIntValueInvert, &&do_kLEIntValueInvert,
2654             &&do_kGTRealValueInvert, &&do_kLTRealValueInvert, &&do_kGERealValueInvert, &&do_kLERealValueInvert,
2655 
2656             // Extended unary math
2657             &&do_kAbs, &&do_kAbsf, &&do_kAcosf, &&do_kAcoshf, &&do_kAsinf, &&do_kAsinhf, &&do_kAtanf, &&do_kAtanhf, &&do_kCeilf,
2658             &&do_kCosf, &&do_kCoshf,
2659             &&do_kExpf, &&do_kFloorf, &&do_kLogf, &&do_kLog10f, &&do_kRintf, &&do_kRoundf, &&do_kSinf, &&do_kSinhf, &&do_kSqrtf,
2660             &&do_kTanf, &&do_kTanhf, &&do_kIsnanf, &&do_kIsinff,
2661 
2662             // Extended unary math (heap OP heap)
2663             &&do_kAbsHeap, &&do_kAbsfHeap, &&do_kAcosfHeap, &&do_kAcoshfHeap, &&do_kAsinfHeap, &&do_kAsinhfHeap, &&do_kAtanfHeap, &&do_kAtanhfHeap,
2664             &&do_kCeilfHeap,
2665             &&do_kCosfHeap, &&do_kCoshfHeap, &&do_kExpfHeap, &&do_kFloorfHeap, &&do_kLogfHeap, &&do_kLog10fHeap,
2666             &&do_kRintfHeap, &&do_kRoundfHeap, &&do_kSinfHeap, &&do_kSinhfHeap, &&do_kSqrtfHeap, &&do_kTanfHeap, &&do_kTanhfHeap,
2667 
2668             // Extended binary math
2669             &&do_kAtan2f, &&do_kFmodf, &&do_kPowf, &&do_kMax, &&do_kMaxf, &&do_kMin, &&do_kMinf, &&do_kCopysignf,
2670 
2671             // Extended binary math (heap version)
2672             &&do_kAtan2fHeap, &&do_kFmodfHeap, &&do_kPowfHeap, &&do_kMaxHeap, &&do_kMaxfHeap, &&do_kMinHeap,
2673             &&do_kMinfHeap,
2674 
2675             // Extended binary math (stack version)
2676             &&do_kAtan2fStack, &&do_kFmodfStack, &&do_kPowfStack, &&do_kMaxStack, &&do_kMaxfStack, &&do_kMinStack,
2677             &&do_kMinfStack,
2678 
2679             // Extended binary math (Stack/Value version)
2680             &&do_kAtan2fStackValue, &&do_kFmodfStackValue, &&do_kPowfStackValue, &&do_kMaxStackValue,
2681             &&do_kMaxfStackValue, &&do_kMinStackValue, &&do_kMinfStackValue,
2682 
2683             // Extended binary math (Value version)
2684             &&do_kAtan2fValue, &&do_kFmodfValue, &&do_kPowfValue, &&do_kMaxValue, &&do_kMaxfValue, &&do_kMinValue,
2685             &&do_kMinfValue,
2686 
2687             // Extended binary math (Value version) : non commutative operations
2688             &&do_kAtan2fValueInvert, &&do_kFmodfValueInvert, &&do_kPowfValueInvert,
2689 
2690             // Control
2691             &&do_kLoop, &&do_kReturn,
2692 
2693             // Select/if
2694             &&do_kIf, &&do_kSelectReal, &&do_kSelectInt, &&do_kCondBranch
2695 
2696         };
2697 
2698         int real_stack_index  = 0;
2699         int int_stack_index   = 0;
2700         int sound_stack_index = 0;
2701         int addr_stack_index  = 0;
2702 
2703         REAL          real_stack[512];
2704         int           int_stack[512];
2705         Soundfile*    sound_stack[512];
2706         InstructionIT address_stack[64];
2707 
2708         memset(real_stack, 0, sizeof(REAL)*512);
2709         memset(int_stack, 0, sizeof(int)*512);
2710         memset(sound_stack, 0, sizeof(Soundfile*)*512);
2711         memset(address_stack, 0, sizeof(InstructionIT)*64);
2712 
2713 #define dispatchFirstScal()                   \
2714     {                                         \
2715         goto *fDispatchTable[(*it)->fOpcode]; \
2716     }
2717 #define dispatchNextScal()                    \
2718     {                                         \
2719         if (TRACE >= 4) {     \
2720             traceInstruction(it, int_stack[int_stack_index], real_stack[real_stack_index]); \
2721         }                                     \
2722         it++;                                 \
2723         dispatchFirstScal();                  \
2724     }
2725 
2726 
2727 #define dispatchBranch1Scal()                        \
2728     {                                                \
2729         it = (*it)->fBranch1->fInstructions.begin(); \
2730         dispatchFirstScal();                         \
2731     }
2732 #define dispatchBranch2Scal()                        \
2733     {                                                \
2734         it = (*it)->fBranch2->fInstructions.begin(); \
2735         dispatchFirstScal();                         \
2736     }
2737 
2738 #define pushBranch1Scal()                                  \
2739     {                                                      \
2740         pushAddr_((*it)->fBranch1->fInstructions.begin()); \
2741     }
2742 #define pushBranch2Scal()                                  \
2743     {                                                      \
2744         pushAddr_((*it)->fBranch2->fInstructions.begin()); \
2745     }
2746 
2747 #define dispatchReturnScal() \
2748     {                        \
2749         it = popAddr_();     \
2750         dispatchFirstScal(); \
2751     }
2752 #define saveReturnScal()   \
2753     {                      \
2754         pushAddr_(it + 1); \
2755     }
2756 #define emptyReturnScal() (addr_stack_index == 0)
2757 
2758         if (TRACE > 0) {
2759             // Check block coherency
2760             block->check();
2761         }
2762 
2763         InstructionIT it = block->fInstructions.begin();
2764         dispatchFirstScal();
2765 
2766     // Number operations
2767     do_kRealValue : {
2768         pushReal(it, (*it)->fRealValue);
2769         dispatchNextScal();
2770     }
2771 
2772     do_kInt32Value : {
2773         pushInt((*it)->fIntValue);
2774         dispatchNextScal();
2775     }
2776 
2777     // Memory operations
2778     do_kLoadReal : {
2779         if (TRACE > 0) {
2780             pushReal(it, fRealHeap[assertLoadRealHeap(it, (*it)->fOffset1)]);
2781         } else {
2782             pushReal(it, fRealHeap[(*it)->fOffset1]);
2783         }
2784         dispatchNextScal();
2785     }
2786 
2787     do_kLoadInt : {
2788         if (TRACE > 0) {
2789             pushInt(fIntHeap[assertLoadIntHeap(it, (*it)->fOffset1)]);
2790         } else {
2791             pushInt(fIntHeap[(*it)->fOffset1]);
2792         }
2793         dispatchNextScal();
2794     }
2795 
2796     do_kLoadSound : {
2797         if (TRACE > 0) {
2798             pushSound(fSoundHeap[assertSoundHeap(it, (*it)->fOffset1)]);
2799         } else {
2800             pushSound(fSoundHeap[(*it)->fOffset1]);
2801         }
2802         dispatchNextScal();
2803     }
2804 
2805     do_kLoadSoundField : {
2806         /*
2807         if (TRACE > 0) {
2808             pushSound(fSoundHeap[assertSoundHeap(it, (*it)->fOffset1)]);
2809         } else {
2810             pushSound(fSoundHeap[(*it)->fOffset1]);
2811         }
2812         dispatchNextScal();
2813         */
2814     }
2815 
2816     do_kStoreReal : {
2817         if (TRACE > 0) {
2818             fRealHeap[assertStoreRealHeap(it, (*it)->fOffset1)] = popReal(it);
2819         } else {
2820             fRealHeap[(*it)->fOffset1] = popReal(it);
2821         }
2822         dispatchNextScal();
2823     }
2824 
2825     do_kStoreInt : {
2826         if (TRACE > 0) {
2827             fIntHeap[assertStoreIntHeap(it, (*it)->fOffset1)] = popInt();
2828         } else {
2829             fIntHeap[(*it)->fOffset1] = popInt();
2830         }
2831         dispatchNextScal();
2832     }
2833 
2834     do_kStoreSound : {
2835         /*
2836         if (TRACE > 0) {
2837             fSoundHeap[assertSoundHeap(it, (*it)->fOffset1)] = popSound();
2838         } else {
2839             fSoundHeap[(*it)->fOffset1] = popSound();
2840         }
2841         */
2842         dispatchNextScal();
2843     }
2844 
2845     // Directly store a value
2846     do_kStoreRealValue : {
2847         if (TRACE > 0) {
2848             fRealHeap[assertStoreRealHeap(it, (*it)->fOffset1)] = (*it)->fRealValue;
2849         } else {
2850             fRealHeap[(*it)->fOffset1] = (*it)->fRealValue;
2851         }
2852         dispatchNextScal();
2853     }
2854 
2855     do_kStoreIntValue : {
2856         if (TRACE > 0) {
2857             fIntHeap[assertStoreIntHeap(it, (*it)->fOffset1)] = (*it)->fIntValue;
2858         } else {
2859             fIntHeap[(*it)->fOffset1] = (*it)->fIntValue;
2860         }
2861         dispatchNextScal();
2862     }
2863 
2864     do_kLoadIndexedReal : {
2865         int offset = popInt();
2866         if (TRACE > 0) {
2867             // DEBUG
2868             // assertIndex(it, offset, (*it)->fOffset2);
2869             pushReal(it, fRealHeap[assertLoadRealHeap(it, (*it)->fOffset1 + offset, (*it)->fOffset2)]);
2870         } else {
2871             pushReal(it, fRealHeap[(*it)->fOffset1 + offset]);
2872         }
2873         dispatchNextScal();
2874     }
2875 
2876     do_kLoadIndexedInt : {
2877         int offset = popInt();
2878         if (TRACE > 0) {
2879             // DEBUG
2880             // assertIndex(it, offset, (*it)->fOffset2);
2881             pushInt(fIntHeap[assertLoadIntHeap(it, (*it)->fOffset1 + offset, (*it)->fOffset2)]);
2882         } else {
2883             pushInt(fIntHeap[(*it)->fOffset1 + offset]);
2884         }
2885         dispatchNextScal();
2886     }
2887 
2888     do_kStoreIndexedReal : {
2889         int offset = popInt();
2890         if (TRACE > 0) {
2891             // DEBUG
2892             // assertIndex(it, offset, (*it)->fOffset2);
2893             fRealHeap[assertStoreRealHeap(it, (*it)->fOffset1 + offset, (*it)->fOffset2)] = popReal(it);
2894         } else {
2895             fRealHeap[(*it)->fOffset1 + offset] = popReal(it);
2896         }
2897         dispatchNextScal();
2898     }
2899 
2900     do_kStoreIndexedInt : {
2901         int offset = popInt();
2902         if (TRACE > 0) {
2903             // DEBUG
2904             // assertIndex(it, offset, (*it)->fOffset2);
2905             fIntHeap[assertStoreIntHeap(it, (*it)->fOffset1 + offset, (*it)->fOffset2)] = popInt();
2906         } else {
2907             fIntHeap[(*it)->fOffset1 + offset] = popInt();
2908         }
2909         dispatchNextScal();
2910     }
2911 
2912     do_kBlockStoreReal : {
2913         FIRBlockStoreRealInstruction<REAL>* inst = static_cast<FIRBlockStoreRealInstruction<REAL>*>(*it);
2914         assertInterp(inst);
2915         for (int i = 0; i < inst->fOffset2; i++) {
2916             fRealHeap[inst->fOffset1 + i] = inst->fNumTable[i];
2917         }
2918         dispatchNextScal();
2919     }
2920 
2921     do_kBlockStoreInt : {
2922         FIRBlockStoreIntInstruction<REAL>* inst = static_cast<FIRBlockStoreIntInstruction<REAL>*>(*it);
2923         assertInterp(inst);
2924         for (int i = 0; i < inst->fOffset2; i++) {
2925             fIntHeap[inst->fOffset1 + i] = inst->fNumTable[i];
2926         }
2927         dispatchNextScal();
2928     }
2929 
2930     do_kMoveReal : {
2931         fRealHeap[(*it)->fOffset1] = fRealHeap[(*it)->fOffset2];
2932         dispatchNextScal();
2933     }
2934 
2935     do_kMoveInt : {
2936         fIntHeap[(*it)->fOffset1] = fIntHeap[(*it)->fOffset2];
2937         dispatchNextScal();
2938     }
2939 
2940     do_kPairMoveReal : {
2941         fRealHeap[(*it)->fOffset1] = fRealHeap[(*it)->fOffset1 - 1];
2942         fRealHeap[(*it)->fOffset2] = fRealHeap[(*it)->fOffset2 - 1];
2943         dispatchNextScal();
2944     }
2945 
2946     do_kPairMoveInt : {
2947         fIntHeap[(*it)->fOffset1] = fIntHeap[(*it)->fOffset1 - 1];
2948         fIntHeap[(*it)->fOffset2] = fIntHeap[(*it)->fOffset2 - 1];
2949         dispatchNextScal();
2950     }
2951 
2952     do_kBlockPairMoveReal : {
2953         for (int i = (*it)->fOffset1; i < (*it)->fOffset2; i += 2) {
2954             fRealHeap[i + 1] = fRealHeap[i];
2955         }
2956         dispatchNextScal();
2957     }
2958 
2959     do_kBlockPairMoveInt : {
2960         for (int i = (*it)->fOffset1; i < (*it)->fOffset2; i += 2) {
2961             fIntHeap[i + 1] = fIntHeap[i];
2962         }
2963         dispatchNextScal();
2964     }
2965 
2966     do_kBlockShiftReal : {
2967         for (int i = (*it)->fOffset1; i > (*it)->fOffset2; i -= 1) {
2968             fRealHeap[i] = fRealHeap[i - 1];
2969         }
2970         dispatchNextScal();
2971     }
2972 
2973     do_kBlockShiftInt : {
2974         for (int i = (*it)->fOffset1; i > (*it)->fOffset2; i -= 1) {
2975             fIntHeap[i] = fIntHeap[i - 1];
2976         }
2977         dispatchNextScal();
2978     }
2979 
2980     // Input/output access
2981     do_kLoadInput : {
2982         if (TRACE > 0) {
2983             pushReal(it, fInputs[(*it)->fOffset1][assertAudioBuffer(it, popInt())]);
2984         } else {
2985             /*
2986             int index = popInt();
2987             pushReal(it, fInputs[(*it)->fOffset1][index]);
2988             std::cout << "do_kLoadInput " << index << std::endl;
2989             */
2990             pushReal(it, fInputs[(*it)->fOffset1][popInt()]);
2991         }
2992         dispatchNextScal();
2993     }
2994 
2995     do_kStoreOutput : {
2996         if (TRACE > 0) {
2997             fOutputs[(*it)->fOffset1][assertAudioBuffer(it, popInt())] = popReal(it);
2998         } else {
2999             /*
3000             int index = popInt();
3001             std::cout << "do_kStoreOutput " << index << std::endl;
3002             fOutputs[(*it)->fOffset1][index] = popReal(it);
3003             */
3004             fOutputs[(*it)->fOffset1][popInt()] = popReal(it);
3005         }
3006         dispatchNextScal();
3007     }
3008 
3009     // Cast operations
3010     do_kCastReal : {
3011         pushReal(it, REAL(popInt()));
3012         dispatchNextScal();
3013     }
3014 
3015     do_kCastRealHeap : {
3016         pushReal(it, REAL(fIntHeap[(*it)->fOffset1]));
3017         dispatchNextScal();
3018     }
3019 
3020     do_kCastInt : {
3021         if (TRACE >= 3) {
3022             pushInt(int(checkCastIntOverflow(it, popReal(it))));
3023         } else {
3024             pushInt(int(popReal(it)));
3025         }
3026         dispatchNextScal();
3027     }
3028 
3029     do_kCastIntHeap : {
3030         if (TRACE >= 3) {
3031             pushInt(int(checkCastIntOverflow(it, fRealHeap[(*it)->fOffset1])));
3032         } else {
3033             pushInt(int(fRealHeap[(*it)->fOffset1]));
3034         }
3035         dispatchNextScal();
3036     }
3037 
3038     // Bitcast operations
3039     do_kBitcastInt : {
3040         REAL v1 = popReal(it);
3041         int  v2 = *reinterpret_cast<int*>(&v1);
3042         pushInt(v2);
3043         dispatchNextScal();
3044     }
3045 
3046     do_kBitcastReal : {
3047         int  v1 = popInt();
3048         REAL v2 = *reinterpret_cast<REAL*>(&v1);
3049         pushReal(it, v2);
3050         dispatchNextScal();
3051     }
3052 
3053         //-------------------------------------------------------
3054         // Standard math operations : 'stack' OP 'stack' version
3055         //-------------------------------------------------------
3056 
3057     do_kAddReal : {
3058         REAL v1 = popReal(it);
3059         REAL v2 = popReal(it);
3060         pushReal(it, v1 + v2);
3061         dispatchNextScal();
3062     }
3063 
3064     do_kAddInt : {
3065         int v1 = popInt();
3066         int v2 = popInt();
3067         if (TRACE > 0) {
3068             int res;
3069             if (__builtin_sadd_overflow(v1, v2, &res)) {
3070                 warningOverflow(it);
3071             }
3072             pushInt(res);
3073         } else {
3074             pushInt(v1 + v2);
3075         }
3076         dispatchNextScal();
3077     }
3078 
3079     do_kSubReal : {
3080         REAL v1 = popReal(it);
3081         REAL v2 = popReal(it);
3082         pushReal(it, v1 - v2);
3083         dispatchNextScal();
3084     }
3085 
3086     do_kSubInt : {
3087         int v1 = popInt();
3088         int v2 = popInt();
3089         if (TRACE > 0) {
3090             int res;
3091             if (__builtin_ssub_overflow(v1, v2, &res)) {
3092                 warningOverflow(it);
3093             }
3094             pushInt(res);
3095         } else {
3096             pushInt(v1 - v2);
3097         }
3098         dispatchNextScal();
3099     }
3100 
3101     do_kMultReal : {
3102         REAL v1 = popReal(it);
3103         REAL v2 = popReal(it);
3104         pushReal(it, v1 * v2);
3105         dispatchNextScal();
3106     }
3107 
3108     do_kMultInt : {
3109         int v1 = popInt();
3110         int v2 = popInt();
3111         if (TRACE > 0) {
3112             int res;
3113             if (__builtin_smul_overflow(v1, v2, &res)) {
3114                 warningOverflow(it);
3115             }
3116             pushInt(res);
3117         } else {
3118             pushInt(v1 * v2);
3119         }
3120         dispatchNextScal();
3121     }
3122 
3123     do_kDivReal : {
3124         REAL v1 = popReal(it);
3125         REAL v2 = popReal(it);
3126         if (TRACE > 0) {
3127             checkDivZero(it, v2);
3128         }
3129         pushReal(it, v1 / v2);
3130         dispatchNextScal();
3131     }
3132 
3133     do_kDivInt : {
3134         int v1 = popInt();
3135         int v2 = popInt();
3136         if (TRACE > 0) {
3137             checkDivZero(it, v2);
3138         }
3139         pushInt(v1 / v2);
3140         dispatchNextScal();
3141     }
3142 
3143     do_kRemReal : {
3144         REAL v1 = popReal(it);
3145         REAL v2 = popReal(it);
3146         if (TRACE > 0) {
3147             checkDivZero(it, v2);
3148         }
3149         pushReal(it, std::remainder(v1, v2));
3150         dispatchNextScal();
3151     }
3152 
3153     do_kRemInt : {
3154         int v1 = popInt();
3155         int v2 = popInt();
3156         if (TRACE > 0) {
3157             checkDivZero(it, v2);
3158         }
3159         pushInt(v1 % v2);
3160         dispatchNextScal();
3161     }
3162 
3163     // Shift operation
3164     do_kLshInt : {
3165         int v1 = popInt();
3166         int v2 = popInt();
3167         pushInt(v1 << v2);
3168         dispatchNextScal();
3169     }
3170 
3171     do_kARshInt : {
3172         int v1 = popInt();
3173         int v2 = popInt();
3174         pushInt(v1 >> v2);
3175         dispatchNextScal();
3176     }
3177 
3178     do_kLRshInt : {
3179         // TODO
3180         int v1 = popInt();
3181         int v2 = popInt();
3182         pushInt(v1 >> v2);
3183         dispatchNextScal();
3184     }
3185 
3186     // Comparaison Int
3187     do_kGTInt : {
3188         int v1 = popInt();
3189         int v2 = popInt();
3190         pushInt(v1 > v2);
3191         dispatchNextScal();
3192     }
3193 
3194     do_kLTInt : {
3195         int v1 = popInt();
3196         int v2 = popInt();
3197         pushInt(v1 < v2);
3198         dispatchNextScal();
3199     }
3200 
3201     do_kGEInt : {
3202         int v1 = popInt();
3203         int v2 = popInt();
3204         pushInt(v1 >= v2);
3205         dispatchNextScal();
3206     }
3207 
3208     do_kLEInt : {
3209         int v1 = popInt();
3210         int v2 = popInt();
3211         pushInt(v1 <= v2);
3212         dispatchNextScal();
3213     }
3214 
3215     do_kEQInt : {
3216         int v1 = popInt();
3217         int v2 = popInt();
3218         pushInt(v1 == v2);
3219         dispatchNextScal();
3220     }
3221 
3222     do_kNEInt : {
3223         int v1 = popInt();
3224         int v2 = popInt();
3225         pushInt(v1 != v2);
3226         dispatchNextScal();
3227     }
3228 
3229     // Comparaison Real
3230     do_kGTReal : {
3231         REAL v1 = popReal(it);
3232         REAL v2 = popReal(it);
3233         pushInt(v1 > v2);
3234         dispatchNextScal();
3235     }
3236 
3237     do_kLTReal : {
3238         REAL v1 = popReal(it);
3239         REAL v2 = popReal(it);
3240         pushInt(v1 < v2);
3241         dispatchNextScal();
3242     }
3243 
3244     do_kGEReal : {
3245         REAL v1 = popReal(it);
3246         REAL v2 = popReal(it);
3247         pushInt(v1 >= v2);
3248         dispatchNextScal();
3249     }
3250 
3251     do_kLEReal : {
3252         REAL v1 = popReal(it);
3253         REAL v2 = popReal(it);
3254         pushInt(v1 <= v2);
3255         dispatchNextScal();
3256     }
3257 
3258     do_kEQReal : {
3259         REAL v1 = popReal(it);
3260         REAL v2 = popReal(it);
3261         pushInt(v1 == v2);
3262         dispatchNextScal();
3263     }
3264 
3265     do_kNEReal : {
3266         REAL v1 = popReal(it);
3267         REAL v2 = popReal(it);
3268         pushInt(v1 != v2);
3269         dispatchNextScal();
3270     }
3271 
3272     // Logical operations
3273     do_kANDInt : {
3274         int v1 = popInt();
3275         int v2 = popInt();
3276         pushInt(v1 & v2);
3277         dispatchNextScal();
3278     }
3279 
3280     do_kORInt : {
3281         int v1 = popInt();
3282         int v2 = popInt();
3283         pushInt(v1 | v2);
3284         dispatchNextScal();
3285     }
3286 
3287     do_kXORInt : {
3288         int v1 = popInt();
3289         int v2 = popInt();
3290         pushInt(v1 ^ v2);
3291         dispatchNextScal();
3292     }
3293 
3294         //-----------------------------------------------------
3295         // Standard math operations : 'heap' OP 'heap' version
3296         //-----------------------------------------------------
3297 
3298     do_kAddRealHeap : {
3299         pushReal(it, fRealHeap[(*it)->fOffset1] + fRealHeap[(*it)->fOffset2]);
3300         dispatchNextScal();
3301     }
3302 
3303     do_kAddIntHeap : {
3304         pushInt(fIntHeap[(*it)->fOffset1] + fIntHeap[(*it)->fOffset2]);
3305         dispatchNextScal();
3306     }
3307 
3308     do_kSubRealHeap : {
3309         pushReal(it, fRealHeap[(*it)->fOffset1] - fRealHeap[(*it)->fOffset2]);
3310         dispatchNextScal();
3311     }
3312 
3313     do_kSubIntHeap : {
3314         pushInt(fIntHeap[(*it)->fOffset1] - fIntHeap[(*it)->fOffset2]);
3315         dispatchNextScal();
3316     }
3317 
3318     do_kMultRealHeap : {
3319         pushReal(it, fRealHeap[(*it)->fOffset1] * fRealHeap[(*it)->fOffset2]);
3320         dispatchNextScal();
3321     }
3322 
3323     do_kMultIntHeap : {
3324         pushInt(fIntHeap[(*it)->fOffset1] * fIntHeap[(*it)->fOffset2]);
3325         dispatchNextScal();
3326     }
3327 
3328     do_kDivRealHeap : {
3329         pushReal(it, fRealHeap[(*it)->fOffset1] / fRealHeap[(*it)->fOffset2]);
3330         dispatchNextScal();
3331     }
3332 
3333     do_kDivIntHeap : {
3334         pushInt(fIntHeap[(*it)->fOffset1] / fIntHeap[(*it)->fOffset2]);
3335         dispatchNextScal();
3336     }
3337 
3338     do_kRemRealHeap : {
3339         pushReal(it, std::remainder(fRealHeap[(*it)->fOffset1], fRealHeap[(*it)->fOffset2]));
3340         dispatchNextScal();
3341     }
3342 
3343     do_kRemIntHeap : {
3344         pushInt(fIntHeap[(*it)->fOffset1] % fIntHeap[(*it)->fOffset2]);
3345         dispatchNextScal();
3346     }
3347 
3348     // Shift operation
3349     do_kLshIntHeap : {
3350         pushInt(fIntHeap[(*it)->fOffset1] << fIntHeap[(*it)->fOffset2]);
3351         dispatchNextScal();
3352     }
3353 
3354     do_kARshIntHeap : {
3355         pushInt(fIntHeap[(*it)->fOffset1] >> fIntHeap[(*it)->fOffset2]);
3356         dispatchNextScal();
3357     }
3358 
3359     do_kLRshIntHeap : {
3360         // TODO
3361         pushInt(fIntHeap[(*it)->fOffset1] >> fIntHeap[(*it)->fOffset2]);
3362         dispatchNextScal();
3363     }
3364 
3365     // Comparaison Int
3366     do_kGTIntHeap : {
3367         pushInt(fIntHeap[(*it)->fOffset1] > fIntHeap[(*it)->fOffset2]);
3368         dispatchNextScal();
3369     }
3370 
3371     do_kLTIntHeap : {
3372         pushInt(fIntHeap[(*it)->fOffset1] < fIntHeap[(*it)->fOffset2]);
3373         dispatchNextScal();
3374     }
3375 
3376     do_kGEIntHeap : {
3377         pushInt(fIntHeap[(*it)->fOffset1] >= fIntHeap[(*it)->fOffset2]);
3378         dispatchNextScal();
3379     }
3380 
3381     do_kLEIntHeap : {
3382         pushInt(fIntHeap[(*it)->fOffset1] <= fIntHeap[(*it)->fOffset2]);
3383         dispatchNextScal();
3384     }
3385 
3386     do_kEQIntHeap : {
3387         pushInt(fIntHeap[(*it)->fOffset1] == fIntHeap[(*it)->fOffset2]);
3388         dispatchNextScal();
3389     }
3390 
3391     do_kNEIntHeap : {
3392         pushInt(fIntHeap[(*it)->fOffset1] != fIntHeap[(*it)->fOffset2]);
3393         dispatchNextScal();
3394     }
3395 
3396     // Comparaison Real
3397     do_kGTRealHeap : {
3398         pushInt(fRealHeap[(*it)->fOffset1] > fRealHeap[(*it)->fOffset2]);
3399         dispatchNextScal();
3400     }
3401 
3402     do_kLTRealHeap : {
3403         pushInt(fRealHeap[(*it)->fOffset1] < fRealHeap[(*it)->fOffset2]);
3404         dispatchNextScal();
3405     }
3406 
3407     do_kGERealHeap : {
3408         pushInt(fRealHeap[(*it)->fOffset1] >= fRealHeap[(*it)->fOffset2]);
3409         dispatchNextScal();
3410     }
3411 
3412     do_kLERealHeap : {
3413         pushInt(fRealHeap[(*it)->fOffset1] <= fRealHeap[(*it)->fOffset2]);
3414         dispatchNextScal();
3415     }
3416 
3417     do_kEQRealHeap : {
3418         pushInt(fRealHeap[(*it)->fOffset1] == fRealHeap[(*it)->fOffset2]);
3419         dispatchNextScal();
3420     }
3421 
3422     do_kNERealHeap : {
3423         pushInt(fRealHeap[(*it)->fOffset1] != fRealHeap[(*it)->fOffset2]);
3424         dispatchNextScal();
3425     }
3426 
3427     // Logical operations
3428     do_kANDIntHeap : {
3429         pushInt(fIntHeap[(*it)->fOffset1] & fIntHeap[(*it)->fOffset2]);
3430         dispatchNextScal();
3431     }
3432 
3433     do_kORIntHeap : {
3434         pushInt(fIntHeap[(*it)->fOffset1] | fIntHeap[(*it)->fOffset2]);
3435         dispatchNextScal();
3436     }
3437 
3438     do_kXORIntHeap : {
3439         pushInt(fIntHeap[(*it)->fOffset1] ^ fIntHeap[(*it)->fOffset2]);
3440         dispatchNextScal();
3441     }
3442 
3443         //------------------------------------------------------
3444         // Standard math operations : 'stack' OP 'heap' version
3445         //------------------------------------------------------
3446 
3447     do_kAddRealStack : {
3448         REAL v1 = popReal(it);
3449         pushReal(it, fRealHeap[(*it)->fOffset1] + v1);
3450         dispatchNextScal();
3451     }
3452 
3453     do_kAddIntStack : {
3454         int v1 = popInt();
3455         pushInt(fIntHeap[(*it)->fOffset1] + v1);
3456         dispatchNextScal();
3457     }
3458 
3459     do_kSubRealStack : {
3460         REAL v1 = popReal(it);
3461         pushReal(it, fRealHeap[(*it)->fOffset1] - v1);
3462         dispatchNextScal();
3463     }
3464 
3465     do_kSubIntStack : {
3466         int v1 = popInt();
3467         pushInt(fIntHeap[(*it)->fOffset1] - v1);
3468         dispatchNextScal();
3469     }
3470 
3471     do_kMultRealStack : {
3472         REAL v1 = popReal(it);
3473         pushReal(it, fRealHeap[(*it)->fOffset1] * v1);
3474         dispatchNextScal();
3475     }
3476 
3477     do_kMultIntStack : {
3478         int v1 = popInt();
3479         pushInt(fIntHeap[(*it)->fOffset1] * v1);
3480         dispatchNextScal();
3481     }
3482 
3483     do_kDivRealStack : {
3484         REAL v1 = popReal(it);
3485         pushReal(it, fRealHeap[(*it)->fOffset1] / v1);
3486         dispatchNextScal();
3487     }
3488 
3489     do_kDivIntStack : {
3490         int v1 = popInt();
3491         pushInt(fIntHeap[(*it)->fOffset1] / v1);
3492         dispatchNextScal();
3493     }
3494 
3495     do_kRemRealStack : {
3496         REAL v1 = popReal(it);
3497         pushReal(it, std::remainder(fRealHeap[(*it)->fOffset1], v1));
3498         dispatchNextScal();
3499     }
3500 
3501     do_kRemIntStack : {
3502         int v1 = popInt();
3503         pushInt(fIntHeap[(*it)->fOffset1] % v1);
3504         dispatchNextScal();
3505     }
3506 
3507     // Shift operation
3508     do_kLshIntStack : {
3509         int v1 = popInt();
3510         pushInt(fIntHeap[(*it)->fOffset1] << v1);
3511         dispatchNextScal();
3512     }
3513 
3514     do_kARshIntStack : {
3515         int v1 = popInt();
3516         pushInt(fIntHeap[(*it)->fOffset1] >> v1);
3517         dispatchNextScal();
3518     }
3519 
3520     do_kLRshIntStack : {
3521         // TODO
3522         int v1 = popInt();
3523         pushInt(fIntHeap[(*it)->fOffset1] >> v1);
3524         dispatchNextScal();
3525     }
3526 
3527     // Comparaison Int
3528     do_kGTIntStack : {
3529         int v1 = popInt();
3530         pushInt(fIntHeap[(*it)->fOffset1] > v1);
3531         dispatchNextScal();
3532     }
3533 
3534     do_kLTIntStack : {
3535         int v1 = popInt();
3536         pushInt(fIntHeap[(*it)->fOffset1] < v1);
3537         dispatchNextScal();
3538     }
3539 
3540     do_kGEIntStack : {
3541         int v1 = popInt();
3542         pushInt(fIntHeap[(*it)->fOffset1] >= v1);
3543         dispatchNextScal();
3544     }
3545 
3546     do_kLEIntStack : {
3547         int v1 = popInt();
3548         pushInt(fIntHeap[(*it)->fOffset1] <= v1);
3549         dispatchNextScal();
3550     }
3551 
3552     do_kEQIntStack : {
3553         int v1 = popInt();
3554         pushInt(fIntHeap[(*it)->fOffset1] == v1);
3555         dispatchNextScal();
3556     }
3557 
3558     do_kNEIntStack : {
3559         int v1 = popInt();
3560         pushInt(fIntHeap[(*it)->fOffset1] != v1);
3561         dispatchNextScal();
3562     }
3563 
3564     // Comparaison Real
3565     do_kGTRealStack : {
3566         REAL v1 = popReal(it);
3567         pushInt(fRealHeap[(*it)->fOffset1] > v1);
3568         dispatchNextScal();
3569     }
3570 
3571     do_kLTRealStack : {
3572         REAL v1 = popReal(it);
3573         pushInt(fRealHeap[(*it)->fOffset1] < v1);
3574         dispatchNextScal();
3575     }
3576 
3577     do_kGERealStack : {
3578         REAL v1 = popReal(it);
3579         pushInt(fRealHeap[(*it)->fOffset1] >= v1);
3580         dispatchNextScal();
3581     }
3582 
3583     do_kLERealStack : {
3584         REAL v1 = popReal(it);
3585         pushInt(fRealHeap[(*it)->fOffset1] <= v1);
3586         dispatchNextScal();
3587     }
3588 
3589     do_kEQRealStack : {
3590         REAL v1 = popReal(it);
3591         pushInt(fRealHeap[(*it)->fOffset1] == v1);
3592         dispatchNextScal();
3593     }
3594 
3595     do_kNERealStack : {
3596         REAL v1 = popReal(it);
3597         pushInt(fRealHeap[(*it)->fOffset1] != v1);
3598         dispatchNextScal();
3599     }
3600 
3601     // Logical operations
3602     do_kANDIntStack : {
3603         int v1 = popInt();
3604         pushInt(fIntHeap[(*it)->fOffset1] & v1);
3605         dispatchNextScal();
3606     }
3607 
3608     do_kORIntStack : {
3609         int v1 = popInt();
3610         pushInt(fIntHeap[(*it)->fOffset1] | v1);
3611         dispatchNextScal();
3612     }
3613 
3614     do_kXORIntStack : {
3615         int v1 = popInt();
3616         pushInt(fIntHeap[(*it)->fOffset1] ^ v1);
3617         dispatchNextScal();
3618     }
3619 
3620         //-------------------------------------------------------
3621         // Standard math operations : 'stack' OP 'value' version
3622         //-------------------------------------------------------
3623 
3624     do_kAddRealStackValue : {
3625         REAL v1 = popReal(it);
3626         pushReal(it, (*it)->fRealValue + v1);
3627         dispatchNextScal();
3628     }
3629 
3630     do_kAddIntStackValue : {
3631         int v1 = popInt();
3632         pushInt((*it)->fIntValue + v1);
3633         dispatchNextScal();
3634     }
3635 
3636     do_kSubRealStackValue : {
3637         REAL v1 = popReal(it);
3638         pushReal(it, (*it)->fRealValue - v1);
3639         dispatchNextScal();
3640     }
3641 
3642     do_kSubIntStackValue : {
3643         int v1 = popInt();
3644         pushInt((*it)->fIntValue - v1);
3645         dispatchNextScal();
3646     }
3647 
3648     do_kMultRealStackValue : {
3649         REAL v1 = popReal(it);
3650         pushReal(it, (*it)->fRealValue * v1);
3651         dispatchNextScal();
3652     }
3653 
3654     do_kMultIntStackValue : {
3655         int v1 = popInt();
3656         pushInt((*it)->fIntValue * v1);
3657         dispatchNextScal();
3658     }
3659 
3660     do_kDivRealStackValue : {
3661         REAL v1 = popReal(it);
3662         pushReal(it, (*it)->fRealValue / v1);
3663         dispatchNextScal();
3664     }
3665 
3666     do_kDivIntStackValue : {
3667         int v1 = popInt();
3668         pushInt((*it)->fIntValue / v1);
3669         dispatchNextScal();
3670     }
3671 
3672     do_kRemRealStackValue : {
3673         REAL v1 = popReal(it);
3674         pushReal(it, std::remainder((*it)->fRealValue, v1));
3675         dispatchNextScal();
3676     }
3677 
3678     do_kRemIntStackValue : {
3679         int v1 = popInt();
3680         pushInt((*it)->fIntValue % v1);
3681         dispatchNextScal();
3682     }
3683 
3684     // Shift operation
3685     do_kLshIntStackValue : {
3686         int v1 = popInt();
3687         pushInt((*it)->fIntValue << v1);
3688         dispatchNextScal();
3689     }
3690 
3691     do_kARshIntStackValue : {
3692         int v1 = popInt();
3693         pushInt((*it)->fIntValue >> v1);
3694         dispatchNextScal();
3695     }
3696 
3697     do_kLRshIntStackValue : {
3698         // TODO
3699         int v1 = popInt();
3700         pushInt((*it)->fIntValue >> v1);
3701         dispatchNextScal();
3702     }
3703 
3704     // Comparaison Int
3705     do_kGTIntStackValue : {
3706         int v1 = popInt();
3707         pushInt((*it)->fIntValue > v1);
3708         dispatchNextScal();
3709     }
3710 
3711     do_kLTIntStackValue : {
3712         int v1 = popInt();
3713         pushInt((*it)->fIntValue < v1);
3714         dispatchNextScal();
3715     }
3716 
3717     do_kGEIntStackValue : {
3718         int v1 = popInt();
3719         pushInt((*it)->fIntValue >= v1);
3720         dispatchNextScal();
3721     }
3722 
3723     do_kLEIntStackValue : {
3724         int v1 = popInt();
3725         pushInt((*it)->fIntValue <= v1);
3726         dispatchNextScal();
3727     }
3728 
3729     do_kEQIntStackValue : {
3730         int v1 = popInt();
3731         pushInt((*it)->fIntValue == v1);
3732         dispatchNextScal();
3733     }
3734 
3735     do_kNEIntStackValue : {
3736         int v1 = popInt();
3737         pushInt((*it)->fIntValue != v1);
3738         dispatchNextScal();
3739     }
3740 
3741     // Comparaison Real
3742     do_kGTRealStackValue : {
3743         REAL v1 = popReal(it);
3744         pushInt((*it)->fRealValue > v1);
3745         dispatchNextScal();
3746     }
3747 
3748     do_kLTRealStackValue : {
3749         REAL v1 = popReal(it);
3750         pushInt((*it)->fRealValue < v1);
3751         dispatchNextScal();
3752     }
3753 
3754     do_kGERealStackValue : {
3755         REAL v1 = popReal(it);
3756         pushInt((*it)->fRealValue >= v1);
3757         dispatchNextScal();
3758     }
3759 
3760     do_kLERealStackValue : {
3761         REAL v1 = popReal(it);
3762         pushInt((*it)->fRealValue <= v1);
3763         dispatchNextScal();
3764     }
3765 
3766     do_kEQRealStackValue : {
3767         REAL v1 = popReal(it);
3768         pushInt((*it)->fRealValue == v1);
3769         dispatchNextScal();
3770     }
3771 
3772     do_kNERealStackValue : {
3773         REAL v1 = popReal(it);
3774         pushInt((*it)->fRealValue != v1);
3775         dispatchNextScal();
3776     }
3777 
3778     // Logical operations
3779     do_kANDIntStackValue : {
3780         int v1 = popInt();
3781         pushInt((*it)->fIntValue & v1);
3782         dispatchNextScal();
3783     }
3784 
3785     do_kORIntStackValue : {
3786         int v1 = popInt();
3787         pushInt((*it)->fIntValue | v1);
3788         dispatchNextScal();
3789     }
3790 
3791     do_kXORIntStackValue : {
3792         int v1 = popInt();
3793         pushInt((*it)->fIntValue ^ v1);
3794         dispatchNextScal();
3795     }
3796 
3797         //------------------------------------------------------
3798         // Standard math operations : 'value' OP 'heap' version
3799         //------------------------------------------------------
3800 
3801     do_kAddRealValue : {
3802         pushReal(it, (*it)->fRealValue + fRealHeap[(*it)->fOffset1]);
3803         dispatchNextScal();
3804     }
3805 
3806     do_kAddIntValue : {
3807         pushInt((*it)->fIntValue + fIntHeap[(*it)->fOffset1]);
3808         dispatchNextScal();
3809     }
3810 
3811     do_kSubRealValue : {
3812         pushReal(it, (*it)->fRealValue - fRealHeap[(*it)->fOffset1]);
3813         dispatchNextScal();
3814     }
3815 
3816     do_kSubIntValue : {
3817         pushInt((*it)->fIntValue - fIntHeap[(*it)->fOffset1]);
3818         dispatchNextScal();
3819     }
3820 
3821     do_kMultRealValue : {
3822         pushReal(it, (*it)->fRealValue * fRealHeap[(*it)->fOffset1]);
3823         dispatchNextScal();
3824     }
3825 
3826     do_kMultIntValue : {
3827         pushInt((*it)->fIntValue * fIntHeap[(*it)->fOffset1]);
3828         dispatchNextScal();
3829     }
3830 
3831     do_kDivRealValue : {
3832         pushReal(it, (*it)->fRealValue / fRealHeap[(*it)->fOffset1]);
3833         dispatchNextScal();
3834     }
3835 
3836     do_kDivIntValue : {
3837         pushInt((*it)->fIntValue / fIntHeap[(*it)->fOffset1]);
3838         dispatchNextScal();
3839     }
3840 
3841     do_kRemRealValue : {
3842         pushReal(it, std::remainder((*it)->fRealValue, fRealHeap[(*it)->fOffset1]));
3843         dispatchNextScal();
3844     }
3845 
3846     do_kRemIntValue : {
3847         pushInt((*it)->fIntValue % fIntHeap[(*it)->fOffset1]);
3848         dispatchNextScal();
3849     }
3850 
3851     // Shift operation
3852     do_kLshIntValue : {
3853         pushInt((*it)->fIntValue << fIntHeap[(*it)->fOffset1]);
3854         dispatchNextScal();
3855     }
3856 
3857     do_kARshIntValue : {
3858         pushInt((*it)->fIntValue >> fIntHeap[(*it)->fOffset1]);
3859         dispatchNextScal();
3860     }
3861 
3862     do_kLRshIntValue : {
3863         // TODO
3864         pushInt((*it)->fIntValue >> fIntHeap[(*it)->fOffset1]);
3865         dispatchNextScal();
3866     }
3867 
3868     // Comparaison Int
3869     do_kGTIntValue : {
3870         pushInt((*it)->fIntValue > fIntHeap[(*it)->fOffset1]);
3871         dispatchNextScal();
3872     }
3873 
3874     do_kLTIntValue : {
3875         pushInt((*it)->fIntValue < fIntHeap[(*it)->fOffset1]);
3876         dispatchNextScal();
3877     }
3878 
3879     do_kGEIntValue : {
3880         pushInt((*it)->fIntValue >= fIntHeap[(*it)->fOffset1]);
3881         dispatchNextScal();
3882     }
3883 
3884     do_kLEIntValue : {
3885         pushInt((*it)->fIntValue <= fIntHeap[(*it)->fOffset1]);
3886         dispatchNextScal();
3887     }
3888 
3889     do_kEQIntValue : {
3890         pushInt((*it)->fIntValue == fIntHeap[(*it)->fOffset1]);
3891         dispatchNextScal();
3892     }
3893 
3894     do_kNEIntValue : {
3895         pushInt((*it)->fIntValue != fIntHeap[(*it)->fOffset1]);
3896         dispatchNextScal();
3897     }
3898 
3899     // Comparaison Real
3900     do_kGTRealValue : {
3901         pushInt((*it)->fRealValue > fRealHeap[(*it)->fOffset1]);
3902         dispatchNextScal();
3903     }
3904 
3905     do_kLTRealValue : {
3906         pushInt((*it)->fRealValue < fRealHeap[(*it)->fOffset1]);
3907         dispatchNextScal();
3908     }
3909 
3910     do_kGERealValue : {
3911         pushInt((*it)->fRealValue >= fRealHeap[(*it)->fOffset1]);
3912         dispatchNextScal();
3913     }
3914 
3915     do_kLERealValue : {
3916         pushInt((*it)->fRealValue <= fRealHeap[(*it)->fOffset1]);
3917         dispatchNextScal();
3918     }
3919 
3920     do_kEQRealValue : {
3921         pushInt((*it)->fRealValue == fRealHeap[(*it)->fOffset1]);
3922         dispatchNextScal();
3923     }
3924 
3925     do_kNERealValue : {
3926         pushInt((*it)->fRealValue != fRealHeap[(*it)->fOffset1]);
3927         dispatchNextScal();
3928     }
3929 
3930     // Logical operations
3931     do_kANDIntValue : {
3932         pushInt((*it)->fIntValue & fIntHeap[(*it)->fOffset1]);
3933         dispatchNextScal();
3934     }
3935 
3936     do_kORIntValue : {
3937         pushInt((*it)->fIntValue | fIntHeap[(*it)->fOffset1]);
3938         dispatchNextScal();
3939     }
3940 
3941     do_kXORIntValue : {
3942         pushInt((*it)->fIntValue ^ fIntHeap[(*it)->fOffset1]);
3943         dispatchNextScal();
3944     }
3945 
3946         //----------------------------------------------------
3947         // Standard math operations : Value inverted version
3948         // (non commutative operations)
3949         //----------------------------------------------------
3950 
3951     do_kSubRealValueInvert : {
3952         pushReal(it, fRealHeap[(*it)->fOffset1] - (*it)->fRealValue);
3953         dispatchNextScal();
3954     }
3955 
3956     do_kSubIntValueInvert : {
3957         pushInt(fIntHeap[(*it)->fOffset1] - (*it)->fIntValue);
3958         dispatchNextScal();
3959     }
3960 
3961     do_kDivRealValueInvert : {
3962         pushReal(it, fRealHeap[(*it)->fOffset1] / (*it)->fRealValue);
3963         dispatchNextScal();
3964     }
3965 
3966     do_kDivIntValueInvert : {
3967         pushInt(fIntHeap[(*it)->fOffset1] / (*it)->fIntValue);
3968         dispatchNextScal();
3969     }
3970 
3971     do_kRemRealValueInvert : {
3972         pushReal(it, std::remainder(fRealHeap[(*it)->fOffset1], (*it)->fRealValue));
3973         dispatchNextScal();
3974     }
3975 
3976     do_kRemIntValueInvert : {
3977         pushInt(fIntHeap[(*it)->fOffset1] % (*it)->fIntValue);
3978         dispatchNextScal();
3979     }
3980 
3981     // Shift operation
3982     do_kLshIntValueInvert : {
3983         pushInt(fIntHeap[(*it)->fOffset1] << (*it)->fIntValue);
3984         dispatchNextScal();
3985     }
3986 
3987     do_kARshIntValueInvert : {
3988         pushInt(fIntHeap[(*it)->fOffset1] >> (*it)->fIntValue);
3989         dispatchNextScal();
3990     }
3991 
3992     do_kLRshIntValueInvert : {
3993         // TODO
3994         pushInt(fIntHeap[(*it)->fOffset1] >> (*it)->fIntValue);
3995         dispatchNextScal();
3996     }
3997 
3998     // Comparaison Int
3999     do_kGTIntValueInvert : {
4000         pushInt(fIntHeap[(*it)->fOffset1] > (*it)->fIntValue);
4001         dispatchNextScal();
4002     }
4003 
4004     do_kLTIntValueInvert : {
4005         pushInt(fIntHeap[(*it)->fOffset1] < (*it)->fIntValue);
4006         dispatchNextScal();
4007     }
4008 
4009     do_kGEIntValueInvert : {
4010         pushInt(fIntHeap[(*it)->fOffset1] >= (*it)->fIntValue);
4011         dispatchNextScal();
4012     }
4013 
4014     do_kLEIntValueInvert : {
4015         pushInt(fIntHeap[(*it)->fOffset1] <= (*it)->fIntValue);
4016         dispatchNextScal();
4017     }
4018 
4019     // Comparaison Real
4020     do_kGTRealValueInvert : {
4021         pushInt(fRealHeap[(*it)->fOffset1] > (*it)->fRealValue);
4022         dispatchNextScal();
4023     }
4024 
4025     do_kLTRealValueInvert : {
4026         pushInt(fRealHeap[(*it)->fOffset1] < (*it)->fRealValue);
4027         dispatchNextScal();
4028     }
4029 
4030     do_kGERealValueInvert : {
4031         pushInt(fRealHeap[(*it)->fOffset1] >= (*it)->fRealValue);
4032         dispatchNextScal();
4033     }
4034 
4035     do_kLERealValueInvert : {
4036         pushInt(fRealHeap[(*it)->fOffset1] <= (*it)->fRealValue);
4037         dispatchNextScal();
4038     }
4039 
4040         //---------------------
4041         // Extended unary math
4042         //---------------------
4043 
4044     do_kAbs : {
4045         int v = popInt();
4046         pushInt(std::abs(v));
4047         dispatchNextScal();
4048     }
4049 
4050     do_kAbsf : {
4051         REAL v = popReal(it);
4052         pushReal(it, std::fabs(v));
4053         dispatchNextScal();
4054     }
4055 
4056     do_kAcosf : {
4057         REAL v = popReal(it);
4058         pushReal(it, std::acos(v));
4059         dispatchNextScal();
4060     }
4061 
4062     do_kAcoshf : {
4063         REAL v = popReal(it);
4064         pushReal(it, std::acosh(v));
4065         dispatchNextScal();
4066     }
4067 
4068     do_kAsinf : {
4069         REAL v = popReal(it);
4070         pushReal(it, std::asin(v));
4071         dispatchNextScal();
4072     }
4073 
4074     do_kAsinhf : {
4075         REAL v = popReal(it);
4076         pushReal(it, std::asinh(v));
4077         dispatchNextScal();
4078     }
4079 
4080     do_kAtanf : {
4081         REAL v = popReal(it);
4082         pushReal(it, std::atan(v));
4083         dispatchNextScal();
4084     }
4085 
4086     do_kAtanhf : {
4087         REAL v = popReal(it);
4088         pushReal(it, std::atanh(v));
4089         dispatchNextScal();
4090     }
4091 
4092     do_kCeilf : {
4093         REAL v = popReal(it);
4094         pushReal(it, std::ceil(v));
4095         dispatchNextScal();
4096     }
4097 
4098     do_kCosf : {
4099         REAL v = popReal(it);
4100         pushReal(it, std::cos(v));
4101         dispatchNextScal();
4102     }
4103 
4104     do_kCoshf : {
4105         REAL v = popReal(it);
4106         pushReal(it, std::cosh(v));
4107         dispatchNextScal();
4108     }
4109 
4110     do_kExpf : {
4111         REAL v = popReal(it);
4112         pushReal(it, std::exp(v));
4113         dispatchNextScal();
4114     }
4115 
4116     do_kFloorf : {
4117         REAL v = popReal(it);
4118         pushReal(it, std::floor(v));
4119         dispatchNextScal();
4120     }
4121 
4122     do_kLogf : {
4123         REAL v = popReal(it);
4124         pushReal(it, std::log(v));
4125         dispatchNextScal();
4126     }
4127 
4128     do_kLog10f : {
4129         REAL v = popReal(it);
4130         pushReal(it, std::log10(v));
4131         dispatchNextScal();
4132     }
4133 
4134     do_kRintf : {
4135         REAL v = popReal(it);
4136         pushReal(it, std::rint(v));
4137         dispatchNextScal();
4138     }
4139 
4140     do_kRoundf : {
4141         REAL v = popReal(it);
4142         pushReal(it, std::round(v));
4143         dispatchNextScal();
4144     }
4145 
4146     do_kSinf : {
4147         REAL v = popReal(it);
4148         pushReal(it, std::sin(v));
4149         dispatchNextScal();
4150     }
4151 
4152     do_kSinhf : {
4153         REAL v = popReal(it);
4154         pushReal(it, std::sinh(v));
4155         dispatchNextScal();
4156     }
4157 
4158     do_kSqrtf : {
4159         REAL v = popReal(it);
4160         pushReal(it, std::sqrt(v));
4161         dispatchNextScal();
4162     }
4163 
4164     do_kTanf : {
4165         REAL v = popReal(it);
4166         pushReal(it, std::tan(v));
4167         dispatchNextScal();
4168     }
4169 
4170     do_kTanhf : {
4171         REAL v = popReal(it);
4172         pushReal(it, std::tanh(v));
4173         dispatchNextScal();
4174     }
4175 
4176     do_kIsnanf : {
4177         REAL v = popReal(it);
4178         pushInt(std::isnan(v));
4179         dispatchNextScal();
4180     }
4181 
4182     do_kIsinff : {
4183         REAL v = popReal(it);
4184         pushInt(std::isinf(v));
4185         dispatchNextScal();
4186     }
4187 
4188         //------------------------------------
4189         // Extended unary math (heap version)
4190         ///-----------------------------------
4191 
4192     do_kAbsHeap : {
4193         pushInt(std::abs(fIntHeap[(*it)->fOffset1]));
4194         dispatchNextScal();
4195     }
4196 
4197     do_kAbsfHeap : {
4198         pushReal(it, std::fabs(fRealHeap[(*it)->fOffset1]));
4199         dispatchNextScal();
4200     }
4201 
4202     do_kAcosfHeap : {
4203         pushReal(it, std::acos(fRealHeap[(*it)->fOffset1]));
4204         dispatchNextScal();
4205     }
4206 
4207     do_kAcoshfHeap : {
4208         pushReal(it, std::acosh(fRealHeap[(*it)->fOffset1]));
4209         dispatchNextScal();
4210     }
4211 
4212     do_kAsinfHeap : {
4213         pushReal(it, std::asin(fRealHeap[(*it)->fOffset1]));
4214         dispatchNextScal();
4215     }
4216 
4217     do_kAsinhfHeap : {
4218         pushReal(it, std::asinh(fRealHeap[(*it)->fOffset1]));
4219         dispatchNextScal();
4220     }
4221 
4222     do_kAtanfHeap : {
4223         pushReal(it, std::atan(fRealHeap[(*it)->fOffset1]));
4224         dispatchNextScal();
4225     }
4226 
4227     do_kAtanhfHeap : {
4228         pushReal(it, std::atanh(fRealHeap[(*it)->fOffset1]));
4229         dispatchNextScal();
4230     }
4231 
4232     do_kCeilfHeap : {
4233         pushReal(it, std::ceil(fRealHeap[(*it)->fOffset1]));
4234         dispatchNextScal();
4235     }
4236 
4237     do_kCosfHeap : {
4238         pushReal(it, std::cos(fRealHeap[(*it)->fOffset1]));
4239         dispatchNextScal();
4240     }
4241 
4242     do_kCoshfHeap : {
4243         pushReal(it, std::cosh(fRealHeap[(*it)->fOffset1]));
4244         dispatchNextScal();
4245     }
4246 
4247     do_kExpfHeap : {
4248         pushReal(it, std::exp(fRealHeap[(*it)->fOffset1]));
4249         dispatchNextScal();
4250     }
4251 
4252     do_kFloorfHeap : {
4253         pushReal(it, std::floor(fRealHeap[(*it)->fOffset1]));
4254         dispatchNextScal();
4255     }
4256 
4257     do_kLogfHeap : {
4258         pushReal(it, std::log(fRealHeap[(*it)->fOffset1]));
4259         dispatchNextScal();
4260     }
4261 
4262     do_kLog10fHeap : {
4263         pushReal(it, std::log10(fRealHeap[(*it)->fOffset1]));
4264         dispatchNextScal();
4265     }
4266 
4267     do_kRintfHeap : {
4268         pushReal(it, std::rint(fRealHeap[(*it)->fOffset1]));
4269         dispatchNextScal();
4270     }
4271 
4272     do_kRoundfHeap : {
4273         pushReal(it, std::round(fRealHeap[(*it)->fOffset1]));
4274         dispatchNextScal();
4275     }
4276 
4277     do_kSinfHeap : {
4278         pushReal(it, std::sin(fRealHeap[(*it)->fOffset1]));
4279         dispatchNextScal();
4280     }
4281 
4282     do_kSinhfHeap : {
4283         pushReal(it, std::sinh(fRealHeap[(*it)->fOffset1]));
4284         dispatchNextScal();
4285     }
4286 
4287     do_kSqrtfHeap : {
4288         pushReal(it, std::sqrt(fRealHeap[(*it)->fOffset1]));
4289         dispatchNextScal();
4290     }
4291 
4292     do_kTanfHeap : {
4293         pushReal(it, std::tan(fRealHeap[(*it)->fOffset1]));
4294         dispatchNextScal();
4295     }
4296 
4297     do_kTanhfHeap : {
4298         pushReal(it, std::tanh(fRealHeap[(*it)->fOffset1]));
4299         dispatchNextScal();
4300     }
4301 
4302         //----------------------
4303         // Extended binary math
4304         //----------------------
4305 
4306     do_kAtan2f : {
4307         REAL v1 = popReal(it);
4308         REAL v2 = popReal(it);
4309         pushReal(it, std::atan2(v1, v2));
4310         dispatchNextScal();
4311     }
4312 
4313     do_kFmodf : {
4314         REAL v1 = popReal(it);
4315         REAL v2 = popReal(it);
4316         pushReal(it, std::fmod(v1, v2));
4317         dispatchNextScal();
4318     }
4319 
4320     do_kPowf : {
4321         REAL v1 = popReal(it);
4322         REAL v2 = popReal(it);
4323         pushReal(it, std::pow(v1, v2));
4324         dispatchNextScal();
4325     }
4326 
4327     do_kMax : {
4328         int v1 = popInt();
4329         int v2 = popInt();
4330         pushInt(std::max(v1, v2));
4331         dispatchNextScal();
4332     }
4333 
4334     do_kMaxf : {
4335         REAL v1 = popReal(it);
4336         REAL v2 = popReal(it);
4337         pushReal(it, std::max(v1, v2));
4338         dispatchNextScal();
4339     }
4340 
4341     do_kMin : {
4342         int v1 = popInt();
4343         int v2 = popInt();
4344         pushInt(std::min(v1, v2));
4345         dispatchNextScal();
4346     }
4347 
4348     do_kMinf : {
4349         REAL v1 = popReal(it);
4350         REAL v2 = popReal(it);
4351         pushReal(it, std::min(v1, v2));
4352         dispatchNextScal();
4353     }
4354 
4355     do_kCopysignf : {
4356         REAL v1 = popReal(it);
4357         REAL v2 = popReal(it);
4358         pushReal(it, std::copysign(v1, v2));
4359         dispatchNextScal();
4360     }
4361 
4362         //-------------------------------------
4363         // Extended binary math (heap version)
4364         //-------------------------------------
4365 
4366     do_kAtan2fHeap : {
4367         pushReal(it, std::atan2(fRealHeap[(*it)->fOffset1], fRealHeap[(*it)->fOffset2]));
4368         dispatchNextScal();
4369     }
4370 
4371     do_kFmodfHeap : {
4372         pushReal(it, std::fmod(fRealHeap[(*it)->fOffset1], fRealHeap[(*it)->fOffset2]));
4373         dispatchNextScal();
4374     }
4375 
4376     do_kPowfHeap : {
4377         pushReal(it, std::pow(fRealHeap[(*it)->fOffset1], fRealHeap[(*it)->fOffset2]));
4378         dispatchNextScal();
4379     }
4380 
4381     do_kMaxHeap : {
4382         pushInt(std::max(fIntHeap[(*it)->fOffset1], fIntHeap[(*it)->fOffset2]));
4383         dispatchNextScal();
4384     }
4385 
4386     do_kMaxfHeap : {
4387         pushReal(it, std::max(fRealHeap[(*it)->fOffset1], fRealHeap[(*it)->fOffset2]));
4388         dispatchNextScal();
4389     }
4390 
4391     do_kMinHeap : {
4392         pushInt(std::min(fIntHeap[(*it)->fOffset1], fIntHeap[(*it)->fOffset2]));
4393         dispatchNextScal();
4394     }
4395 
4396     do_kMinfHeap : {
4397         pushReal(it, std::min(fRealHeap[(*it)->fOffset1], fRealHeap[(*it)->fOffset2]));
4398         dispatchNextScal();
4399     }
4400 
4401         //--------------------------------------
4402         // Extended binary math (stack version)
4403         //--------------------------------------
4404 
4405     do_kAtan2fStack : {
4406         REAL v1 = popReal(it);
4407         pushReal(it, std::atan2(fRealHeap[(*it)->fOffset1], v1));
4408         dispatchNextScal();
4409     }
4410 
4411     do_kFmodfStack : {
4412         REAL v1 = popReal(it);
4413         pushReal(it, std::fmod(fRealHeap[(*it)->fOffset1], v1));
4414         dispatchNextScal();
4415     }
4416 
4417     do_kPowfStack : {
4418         REAL v1 = popReal(it);
4419         pushReal(it, std::pow(fRealHeap[(*it)->fOffset1], v1));
4420         dispatchNextScal();
4421     }
4422 
4423     do_kMaxStack : {
4424         int v1 = popInt();
4425         pushInt(std::max(fIntHeap[(*it)->fOffset1], v1));
4426         dispatchNextScal();
4427     }
4428 
4429     do_kMaxfStack : {
4430         REAL v1 = popReal(it);
4431         pushReal(it, std::max(fRealHeap[(*it)->fOffset1], v1));
4432         dispatchNextScal();
4433     }
4434 
4435     do_kMinStack : {
4436         int v1 = popInt();
4437         pushInt(std::min(fIntHeap[(*it)->fOffset1], v1));
4438         dispatchNextScal();
4439     }
4440 
4441     do_kMinfStack : {
4442         REAL v1 = popReal(it);
4443         pushReal(it, std::min(fRealHeap[(*it)->fOffset1], v1));
4444         dispatchNextScal();
4445     }
4446 
4447         //--------------------------------------------
4448         // Extended binary math (stack/value version)
4449         //--------------------------------------------
4450 
4451     do_kAtan2fStackValue : {
4452         REAL v1 = popReal(it);
4453         pushReal(it, std::atan2((*it)->fRealValue, v1));
4454         dispatchNextScal();
4455     }
4456 
4457     do_kFmodfStackValue : {
4458         REAL v1 = popReal(it);
4459         pushReal(it, std::fmod((*it)->fRealValue, v1));
4460         dispatchNextScal();
4461     }
4462 
4463     do_kPowfStackValue : {
4464         REAL v1 = popReal(it);
4465         pushReal(it, std::pow((*it)->fRealValue, v1));
4466         dispatchNextScal();
4467     }
4468 
4469     do_kMaxStackValue : {
4470         int v1 = popInt();
4471         pushInt(std::max((*it)->fIntValue, v1));
4472         dispatchNextScal();
4473     }
4474 
4475     do_kMaxfStackValue : {
4476         REAL v1 = popReal(it);
4477         pushReal(it, std::max((*it)->fRealValue, v1));
4478         dispatchNextScal();
4479     }
4480 
4481     do_kMinStackValue : {
4482         int v1 = popInt();
4483         pushInt(std::min((*it)->fIntValue, v1));
4484         dispatchNextScal();
4485     }
4486 
4487     do_kMinfStackValue : {
4488         REAL v1 = popReal(it);
4489         pushReal(it, std::min((*it)->fRealValue, v1));
4490         dispatchNextScal();
4491     }
4492 
4493         //-------------------------------------
4494         // Extended binary math (Value version)
4495         //-------------------------------------
4496 
4497     do_kAtan2fValue : {
4498         pushReal(it, std::atan2((*it)->fRealValue, fRealHeap[(*it)->fOffset1]));
4499         dispatchNextScal();
4500     }
4501 
4502     do_kFmodfValue : {
4503         pushReal(it, std::fmod((*it)->fRealValue, fRealHeap[(*it)->fOffset1]));
4504         dispatchNextScal();
4505     }
4506 
4507     do_kPowfValue : {
4508         pushReal(it, std::pow((*it)->fRealValue, fRealHeap[(*it)->fOffset1]));
4509         dispatchNextScal();
4510     }
4511 
4512     do_kMaxValue : {
4513         pushInt(std::max((*it)->fIntValue, fIntHeap[(*it)->fOffset1]));
4514         dispatchNextScal();
4515     }
4516 
4517     do_kMaxfValue : {
4518         pushReal(it, std::max((*it)->fRealValue, fRealHeap[(*it)->fOffset1]));
4519         dispatchNextScal();
4520     }
4521 
4522     do_kMinValue : {
4523         pushInt(std::min((*it)->fIntValue, fIntHeap[(*it)->fOffset1]));
4524         dispatchNextScal();
4525     }
4526 
4527     do_kMinfValue : {
4528         pushReal(it, std::min((*it)->fRealValue, fRealHeap[(*it)->fOffset1]));
4529         dispatchNextScal();
4530     }
4531 
4532         //-------------------------------------------------------------------
4533         // Extended binary math (Value version) : non commutative operations
4534         //-------------------------------------------------------------------
4535 
4536     do_kAtan2fValueInvert : {
4537         pushReal(it, std::atan2(fRealHeap[(*it)->fOffset1], (*it)->fRealValue));
4538         dispatchNextScal();
4539     }
4540 
4541     do_kFmodfValueInvert : {
4542         pushReal(it, std::fmod(fRealHeap[(*it)->fOffset1], (*it)->fRealValue));
4543         dispatchNextScal();
4544     }
4545 
4546     do_kPowfValueInvert : {
4547         pushReal(it, std::pow(fRealHeap[(*it)->fOffset1], (*it)->fRealValue));
4548         dispatchNextScal();
4549     }
4550 
4551         //---------
4552         // Control
4553         //---------
4554 
4555     do_kReturn : {
4556         // Empty addr stack = end of computation
4557         if (emptyReturnScal()) {
4558             goto end;
4559         } else {
4560             dispatchReturnScal();
4561         }
4562     }
4563 
4564     do_kIf : {
4565         // Keep next instruction
4566         saveReturnScal();
4567 
4568         if (popInt()) {
4569             // Execute new block
4570             assertInterp((*it)->fBranch1);
4571             dispatchBranch1Scal();
4572             // No value (If)
4573         } else {
4574             // Execute new block
4575             assertInterp((*it)->fBranch2);
4576             dispatchBranch2Scal();
4577             // No value (If)
4578         }
4579     }
4580 
4581     do_kSelectReal : {
4582         // Keep next instruction
4583         saveReturnScal();
4584 
4585         if (popInt()) {
4586             // Execute new block
4587             assertInterp((*it)->fBranch1);
4588             dispatchBranch1Scal();
4589             // Real value
4590         } else {
4591             // Execute new block
4592             assertInterp((*it)->fBranch2);
4593             dispatchBranch2Scal();
4594             // Real value
4595         }
4596     }
4597 
4598     do_kSelectInt : {
4599         // Keep next instruction
4600         saveReturnScal();
4601 
4602         if (popInt()) {
4603             // Execute new block
4604             assertInterp((*it)->fBranch1);
4605             dispatchBranch1Scal();
4606             // Int value
4607         } else {
4608             // Execute new block
4609             assertInterp((*it)->fBranch2);
4610             dispatchBranch2Scal();
4611             // Int value
4612         }
4613     }
4614 
4615     do_kCondBranch : {
4616         // If condition is true, just branch back on the block beginning
4617         if (popInt()) {
4618             assertInterp((*it)->fBranch1);
4619             dispatchBranch1Scal();
4620         } else {
4621             // Just continue after 'loop block' (do the final 'return')
4622             dispatchNextScal();
4623         }
4624     }
4625 
4626     do_kLoop : {
4627         // Keep next instruction
4628         saveReturnScal();
4629 
4630         // Push branch2 (loop content)
4631         assertInterp((*it)->fBranch2);
4632         pushBranch2Scal();
4633 
4634         // And start branch1 loop variable declaration block
4635         assertInterp((*it)->fBranch1);
4636         dispatchBranch1Scal();
4637     }
4638 
4639     end:
4640         // Check stack coherency
4641         assertInterp(real_stack_index == 0 && int_stack_index == 0 && sound_stack_index == 0);
4642     }
4643 #endif
4644 
4645    public:
FBCInterpreter(interpreter_dsp_factory_aux<REAL,TRACE> * factory)4646     FBCInterpreter(interpreter_dsp_factory_aux<REAL, TRACE>* factory)
4647     {
4648         /*
4649         std::cout << "FBCInterpreter :"
4650                 << " int_heap_size " << int_heap_size
4651                 << " real_heap_size " << real_heap_size
4652                 << " sr_offset " << sr_offset
4653                 << " count_offset " << count_offset << std::endl;
4654         */
4655 
4656         fFactory = factory;
4657 
4658         if (fFactory->getMemoryManager()) {
4659             fRealHeap  = static_cast<REAL*>(fFactory->allocate(sizeof(REAL) * fFactory->fRealHeapSize));
4660             fIntHeap   = static_cast<int*>(fFactory->allocate(sizeof(REAL) * fFactory->fIntHeapSize));
4661             fSoundHeap = static_cast<Soundfile**>(fFactory->allocate(sizeof(Soundfile*) * fFactory->fSoundHeapSize));
4662             fInputs    = static_cast<REAL**>(fFactory->allocate(sizeof(REAL*) * fFactory->fNumInputs));
4663             fOutputs   = static_cast<REAL**>(fFactory->allocate(sizeof(REAL*) * fFactory->fNumOutputs));
4664         } else {
4665             fRealHeap  = new REAL[fFactory->fRealHeapSize];
4666             fIntHeap   = new int[fFactory->fIntHeapSize];
4667             fSoundHeap = new Soundfile*[fFactory->fSoundHeapSize];
4668             fInputs    = new REAL*[fFactory->fNumInputs];
4669             fOutputs   = new REAL*[fFactory->fNumOutputs];
4670         }
4671 
4672         // std::cout << "==== FBCInterpreter ==== " << std::endl;
4673         // std::cout << "fRealHeapSize = " << fFactory->fRealHeapSize << std::endl;
4674         // std::cout << "fIntHeapSize = " << fFactory->fIntHeapSize << std::endl;
4675 
4676         // Initialise HEAP with special values to detect incorrect Load access
4677         for (int i = 0; i < fFactory->fRealHeapSize; i++) {
4678             fRealHeap[i] = REAL(DUMMY_REAL);
4679         }
4680         for (int i = 0; i < fFactory->fIntHeapSize; i++) {
4681             fIntHeap[i] = DUMMY_INT;
4682         }
4683 
4684         fRealStats[INTEGER_OVERFLOW]  = 0;
4685         fRealStats[DIV_BY_ZERO_REAL]  = 0;
4686         fRealStats[DIV_BY_ZERO_INT]   = 0;
4687         fRealStats[FP_INFINITE]       = 0;
4688         fRealStats[FP_NAN]            = 0;
4689         fRealStats[FP_SUBNORMAL]      = 0;
4690         fRealStats[CAST_INT_OVERFLOW] = 0;
4691     }
4692 
~FBCInterpreter()4693     virtual ~FBCInterpreter()
4694     {
4695         for (const auto& it : fPathInputTable) {
4696             delete it.second;
4697         }
4698         for (const auto& it : fPathOutputTable) {
4699             delete it.second;
4700         }
4701         if (fFactory->getMemoryManager()) {
4702             fFactory->destroy(fRealHeap);
4703             fFactory->destroy(fIntHeap);
4704             fFactory->destroy(fSoundHeap);
4705             fFactory->destroy(fInputs);
4706             fFactory->destroy(fOutputs);
4707         } else {
4708             delete[] fRealHeap;
4709             delete[] fIntHeap;
4710             delete[] fSoundHeap;
4711             delete[] fInputs;
4712             delete[] fOutputs;
4713         }
4714         if (TRACE > 0) {
4715             printStats();
4716         }
4717     }
4718 
dumpMemory(FBCBlockInstruction<REAL> * block,const std::string & name,const std::string & filename)4719     void dumpMemory(FBCBlockInstruction<REAL>* block, const std::string& name, const std::string& filename)
4720     {
4721         std::ofstream out(filename);
4722         out << "DSP name: " << name << std::endl;
4723 
4724         out << "REAL memory: " << fFactory->fRealHeapSize << "\n";
4725         for (int i = 0; i < fFactory->fRealHeapSize; i++) {
4726             out << "mem: " << i << " " << fRealHeap[i] << std::endl;
4727         }
4728 
4729         out << "INT memory: " << fFactory->fIntHeapSize << "\n";
4730         for (int i = 0; i < fFactory->fIntHeapSize; i++) {
4731             out << "mem: " << i << " " << fIntHeap[i] << std::endl;
4732         }
4733     }
4734 
setIntValue(int offset,int value)4735     void setIntValue(int offset, int value) { fIntHeap[offset] = value; }
getIntValue(int offset)4736     int  getIntValue(int offset) { return fIntHeap[offset]; }
4737 
setInput(int input,REAL * buffer)4738     virtual void setInput(int input, REAL* buffer) { fInputs[input] = buffer; }
setOutput(int output,REAL * buffer)4739     virtual void setOutput(int output, REAL* buffer) { fOutputs[output] = buffer; }
4740 };
4741 
4742 #endif
4743