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