NativeNativeInstruction.h

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/calculator/NativeNativeInstruction.h#5 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-2009 The Eigenbase Project
00005 // Copyright (C) 2004-2009 SQLstream, Inc.
00006 // Copyright (C) 2009-2009 LucidEra, Inc.
00007 //
00008 // This program is free software; you can redistribute it and/or modify it
00009 // under the terms of the GNU General Public License as published by the Free
00010 // Software Foundation; either version 2 of the License, or (at your option)
00011 // any later version approved by The Eigenbase Project.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 //
00022 // NativeNativeInstruction
00023 //
00024 // Instruction->NativeInstruction->NativeNativeInstruction
00025 //
00026 // NativeInstructions that return a Native
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<typename TMPLT>
00038 class NativeNativeInstruction : public NativeInstruction<TMPLT>
00039 {
00040 public:
00041     explicit
00042     NativeNativeInstruction(
00043         RegisterRef<TMPLT>* result,
00044         StandardTypeDescriptorOrdinal nativeType)
00045         : NativeInstruction<TMPLT>(nativeType),
00046           mResult(result)
00047     {}
00048 
00049     explicit
00050     NativeNativeInstruction(
00051         RegisterRef<TMPLT>* result,
00052         RegisterRef<TMPLT>* op1,
00053         StandardTypeDescriptorOrdinal nativeType)
00054         : NativeInstruction<TMPLT>(op1, nativeType),
00055           mResult(result)
00056     {}
00057 
00058     explicit
00059     NativeNativeInstruction(
00060         RegisterRef<TMPLT>* result,
00061         RegisterRef<TMPLT>* op1,
00062         RegisterRef<TMPLT>* op2,
00063         StandardTypeDescriptorOrdinal nativeType)
00064         : NativeInstruction<TMPLT>(op1, op2, nativeType),
00065           mResult(result)
00066     {}
00067 
00068     virtual
00069     ~NativeNativeInstruction() {}
00070 
00071 protected:
00072     RegisterRef<TMPLT>* mResult;
00073     static void fnSetRegisterToNull(const char *, void *pOpaque) {
00074         RegisterRef<TMPLT> *pReg = (RegisterRef<TMPLT> *)pOpaque;
00075         if (pReg->isNullable()) {
00076             pReg->toNull();
00077         }
00078     }
00079 };
00080 
00081 template <typename TMPLT>
00082 class NativeAdd : public NativeNativeInstruction<TMPLT>
00083 {
00084 public:
00085     explicit
00086     NativeAdd(
00087         RegisterRef<TMPLT>* result,
00088         RegisterRef<TMPLT>* op1,
00089         RegisterRef<TMPLT>* op2,
00090         StandardTypeDescriptorOrdinal nativeType)
00091         : NativeNativeInstruction<TMPLT>(result, op1, op2, nativeType)
00092     {}
00093 
00094     virtual
00095     ~NativeAdd() {}
00096 
00097     virtual void exec(TProgramCounter& pc) const {
00098         pc++;
00099         if (NativeInstruction<TMPLT>::mOp1->isNull() ||
00100             NativeInstruction<TMPLT>::mOp2->isNull()) {
00101             // SQL99 Part 2 Section 6.26 General Rule 1
00102             NativeNativeInstruction<TMPLT>::mResult->toNull();
00103         } else {
00104             TExceptionCBData tE(
00105                 NativeNativeInstruction<TMPLT>::fnSetRegisterToNull,
00106                 NativeNativeInstruction<TMPLT>::mResult);
00107             NativeNativeInstruction<TMPLT>::mResult->value(
00108                 Noisy<TMPLT>::add(
00109                     pc - 1,
00110                     NativeInstruction<TMPLT>::mOp1->value(),
00111                     NativeInstruction<TMPLT>::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<TMPLT>::mResult,
00134             NativeInstruction<TMPLT>::mOp1,
00135             NativeInstruction<TMPLT>::mOp2);
00136     }
00137 
00138     static InstructionSignature
00139     signature(StandardTypeDescriptorOrdinal type) {
00140         vector<StandardTypeDescriptorOrdinal> 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<TMPLT>*> (sig[0]),
00150             static_cast<RegisterRef<TMPLT>*> (sig[1]),
00151             static_cast<RegisterRef<TMPLT>*> (sig[2]),
00152             (sig[0])->type());
00153     }
00154 };
00155 
00156 template <typename TMPLT>
00157 class NativeSub : public NativeNativeInstruction<TMPLT>
00158 {
00159 public:
00160     explicit
00161     NativeSub(
00162         RegisterRef<TMPLT>* result,
00163         RegisterRef<TMPLT>* op1,
00164         RegisterRef<TMPLT>* op2,
00165         StandardTypeDescriptorOrdinal nativeType)
00166         : NativeNativeInstruction<TMPLT>(result, op1, op2, nativeType)
00167     {}
00168     virtual
00169     ~NativeSub() {}
00170 
00171     virtual void exec(TProgramCounter& pc) const {
00172         pc++;
00173         if (NativeInstruction<TMPLT>::mOp1->isNull() ||
00174             NativeInstruction<TMPLT>::mOp2->isNull()) {
00175             // SQL99 Part 2 Section 6.26 General Rule 1
00176             NativeNativeInstruction<TMPLT>::mResult->toNull();
00177         } else {
00178             TExceptionCBData tE(
00179                 NativeNativeInstruction<TMPLT>::fnSetRegisterToNull,
00180                 NativeNativeInstruction<TMPLT>::mResult);
00181             NativeNativeInstruction<TMPLT>::mResult->value(
00182                 Noisy<TMPLT>::sub(
00183                     pc - 1,
00184                     NativeInstruction<TMPLT>::mOp1->value(),
00185                     NativeInstruction<TMPLT>::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<TMPLT>::mResult,
00208             NativeInstruction<TMPLT>::mOp1,
00209             NativeInstruction<TMPLT>::mOp2);
00210     }
00211 
00212     static InstructionSignature
00213     signature(StandardTypeDescriptorOrdinal type) {
00214         vector<StandardTypeDescriptorOrdinal> 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<TMPLT>*> (sig[0]),
00224             static_cast<RegisterRef<TMPLT>*> (sig[1]),
00225             static_cast<RegisterRef<TMPLT>*> (sig[2]),
00226             (sig[0])->type());
00227     }
00228 };
00229 
00230 template <typename TMPLT>
00231 class NativeMul : public NativeNativeInstruction<TMPLT>
00232 {
00233 public:
00234     explicit
00235     NativeMul(
00236         RegisterRef<TMPLT>* result,
00237         RegisterRef<TMPLT>* op1,
00238         RegisterRef<TMPLT>* op2,
00239         StandardTypeDescriptorOrdinal nativeType)
00240         : NativeNativeInstruction<TMPLT>(result, op1, op2, nativeType)
00241     {}
00242 
00243     virtual
00244     ~NativeMul() {}
00245 
00246     virtual void exec(TProgramCounter& pc) const {
00247         pc++;
00248         if (NativeInstruction<TMPLT>::mOp1->isNull() ||
00249             NativeInstruction<TMPLT>::mOp2->isNull()) {
00250             // SQL99 Part 2 Section 6.26 General Rule 1
00251             NativeNativeInstruction<TMPLT>::mResult->toNull();
00252         } else {
00253             TExceptionCBData tE(
00254                 NativeNativeInstruction<TMPLT>::fnSetRegisterToNull,
00255                 NativeNativeInstruction<TMPLT>::mResult);
00256             NativeNativeInstruction<TMPLT>::mResult->value(
00257                 Noisy<TMPLT>::mul(
00258                     pc - 1,
00259                     NativeInstruction<TMPLT>::mOp1->value(),
00260                     NativeInstruction<TMPLT>::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<TMPLT>::mResult,
00283             NativeInstruction<TMPLT>::mOp1,
00284             NativeInstruction<TMPLT>::mOp2);
00285     }
00286 
00287     static InstructionSignature
00288     signature(StandardTypeDescriptorOrdinal type) {
00289         vector<StandardTypeDescriptorOrdinal> 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<TMPLT>*> (sig[0]),
00299             static_cast<RegisterRef<TMPLT>*> (sig[1]),
00300             static_cast<RegisterRef<TMPLT>*> (sig[2]),
00301             (sig[0])->type());
00302     }
00303 };
00304 
00305 template <typename TMPLT>
00306 class NativeDiv : public NativeNativeInstruction<TMPLT>
00307 {
00308 public:
00309     explicit
00310     NativeDiv(
00311         RegisterRef<TMPLT>* result,
00312         RegisterRef<TMPLT>* op1,
00313         RegisterRef<TMPLT>* op2,
00314         StandardTypeDescriptorOrdinal nativeType)
00315         : NativeNativeInstruction<TMPLT>(result, op1, op2, nativeType)
00316     {}
00317 
00318     virtual
00319     ~NativeDiv() {}
00320 
00321     virtual void exec(TProgramCounter& pc) const {
00322         pc++;
00323         if (NativeInstruction<TMPLT>::mOp1->isNull() ||
00324             NativeInstruction<TMPLT>::mOp2->isNull()) {
00325             // SQL99 Part 2 Section 6.26 General Rule 1
00326             NativeNativeInstruction<TMPLT>::mResult->toNull();
00327         } else {
00328 #if 0
00329             // JR 6/07, now thrown in NoisyArithmetic ...
00330             // encourage into register
00331             TMPLT o2 = NativeInstruction<TMPLT>::mOp2->value();
00332             if (o2 == 0) {
00333                 // SQL99 Part 2 Section 6.26 General Rule 4
00334                 NativeNativeInstruction<TMPLT>::mResult->toNull();
00335                 // SQL99 Part 2 Section 22.1 SQLState dataexception class 22,
00336                 // division by zero subclass 012
00337                 throw CalcMessage("22012", pc - 1);
00338             }
00339 #endif
00340             TExceptionCBData tE(
00341                 NativeNativeInstruction<TMPLT>::fnSetRegisterToNull,
00342                 NativeNativeInstruction<TMPLT>::mResult);
00343             NativeNativeInstruction<TMPLT>::mResult->value(
00344                 Noisy<TMPLT>::div(
00345                     pc - 1,
00346                     NativeInstruction<TMPLT>::mOp1->value(),
00347                     NativeInstruction<TMPLT>::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<TMPLT>::mResult,
00370             NativeInstruction<TMPLT>::mOp1,
00371             NativeInstruction<TMPLT>::mOp2);
00372     }
00373 
00374     static InstructionSignature
00375     signature(StandardTypeDescriptorOrdinal type) {
00376         vector<StandardTypeDescriptorOrdinal> 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<TMPLT>*> (sig[0]),
00386             static_cast<RegisterRef<TMPLT>*> (sig[1]),
00387             static_cast<RegisterRef<TMPLT>*> (sig[2]),
00388             (sig[0])->type());
00389     }
00390 };
00391 
00392 // NativeNeg implements monadic arithmetic operator '-' (unary minus)
00393 // See SQL99 Part 2 Section 6.26 General Rule 3.
00394 template <typename TMPLT>
00395 class NativeNeg : public NativeNativeInstruction<TMPLT>
00396 {
00397 public:
00398     explicit
00399     NativeNeg(
00400         RegisterRef<TMPLT>* result,
00401         RegisterRef<TMPLT>* op1,
00402         StandardTypeDescriptorOrdinal nativeType)
00403         : NativeNativeInstruction<TMPLT>(result, op1, nativeType)
00404     {}
00405     virtual
00406     ~NativeNeg() {}
00407 
00408     virtual void exec(TProgramCounter& pc) const {
00409         pc++;
00410         if (NativeInstruction<TMPLT>::mOp1->isNull()) {
00411             // SQL99 Part 2 Section 6.26 General Rule 1
00412             NativeNativeInstruction<TMPLT>::mResult->toNull();
00413         } else {
00414             TExceptionCBData tE(
00415                 NativeNativeInstruction<TMPLT>::fnSetRegisterToNull,
00416                 NativeNativeInstruction<TMPLT>::mResult);
00417             NativeNativeInstruction<TMPLT>::mResult->
00418                value(
00419                    Noisy<TMPLT>::neg(
00420                        pc - 1,
00421                        NativeInstruction<TMPLT>::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<TMPLT>::mResult,
00444             NativeInstruction<TMPLT>::mOp1,
00445             NativeInstruction<TMPLT>::mOp2);
00446     }
00447 
00448     static InstructionSignature
00449     signature(StandardTypeDescriptorOrdinal type) {
00450         vector<StandardTypeDescriptorOrdinal> 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<TMPLT>*> (sig[0]),
00460             static_cast<RegisterRef<TMPLT>*> (sig[1]),
00461             (sig[0])->type());
00462     }
00463 };
00464 
00465 template <class TMPLT>
00466 class NativeRoundHelp {
00467 public:
00468     static void r(TMPLT& result, TMPLT op1) {
00469         // no-op
00470         result = op1;
00471     }
00472 };
00473 
00474 template<>
00475 class NativeRoundHelp<double> {
00476 public:
00477     static void r(double& result, double op1) {
00478         // implements round away from zero
00479         result = round(op1);
00480     }
00481 };
00482 
00483 template<>
00484 class NativeRoundHelp<float> {
00485 public:
00486     static void r(float& result, float op1) {
00487         // implements round away from zero
00488         result = roundf(op1);
00489     }
00490 };
00491 
00492 // See SQL99 Part 2 Section 4.5 Numbers, paragraph 4, for a discussion on
00493 // rounding away from zero.
00494 // NativeRound does a round "away from zero" (e.g. -0.5 -> -1.0)
00495 template <typename TMPLT>
00496 class NativeRound : public NativeNativeInstruction<TMPLT>
00497 {
00498 public:
00499     explicit
00500     NativeRound(
00501         RegisterRef<TMPLT>* result,
00502         RegisterRef<TMPLT>* op1,
00503         StandardTypeDescriptorOrdinal nativeType)
00504         : NativeNativeInstruction<TMPLT>(result, op1, nativeType)
00505     {}
00506     virtual
00507     ~NativeRound() {}
00508 
00509     virtual void exec(TProgramCounter& pc) const {
00510         pc++;
00511         if (NativeInstruction<TMPLT>::mOp1->isNull()) {
00512             NativeNativeInstruction<TMPLT>::mResult->toNull();
00513         } else {
00514             // TODO: have not implemented exceptions for this operation
00515             TMPLT tmp;
00516             NativeRoundHelp<TMPLT>::r
00517                  (tmp, NativeInstruction<TMPLT>::mOp1->value());
00518             NativeNativeInstruction<TMPLT>::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<TMPLT>::mResult,
00541             NativeInstruction<TMPLT>::mOp1,
00542             NativeInstruction<TMPLT>::mOp2);
00543     }
00544 
00545     static InstructionSignature
00546     signature(StandardTypeDescriptorOrdinal type) {
00547         vector<StandardTypeDescriptorOrdinal> 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<TMPLT>*> (sig[0]),
00557             static_cast<RegisterRef<TMPLT>*> (sig[1]),
00558             (sig[0])->type());
00559     }
00560 };
00561 
00562 template <typename TMPLT>
00563 class NativeMove : public NativeNativeInstruction<TMPLT>
00564 {
00565 public:
00566     explicit
00567     NativeMove(
00568         RegisterRef<TMPLT>* result,
00569         RegisterRef<TMPLT>* op1,
00570         StandardTypeDescriptorOrdinal nativeType)
00571         : NativeNativeInstruction<TMPLT>(result, op1, nativeType)
00572     {}
00573     virtual
00574     ~NativeMove() {}
00575 
00576     virtual void exec(TProgramCounter& pc) const {
00577         pc++;
00578         if (NativeInstruction<TMPLT>::mOp1->isNull()) {
00579             NativeNativeInstruction<TMPLT>::mResult->toNull();
00580         } else {
00581             NativeNativeInstruction<TMPLT>::mResult->value
00582                (NativeInstruction<TMPLT>::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<TMPLT>::mResult,
00604             NativeInstruction<TMPLT>::mOp1,
00605             NativeInstruction<TMPLT>::mOp2);
00606     }
00607 
00608     static InstructionSignature
00609     signature(StandardTypeDescriptorOrdinal type) {
00610         vector<StandardTypeDescriptorOrdinal> 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<TMPLT>*> (sig[0]),
00620             static_cast<RegisterRef<TMPLT>*> (sig[1]),
00621             (sig[0])->type());
00622     }
00623 };
00624 
00625 template <typename TMPLT>
00626 class NativeRef : public NativeNativeInstruction<TMPLT>
00627 {
00628 public:
00629     explicit
00630     NativeRef(
00631         RegisterRef<TMPLT>* result,
00632         RegisterRef<TMPLT>* op1,
00633         StandardTypeDescriptorOrdinal nativeType)
00634         : NativeNativeInstruction<TMPLT>(result, op1, nativeType)
00635     {}
00636     virtual
00637     ~NativeRef() {}
00638 
00639     virtual void exec(TProgramCounter& pc) const {
00640         pc++;
00641         NativeNativeInstruction<TMPLT>::mResult->
00642             refer(NativeInstruction<TMPLT>::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<TMPLT>::mResult,
00664             NativeInstruction<TMPLT>::mOp1,
00665             NativeInstruction<TMPLT>::mOp2);
00666     }
00667 
00668     static InstructionSignature
00669     signature(StandardTypeDescriptorOrdinal type) {
00670         vector<StandardTypeDescriptorOrdinal> 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<TMPLT>*> (sig[0]),
00680             static_cast<RegisterRef<TMPLT>*> (sig[1]),
00681             (sig[0])->type());
00682     }
00683 };
00684 
00685 template <typename TMPLT>
00686 class NativeToNull : public NativeNativeInstruction<TMPLT>
00687 {
00688 public:
00689     explicit
00690     NativeToNull(
00691         RegisterRef<TMPLT>* result,
00692         StandardTypeDescriptorOrdinal nativeType)
00693         : NativeNativeInstruction<TMPLT>(result, nativeType)
00694     {}
00695 
00696     virtual
00697     ~NativeToNull() {}
00698 
00699     virtual void exec(TProgramCounter& pc) const {
00700         pc++;
00701         NativeNativeInstruction<TMPLT>::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<TMPLT>::mResult,
00723             NativeInstruction<TMPLT>::mOp1,
00724             NativeInstruction<TMPLT>::mOp2);
00725     }
00726 
00727     static InstructionSignature
00728     signature(StandardTypeDescriptorOrdinal type) {
00729         vector<StandardTypeDescriptorOrdinal> 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<TMPLT>*> (sig[0]),
00739             (sig[0])->type());
00740     }
00741 };
00742 
00743 class FENNEL_CALCULATOR_EXPORT NativeNativeInstructionRegister
00744     : InstructionRegister
00745 {
00746     // TODO: Refactor registerTypes to class InstructionRegister
00747     template < template <typename> class INSTCLASS2 >
00748     static void
00749     registerTypes(vector<StandardTypeDescriptorOrdinal> const & t) {
00750 
00751         for (uint i = 0; i < t.size(); i++) {
00752             StandardTypeDescriptorOrdinal type = t[i];
00753             // Type <char> below is a placeholder and is ignored.
00754             InstructionSignature sig = INSTCLASS2<char>::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<StandardTypeDescriptorOrdinal> t;
00768         t = InstructionSignature::typeVector
00769             (StandardTypeDescriptor::isNativeNotBool);
00770 
00771         // Have to do full fennel:: qualification of template
00772         // arguments below to prevent template argument 'TMPLT', of
00773         // this encapsulating class, from perverting NativeAdd into
00774         // NativeAdd<TMPLT> or something like
00775         // that. Anyway. Fennel::NativeAdd works just fine.
00776         registerTypes<fennel::NativeAdd>(t);
00777         registerTypes<fennel::NativeSub>(t);
00778         registerTypes<fennel::NativeMul>(t);
00779         registerTypes<fennel::NativeDiv>(t);
00780         registerTypes<fennel::NativeNeg>(t);
00781         registerTypes<fennel::NativeRound>(t);
00782         registerTypes<fennel::NativeMove>(t);
00783         registerTypes<fennel::NativeRef>(t);
00784         registerTypes<fennel::NativeToNull>(t);
00785     }
00786 };
00787 
00788 
00789 FENNEL_END_NAMESPACE
00790 
00791 #endif
00792 
00793 // End NativeNativeInstruction.h

Generated on Mon Jun 22 04:00:17 2009 for Fennel by  doxygen 1.5.1