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(), ¶m->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(), ¶m->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(), ¶m->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(), ¶m->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(), ¶m->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(), ¶m->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(), ¶m->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