Fennel: /home/pub/open/dev/fennel/calculator/NativeNativeInstruction.h Source File (original) (raw)

00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 00017 00018 00019 00020 00021 00022 00023 00024 00025 00026 00027 00028 #ifndef Fennel_NativeNativeInstruction_Included 00029 #define Fennel_NativeNativeInstruction_Included 00030 00031 #include "fennel/calculator/NativeInstruction.h" 00032 #include <math.h> 00033 #include "NoisyArithmetic.h" 00034 00035 FENNEL_BEGIN_NAMESPACE 00036 00037 template 00038 class NativeNativeInstruction : public NativeInstruction 00039 { 00040 public: 00041 explicit 00042 NativeNativeInstruction( 00043 RegisterRef* result, 00044 StandardTypeDescriptorOrdinal nativeType) 00045 : NativeInstruction(nativeType), 00046 mResult(result) 00047 {} 00048 00049 explicit 00050 NativeNativeInstruction( 00051 RegisterRef* result, 00052 RegisterRef* op1, 00053 StandardTypeDescriptorOrdinal nativeType) 00054 : NativeInstruction(op1, nativeType), 00055 mResult(result) 00056 {} 00057 00058 explicit 00059 NativeNativeInstruction( 00060 RegisterRef* result, 00061 RegisterRef* op1, 00062 RegisterRef* op2, 00063 StandardTypeDescriptorOrdinal nativeType) 00064 : NativeInstruction(op1, op2, nativeType), 00065 mResult(result) 00066 {} 00067 00068 virtual 00069 ~NativeNativeInstruction() {} 00070 00071 protected: 00072 RegisterRef* mResult; 00073 static void fnSetRegisterToNull(const char , void pOpaque) { 00074 RegisterRef pReg = (RegisterRef )pOpaque; 00075 if (pReg->isNullable()) { 00076 pReg->toNull(); 00077 } 00078 } 00079 }; 00080 00081 template 00082 class NativeAdd : public NativeNativeInstruction 00083 { 00084 public: 00085 explicit 00086 NativeAdd( 00087 RegisterRef result, 00088 RegisterRef op1, 00089 RegisterRef op2, 00090 StandardTypeDescriptorOrdinal nativeType) 00091 : NativeNativeInstruction(result, op1, op2, nativeType) 00092 {} 00093 00094 virtual 00095 ~NativeAdd() {} 00096 00097 virtual void exec(TProgramCounter& pc) const { 00098 pc++; 00099 if (NativeInstruction::mOp1->isNull() || 00100 NativeInstruction::mOp2->isNull()) { 00101
00102 NativeNativeInstruction::mResult->toNull(); 00103 } else { 00104 TExceptionCBData tE( 00105 NativeNativeInstruction::fnSetRegisterToNull, 00106 NativeNativeInstruction::mResult); 00107 NativeNativeInstruction::mResult->value( 00108 Noisy::add( 00109 pc - 1, 00110 NativeInstruction::mOp1->value(), 00111 NativeInstruction::mOp2->value(), &tE)); 00112 } 00113 } 00114 00115 static const char * longName() 00116 { 00117 return "NativeAdd"; 00118 } 00119 00120 static const char * shortName() 00121 { 00122 return "ADD"; 00123 } 00124 00125 static int numArgs() 00126 { 00127 return 3; 00128 } 00129 00130 void describe(string& out, bool values) const { 00131 describeHelper( 00132 out, values, longName(), shortName(), 00133 NativeNativeInstruction::mResult, 00134 NativeInstruction::mOp1, 00135 NativeInstruction::mOp2); 00136 } 00137 00138 static InstructionSignature 00139 signature(StandardTypeDescriptorOrdinal type) { 00140 vector v(numArgs(), type); 00141 return InstructionSignature(shortName(), v); 00142 } 00143 00144 static Instruction
00145 create(InstructionSignature const & sig) 00146 { 00147 assert(sig.size() == numArgs()); 00148 return new NativeAdd( 00149 static_cast<RegisterRef> (sig[0]), 00150 static_cast<RegisterRef> (sig[1]), 00151 static_cast<RegisterRef> (sig[2]), 00152 (sig[0])->type()); 00153 } 00154 }; 00155 00156 template 00157 class NativeSub : public NativeNativeInstruction 00158 { 00159 public: 00160 explicit 00161 NativeSub( 00162 RegisterRef result, 00163 RegisterRef* op1, 00164 RegisterRef* op2, 00165 StandardTypeDescriptorOrdinal nativeType) 00166 : NativeNativeInstruction(result, op1, op2, nativeType) 00167 {} 00168 virtual 00169 ~NativeSub() {} 00170 00171 virtual void exec(TProgramCounter& pc) const { 00172 pc++; 00173 if (NativeInstruction::mOp1->isNull() || 00174 NativeInstruction::mOp2->isNull()) { 00175
00176 NativeNativeInstruction::mResult->toNull(); 00177 } else { 00178 TExceptionCBData tE( 00179 NativeNativeInstruction::fnSetRegisterToNull, 00180 NativeNativeInstruction::mResult); 00181 NativeNativeInstruction::mResult->value( 00182 Noisy::sub( 00183 pc - 1, 00184 NativeInstruction::mOp1->value(), 00185 NativeInstruction::mOp2->value(), &tE)); 00186 } 00187 } 00188 00189 static char const * const longName() 00190 { 00191 return "NativeSub"; 00192 } 00193 00194 static char const * const shortName() 00195 { 00196 return "SUB"; 00197 } 00198 00199 static int numArgs() 00200 { 00201 return 3; 00202 } 00203 00204 void describe(string& out, bool values) const { 00205 describeHelper( 00206 out, values, longName(), shortName(), 00207 NativeNativeInstruction::mResult, 00208 NativeInstruction::mOp1, 00209 NativeInstruction::mOp2); 00210 } 00211 00212 static InstructionSignature 00213 signature(StandardTypeDescriptorOrdinal type) { 00214 vector v(numArgs(), type); 00215 return InstructionSignature(shortName(), v); 00216 } 00217 00218 static Instruction* 00219 create(InstructionSignature const & sig) 00220 { 00221 assert(sig.size() == numArgs()); 00222 return new NativeSub( 00223 static_cast<RegisterRef> (sig[0]), 00224 static_cast<RegisterRef> (sig[1]), 00225 static_cast<RegisterRef> (sig[2]), 00226 (sig[0])->type()); 00227 } 00228 }; 00229 00230 template 00231 class NativeMul : public NativeNativeInstruction 00232 { 00233 public: 00234 explicit 00235 NativeMul( 00236 RegisterRef result, 00237 RegisterRef* op1, 00238 RegisterRef* op2, 00239 StandardTypeDescriptorOrdinal nativeType) 00240 : NativeNativeInstruction(result, op1, op2, nativeType) 00241 {} 00242 00243 virtual 00244 ~NativeMul() {} 00245 00246 virtual void exec(TProgramCounter& pc) const { 00247 pc++; 00248 if (NativeInstruction::mOp1->isNull() || 00249 NativeInstruction::mOp2->isNull()) { 00250
00251 NativeNativeInstruction::mResult->toNull(); 00252 } else { 00253 TExceptionCBData tE( 00254 NativeNativeInstruction::fnSetRegisterToNull, 00255 NativeNativeInstruction::mResult); 00256 NativeNativeInstruction::mResult->value( 00257 Noisy::mul( 00258 pc - 1, 00259 NativeInstruction::mOp1->value(), 00260 NativeInstruction::mOp2->value(), &tE)); 00261 } 00262 } 00263 00264 static char const * const longName() 00265 { 00266 return "NativeMul"; 00267 } 00268 00269 static char const * const shortName() 00270 { 00271 return "MUL"; 00272 } 00273 00274 static int numArgs() 00275 { 00276 return 3; 00277 } 00278 00279 void describe(string& out, bool values) const { 00280 describeHelper( 00281 out, values, longName(), shortName(), 00282 NativeNativeInstruction::mResult, 00283 NativeInstruction::mOp1, 00284 NativeInstruction::mOp2); 00285 } 00286 00287 static InstructionSignature 00288 signature(StandardTypeDescriptorOrdinal type) { 00289 vector v(numArgs(), type); 00290 return InstructionSignature(shortName(), v); 00291 } 00292 00293 static Instruction* 00294 create(InstructionSignature const & sig) 00295 { 00296 assert(sig.size() == numArgs()); 00297 return new NativeMul( 00298 static_cast<RegisterRef> (sig[0]), 00299 static_cast<RegisterRef> (sig[1]), 00300 static_cast<RegisterRef> (sig[2]), 00301 (sig[0])->type()); 00302 } 00303 }; 00304 00305 template 00306 class NativeDiv : public NativeNativeInstruction 00307 { 00308 public: 00309 explicit 00310 NativeDiv( 00311 RegisterRef result, 00312 RegisterRef* op1, 00313 RegisterRef* op2, 00314 StandardTypeDescriptorOrdinal nativeType) 00315 : NativeNativeInstruction(result, op1, op2, nativeType) 00316 {} 00317 00318 virtual 00319 ~NativeDiv() {} 00320 00321 virtual void exec(TProgramCounter& pc) const { 00322 pc++; 00323 if (NativeInstruction::mOp1->isNull() || 00324 NativeInstruction::mOp2->isNull()) { 00325
00326 NativeNativeInstruction::mResult->toNull(); 00327 } else { 00328 #if 0 00329
00330
00331 TMPLT o2 = NativeInstruction::mOp2->value(); 00332 if (o2 == 0) { 00333
00334 NativeNativeInstruction::mResult->toNull(); 00335
00336
00337 throw CalcMessage("22012", pc - 1); 00338 } 00339 #endif 00340 TExceptionCBData tE( 00341 NativeNativeInstruction::fnSetRegisterToNull, 00342 NativeNativeInstruction::mResult); 00343 NativeNativeInstruction::mResult->value( 00344 Noisy::div( 00345 pc - 1, 00346 NativeInstruction::mOp1->value(), 00347 NativeInstruction::mOp2->value(), &tE)); 00348 } 00349 } 00350 00351 static char const * const longName() 00352 { 00353 return "NativeDiv"; 00354 } 00355 00356 static char const * const shortName() 00357 { 00358 return "DIV"; 00359 } 00360 00361 static int numArgs() 00362 { 00363 return 3; 00364 } 00365 00366 void describe(string& out, bool values) const { 00367 describeHelper( 00368 out, values, longName(), shortName(), 00369 NativeNativeInstruction::mResult, 00370 NativeInstruction::mOp1, 00371 NativeInstruction::mOp2); 00372 } 00373 00374 static InstructionSignature 00375 signature(StandardTypeDescriptorOrdinal type) { 00376 vector v(numArgs(), type); 00377 return InstructionSignature(shortName(), v); 00378 } 00379 00380 static Instruction* 00381 create(InstructionSignature const & sig) 00382 { 00383 assert(sig.size() == numArgs()); 00384 return new NativeDiv( 00385 static_cast<RegisterRef> (sig[0]), 00386 static_cast<RegisterRef> (sig[1]), 00387 static_cast<RegisterRef> (sig[2]), 00388 (sig[0])->type()); 00389 } 00390 }; 00391 00392 00393 00394 template 00395 class NativeNeg : public NativeNativeInstruction 00396 { 00397 public: 00398 explicit 00399 NativeNeg( 00400 RegisterRef result, 00401 RegisterRef* op1, 00402 StandardTypeDescriptorOrdinal nativeType) 00403 : NativeNativeInstruction(result, op1, nativeType) 00404 {} 00405 virtual 00406 ~NativeNeg() {} 00407 00408 virtual void exec(TProgramCounter& pc) const { 00409 pc++; 00410 if (NativeInstruction::mOp1->isNull()) { 00411
00412 NativeNativeInstruction::mResult->toNull(); 00413 } else { 00414 TExceptionCBData tE( 00415 NativeNativeInstruction::fnSetRegisterToNull, 00416 NativeNativeInstruction::mResult); 00417 NativeNativeInstruction::mResult-> 00418 value( 00419 Noisy::neg( 00420 pc - 1, 00421 NativeInstruction::mOp1->value(), &tE)); 00422 } 00423 } 00424 00425 static char const * const longName() 00426 { 00427 return "NativeNeg"; 00428 } 00429 00430 static char const * const shortName() 00431 { 00432 return "NEG"; 00433 } 00434 00435 static int numArgs() 00436 { 00437 return 2; 00438 } 00439 00440 void describe(string& out, bool values) const { 00441 describeHelper( 00442 out, values, longName(), shortName(), 00443 NativeNativeInstruction::mResult, 00444 NativeInstruction::mOp1, 00445 NativeInstruction::mOp2); 00446 } 00447 00448 static InstructionSignature 00449 signature(StandardTypeDescriptorOrdinal type) { 00450 vector v(numArgs(), type); 00451 return InstructionSignature(shortName(), v); 00452 } 00453 00454 static Instruction* 00455 create(InstructionSignature const & sig) 00456 { 00457 assert(sig.size() == numArgs()); 00458 return new NativeNeg( 00459 static_cast<RegisterRef> (sig[0]), 00460 static_cast<RegisterRef> (sig[1]), 00461 (sig[0])->type()); 00462 } 00463 }; 00464 00465 template 00466 class NativeRoundHelp { 00467 public: 00468 static void r(TMPLT& result, TMPLT op1) { 00469
00470 result = op1; 00471 } 00472 }; 00473 00474 template<> 00475 class NativeRoundHelp { 00476 public: 00477 static void r(double& result, double op1) { 00478
00479 result = round(op1); 00480 } 00481 }; 00482 00483 template<> 00484 class NativeRoundHelp { 00485 public: 00486 static void r(float& result, float op1) { 00487
00488 result = roundf(op1); 00489 } 00490 }; 00491 00492 00493 00494 00495 template 00496 class NativeRound : public NativeNativeInstruction 00497 { 00498 public: 00499 explicit 00500 NativeRound( 00501 RegisterRef* result, 00502 RegisterRef* op1, 00503 StandardTypeDescriptorOrdinal nativeType) 00504 : NativeNativeInstruction(result, op1, nativeType) 00505 {} 00506 virtual 00507 ~NativeRound() {} 00508 00509 virtual void exec(TProgramCounter& pc) const { 00510 pc++; 00511 if (NativeInstruction::mOp1->isNull()) { 00512 NativeNativeInstruction::mResult->toNull(); 00513 } else { 00514
00515 TMPLT tmp; 00516 NativeRoundHelp::r 00517 (tmp, NativeInstruction::mOp1->value()); 00518 NativeNativeInstruction::mResult->value(tmp); 00519 } 00520 } 00521 00522 static char const * const longName() 00523 { 00524 return "NativeRound"; 00525 } 00526 00527 static char const * const shortName() 00528 { 00529 return "ROUND"; 00530 } 00531 00532 static int numArgs() 00533 { 00534 return 2; 00535 } 00536 00537 void describe(string& out, bool values) const { 00538 describeHelper( 00539 out, values, longName(), shortName(), 00540 NativeNativeInstruction::mResult, 00541 NativeInstruction::mOp1, 00542 NativeInstruction::mOp2); 00543 } 00544 00545 static InstructionSignature 00546 signature(StandardTypeDescriptorOrdinal type) { 00547 vector v(numArgs(), type); 00548 return InstructionSignature(shortName(), v); 00549 } 00550 00551 static Instruction* 00552 create(InstructionSignature const & sig) 00553 { 00554 assert(sig.size() == numArgs()); 00555 return new NativeRound( 00556 static_cast<RegisterRef> (sig[0]), 00557 static_cast<RegisterRef> (sig[1]), 00558 (sig[0])->type()); 00559 } 00560 }; 00561 00562 template 00563 class NativeMove : public NativeNativeInstruction 00564 { 00565 public: 00566 explicit 00567 NativeMove( 00568 RegisterRef* result, 00569 RegisterRef* op1, 00570 StandardTypeDescriptorOrdinal nativeType) 00571 : NativeNativeInstruction(result, op1, nativeType) 00572 {} 00573 virtual 00574 ~NativeMove() {} 00575 00576 virtual void exec(TProgramCounter& pc) const { 00577 pc++; 00578 if (NativeInstruction::mOp1->isNull()) { 00579 NativeNativeInstruction::mResult->toNull(); 00580 } else { 00581 NativeNativeInstruction::mResult->value 00582 (NativeInstruction::mOp1->value()); 00583 } 00584 } 00585 static char const * const longName() 00586 { 00587 return "NativeMove"; 00588 } 00589 00590 static char const * const shortName() 00591 { 00592 return "MOVE"; 00593 } 00594 00595 static int numArgs() 00596 { 00597 return 2; 00598 } 00599 00600 void describe(string& out, bool values) const { 00601 describeHelper( 00602 out, values, longName(), shortName(), 00603 NativeNativeInstruction::mResult, 00604 NativeInstruction::mOp1, 00605 NativeInstruction::mOp2); 00606 } 00607 00608 static InstructionSignature 00609 signature(StandardTypeDescriptorOrdinal type) { 00610 vector v(numArgs(), type); 00611 return InstructionSignature(shortName(), v); 00612 } 00613 00614 static Instruction* 00615 create(InstructionSignature const & sig) 00616 { 00617 assert(sig.size() == numArgs()); 00618 return new NativeMove( 00619 static_cast<RegisterRef> (sig[0]), 00620 static_cast<RegisterRef> (sig[1]), 00621 (sig[0])->type()); 00622 } 00623 }; 00624 00625 template 00626 class NativeRef : public NativeNativeInstruction 00627 { 00628 public: 00629 explicit 00630 NativeRef( 00631 RegisterRef* result, 00632 RegisterRef* op1, 00633 StandardTypeDescriptorOrdinal nativeType) 00634 : NativeNativeInstruction(result, op1, nativeType) 00635 {} 00636 virtual 00637 ~NativeRef() {} 00638 00639 virtual void exec(TProgramCounter& pc) const { 00640 pc++; 00641 NativeNativeInstruction::mResult-> 00642 refer(NativeInstruction::mOp1); 00643 } 00644 00645 static char const * const longName() 00646 { 00647 return "NativeRef"; 00648 } 00649 00650 static char const * const shortName() 00651 { 00652 return "REF"; 00653 } 00654 00655 static int numArgs() 00656 { 00657 return 2; 00658 } 00659 00660 void describe(string& out, bool values) const { 00661 describeHelper( 00662 out, values, longName(), shortName(), 00663 NativeNativeInstruction::mResult, 00664 NativeInstruction::mOp1, 00665 NativeInstruction::mOp2); 00666 } 00667 00668 static InstructionSignature 00669 signature(StandardTypeDescriptorOrdinal type) { 00670 vector v(numArgs(), type); 00671 return InstructionSignature(shortName(), v); 00672 } 00673 00674 static Instruction* 00675 create(InstructionSignature const & sig) 00676 { 00677 assert(sig.size() == numArgs()); 00678 return new NativeRef( 00679 static_cast<RegisterRef> (sig[0]), 00680 static_cast<RegisterRef> (sig[1]), 00681 (sig[0])->type()); 00682 } 00683 }; 00684 00685 template 00686 class NativeToNull : public NativeNativeInstruction 00687 { 00688 public: 00689 explicit 00690 NativeToNull( 00691 RegisterRef* result, 00692 StandardTypeDescriptorOrdinal nativeType) 00693 : NativeNativeInstruction(result, nativeType) 00694 {} 00695 00696 virtual 00697 ~NativeToNull() {} 00698 00699 virtual void exec(TProgramCounter& pc) const { 00700 pc++; 00701 NativeNativeInstruction::mResult->toNull(); 00702 } 00703 00704 static char const * const longName() 00705 { 00706 return "NativeToNull"; 00707 } 00708 00709 static char const * const shortName() 00710 { 00711 return "TONULL"; 00712 } 00713 00714 static int numArgs() 00715 { 00716 return 1; 00717 } 00718 00719 void describe(string& out, bool values) const { 00720 describeHelper( 00721 out, values, longName(), shortName(), 00722 NativeNativeInstruction::mResult, 00723 NativeInstruction::mOp1, 00724 NativeInstruction::mOp2); 00725 } 00726 00727 static InstructionSignature 00728 signature(StandardTypeDescriptorOrdinal type) { 00729 vector v(numArgs(), type); 00730 return InstructionSignature(shortName(), v); 00731 } 00732 00733 static Instruction* 00734 create(InstructionSignature const & sig) 00735 { 00736 assert(sig.size() == numArgs()); 00737 return new NativeToNull( 00738 static_cast<RegisterRef*> (sig[0]), 00739 (sig[0])->type()); 00740 } 00741 }; 00742 00743 class FENNEL_CALCULATOR_EXPORT NativeNativeInstructionRegister 00744 : InstructionRegister 00745 { 00746
00747 template < template class INSTCLASS2 > 00748 static void 00749 registerTypes(vector const & t) { 00750 00751 for (uint i = 0; i < t.size(); i++) { 00752 StandardTypeDescriptorOrdinal type = t[i]; 00753
00754 InstructionSignature sig = INSTCLASS2::signature(type); 00755 switch (type) { 00756 #define Fennel_InstructionRegisterSwitch_NativeNotBool 1 00757 #include "fennel/calculator/InstructionRegisterSwitch.h" 00758 default: 00759 throw std::logic_error("Default InstructionRegister"); 00760 } 00761 } 00762 } 00763 00764 public: 00765 static void 00766 registerInstructions() { 00767 vector t; 00768 t = InstructionSignature::typeVector 00769 (StandardTypeDescriptor::isNativeNotBool); 00770 00771
00772
00773
00774
00775
00776 registerTypesfennel::NativeAdd(t); 00777 registerTypesfennel::NativeSub(t); 00778 registerTypesfennel::NativeMul(t); 00779 registerTypesfennel::NativeDiv(t); 00780 registerTypesfennel::NativeNeg(t); 00781 registerTypesfennel::NativeRound(t); 00782 registerTypesfennel::NativeMove(t); 00783 registerTypesfennel::NativeRef(t); 00784 registerTypesfennel::NativeToNull(t); 00785 } 00786 }; 00787 00788 00789 FENNEL_END_NAMESPACE 00790 00791 #endif 00792 00793