IntegralNativeInstruction.h

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/calculator/IntegralNativeInstruction.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 #ifndef Fennel_IntegralNativeInstruction_Included
00023 #define Fennel_IntegralNativeInstruction_Included
00024 
00025 #include "fennel/calculator/NativeInstruction.h"
00026 
00027 FENNEL_BEGIN_NAMESPACE
00028 
00036 //
00037 // IntegralNativeInstruction_NotAnIntegralType
00038 //
00039 // Force the use of a (non-pointer) native integral type.
00040 // Note: You cannot use typedefs like int32_t here or the
00041 // built-in names thereof won't work. By using the built-in
00042 // type name, you can support the built-in and typedefs
00043 // built on top.
00044 //
00045 template <class T> class IntegralNativeInstruction_NotAnIntegralType;
00046 template <> class IntegralNativeInstruction_NotAnIntegralType<char> {};
00047 template <> class IntegralNativeInstruction_NotAnIntegralType<short> {};
00048 template <> class IntegralNativeInstruction_NotAnIntegralType<int> {};
00049 template <> class IntegralNativeInstruction_NotAnIntegralType<long> {};
00050 template <> class IntegralNativeInstruction_NotAnIntegralType<long long> {};
00051 template <> class IntegralNativeInstruction_NotAnIntegralType<unsigned char> {};
00052 template <> class IntegralNativeInstruction_NotAnIntegralType<
00053     unsigned short> {};
00054 template <> class IntegralNativeInstruction_NotAnIntegralType<unsigned int> {};
00055 template <> class IntegralNativeInstruction_NotAnIntegralType<unsigned long> {};
00056 template <> class IntegralNativeInstruction_NotAnIntegralType<
00057     unsigned long long> {};
00058 template <> class IntegralNativeInstruction_NotAnIntegralType<signed char> {};
00059 
00060 template<typename TMPLT>
00061 class IntegralNativeInstruction : public NativeInstruction<TMPLT>
00062 {
00063 public:
00064     explicit
00065     IntegralNativeInstruction(
00066         RegisterRef<TMPLT>* result,
00067         RegisterRef<TMPLT>* op1,
00068         StandardTypeDescriptorOrdinal nativeType)
00069         : NativeInstruction<TMPLT>(op1, nativeType),
00070           mResult(result)
00071     {
00072         assert(StandardTypeDescriptor::isIntegralNative(nativeType));
00073     }
00074 
00075     explicit
00076     IntegralNativeInstruction(
00077         RegisterRef<TMPLT>* result,
00078         RegisterRef<TMPLT>* op1,
00079         RegisterRef<TMPLT>* op2,
00080         StandardTypeDescriptorOrdinal nativeType)
00081         : NativeInstruction<TMPLT>(op1, op2, nativeType),
00082           mResult(result)
00083     {
00084         assert(StandardTypeDescriptor::isIntegralNative(nativeType));
00085     }
00086 
00087     ~IntegralNativeInstruction()
00088     {
00089         // If (0) to reduce performance impact of template type checking
00090         if (0) {
00091             IntegralNativeInstruction_NotAnIntegralType<TMPLT>();
00092         }
00093     }
00094 
00095 protected:
00096     RegisterRef<TMPLT>* mResult;
00097 };
00098 
00099 template <typename TMPLT>
00100 class IntegralNativeMod : public IntegralNativeInstruction<TMPLT>
00101 {
00102 public:
00103     explicit
00104     IntegralNativeMod(
00105         RegisterRef<TMPLT>* result,
00106         RegisterRef<TMPLT>* op1,
00107         RegisterRef<TMPLT>* op2,
00108         StandardTypeDescriptorOrdinal nativeType)
00109         : IntegralNativeInstruction<TMPLT>(result, op1, op2, nativeType)
00110     {}
00111 
00112     virtual
00113     ~IntegralNativeMod() {}
00114 
00115     virtual void exec(TProgramCounter& pc) const {
00116         pc++;
00117         // SQL99 Part 2 Section 6.17 General Rule 10
00118         if (NativeInstruction<TMPLT>::mOp1->isNull() ||
00119             NativeInstruction<TMPLT>::mOp2->isNull()) {
00120             IntegralNativeInstruction<TMPLT>::mResult->toNull();
00121         } else {
00122             // encourage into register
00123             TMPLT o2 = NativeInstruction<TMPLT>::mOp2->value();
00124             if (o2 == 0) {
00125                 IntegralNativeInstruction<TMPLT>::mResult->toNull();
00126                 // SQL99 22.1 SQLState dataexception class 22,
00127                 // division by zero subclass 012
00128                 throw CalcMessage("22012", pc - 1);
00129             }
00130             IntegralNativeInstruction<TMPLT>::mResult->value(
00131                 NativeInstruction<TMPLT>::mOp1->value() % o2);
00132         }
00133     }
00134 
00135     static const char * longName()
00136     {
00137         return "IntegralNativeMod";
00138     }
00139 
00140     static const char * shortName()
00141     {
00142         return "MOD";
00143     }
00144 
00145     static int numArgs()
00146     {
00147         return 3;
00148     }
00149 
00150     void describe(string& out, bool values) const {
00151         describeHelper(
00152             out, values, longName(), shortName(),
00153             IntegralNativeInstruction<TMPLT>::mResult,
00154             NativeInstruction<TMPLT>::mOp1,
00155             NativeInstruction<TMPLT>::mOp2);
00156     }
00157 
00158     static InstructionSignature
00159     signature(StandardTypeDescriptorOrdinal type) {
00160         vector<StandardTypeDescriptorOrdinal> v(numArgs(), type);
00161         return InstructionSignature(shortName(), v);
00162     }
00163 
00164     static Instruction*
00165     create(InstructionSignature const & sig)
00166     {
00167         assert(sig.size() == numArgs());
00168         return new IntegralNativeMod(
00169             static_cast<RegisterRef<TMPLT>*> (sig[0]),
00170             static_cast<RegisterRef<TMPLT>*> (sig[1]),
00171             static_cast<RegisterRef<TMPLT>*> (sig[2]),
00172             (sig[0])->type());
00173     }
00174 };
00175 
00176 template <typename TMPLT>
00177 class IntegralNativeAnd : public IntegralNativeInstruction<TMPLT>
00178 {
00179 public:
00180     explicit
00181     IntegralNativeAnd(
00182         RegisterRef<TMPLT>* result,
00183         RegisterRef<TMPLT>* op1,
00184         RegisterRef<TMPLT>* op2,
00185         StandardTypeDescriptorOrdinal nativeType)
00186         : IntegralNativeInstruction<TMPLT>(result, op1, op2, nativeType)
00187     {}
00188 
00189     virtual
00190     ~IntegralNativeAnd() {}
00191 
00192     virtual void exec(TProgramCounter& pc) const {
00193         // making up null semantics here
00194         if (NativeInstruction<TMPLT>::mOp1->isNull() ||
00195             NativeInstruction<TMPLT>::mOp2->isNull()) {
00196             IntegralNativeInstruction<TMPLT>::mResult->toNull();
00197         } else {
00198             IntegralNativeInstruction<TMPLT>::mResult->value(
00199                 NativeInstruction<TMPLT>::mOp1->value() &
00200                 NativeInstruction<TMPLT>::mOp2->value());
00201         }
00202         pc++;
00203     }
00204 
00205     static const char * longName()
00206     {
00207         return "IntegralNativeAnd";
00208     }
00209 
00210     static const char * shortName()
00211     {
00212         return "AND";
00213     }
00214 
00215     static int numArgs()
00216     {
00217         return 3;
00218     }
00219 
00220     void describe(string& out, bool values) const {
00221         describeHelper(
00222             out, values, longName(), shortName(),
00223             IntegralNativeInstruction<TMPLT>::mResult,
00224             NativeInstruction<TMPLT>::mOp1,
00225             NativeInstruction<TMPLT>::mOp2);
00226     }
00227 
00228     static InstructionSignature
00229     signature(StandardTypeDescriptorOrdinal type) {
00230         vector<StandardTypeDescriptorOrdinal> v(numArgs(), type);
00231         return InstructionSignature(shortName(), v);
00232     }
00233 
00234     static Instruction*
00235     create(InstructionSignature const & sig)
00236     {
00237         assert(sig.size() == numArgs());
00238         return new IntegralNativeAnd(
00239             static_cast<RegisterRef<TMPLT>*> (sig[0]),
00240             static_cast<RegisterRef<TMPLT>*> (sig[1]),
00241             static_cast<RegisterRef<TMPLT>*> (sig[2]),
00242             (sig[0])->type());
00243     }
00244 };
00245 
00246 template <typename TMPLT>
00247 class IntegralNativeOr : public IntegralNativeInstruction<TMPLT>
00248 {
00249 public:
00250     explicit
00251     IntegralNativeOr(
00252         RegisterRef<TMPLT>* result,
00253         RegisterRef<TMPLT>* op1,
00254         RegisterRef<TMPLT>* op2,
00255         StandardTypeDescriptorOrdinal nativeType)
00256         : IntegralNativeInstruction<TMPLT>(result, op1, op2, nativeType)
00257     {}
00258     virtual
00259     ~IntegralNativeOr() {}
00260 
00261     virtual void exec(TProgramCounter& pc) const {
00262         pc++;
00263         // making up null semantics here
00264         if (NativeInstruction<TMPLT>::mOp1->isNull() ||
00265             NativeInstruction<TMPLT>::mOp2->isNull()) {
00266             IntegralNativeInstruction<TMPLT>::mResult->toNull();
00267         } else {
00268             IntegralNativeInstruction<TMPLT>::mResult->value(
00269                 NativeInstruction<TMPLT>::mOp1->value() |
00270                 NativeInstruction<TMPLT>::mOp2->value());
00271         }
00272     }
00273 
00274     static const char * longName()
00275     {
00276         return "IntegralNativeOr";
00277     }
00278 
00279     static const char * shortName()
00280     {
00281         return "OR";
00282     }
00283 
00284     static int numArgs()
00285     {
00286         return 3;
00287     }
00288 
00289     void describe(string& out, bool values) const {
00290         describeHelper(
00291             out, values, longName(), shortName(),
00292             IntegralNativeInstruction<TMPLT>::mResult,
00293             NativeInstruction<TMPLT>::mOp1,
00294             NativeInstruction<TMPLT>::mOp2);
00295     }
00296 
00297     static InstructionSignature
00298     signature(StandardTypeDescriptorOrdinal type) {
00299         vector<StandardTypeDescriptorOrdinal> v(numArgs(), type);
00300         return InstructionSignature(shortName(), v);
00301     }
00302 
00303     static Instruction*
00304     create(InstructionSignature const & sig)
00305     {
00306         assert(sig.size() == numArgs());
00307         return new IntegralNativeOr(
00308             static_cast<RegisterRef<TMPLT>*> (sig[0]),
00309             static_cast<RegisterRef<TMPLT>*> (sig[1]),
00310             static_cast<RegisterRef<TMPLT>*> (sig[2]),
00311             (sig[0])->type());
00312     }
00313 };
00314 
00315 template <typename TMPLT>
00316 class IntegralNativeShiftLeft : public IntegralNativeInstruction<TMPLT>
00317 {
00318 public:
00319     explicit
00320     IntegralNativeShiftLeft(
00321         RegisterRef<TMPLT>* result,
00322         RegisterRef<TMPLT>* op1,
00323         RegisterRef<TMPLT>* op2,
00324         StandardTypeDescriptorOrdinal nativeType)
00325         : IntegralNativeInstruction<TMPLT>(result, op1, op2, nativeType)
00326     {}
00327     virtual
00328     ~IntegralNativeShiftLeft() {}
00329 
00330     virtual void exec(TProgramCounter& pc) const {
00331         pc++;
00332         // making up null semantics here
00333         if (NativeInstruction<TMPLT>::mOp1->isNull() ||
00334             NativeInstruction<TMPLT>::mOp2->isNull()) {
00335             IntegralNativeInstruction<TMPLT>::mResult->toNull();
00336         } else {
00337             IntegralNativeInstruction<TMPLT>::mResult->value(
00338                 NativeInstruction<TMPLT>::mOp1->value() <<
00339                 NativeInstruction<TMPLT>::mOp2->value());
00340         }
00341     }
00342 
00343     static const char * longName()
00344     {
00345         return "IntegralNativeShiftLeft";
00346     }
00347 
00348     static const char * shortName()
00349     {
00350         return "SHFL";
00351     }
00352 
00353     static int numArgs()
00354     {
00355         return 3;
00356     }
00357 
00358     void describe(string& out, bool values) const {
00359         describeHelper(
00360             out, values, longName(), shortName(),
00361             IntegralNativeInstruction<TMPLT>::mResult,
00362             NativeInstruction<TMPLT>::mOp1,
00363             NativeInstruction<TMPLT>::mOp2);
00364     }
00365 
00366     static InstructionSignature
00367     signature(StandardTypeDescriptorOrdinal type) {
00368         vector<StandardTypeDescriptorOrdinal> v(numArgs(), type);
00369         return InstructionSignature(shortName(), v);
00370     }
00371 
00372     static Instruction*
00373     create(InstructionSignature const & sig)
00374     {
00375         assert(sig.size() == numArgs());
00376         return new
00377             IntegralNativeShiftLeft(
00378                 static_cast<RegisterRef<TMPLT>*> (sig[0]),
00379                 static_cast<RegisterRef<TMPLT>*> (sig[1]),
00380                 static_cast<RegisterRef<TMPLT>*> (sig[2]),
00381                 (sig[0])->type());
00382     }
00383 };
00384 
00385 template <typename TMPLT>
00386 class IntegralNativeShiftRight : public IntegralNativeInstruction<TMPLT>
00387 {
00388 public:
00389     explicit
00390     IntegralNativeShiftRight(
00391         RegisterRef<TMPLT>* result,
00392         RegisterRef<TMPLT>* op1,
00393         RegisterRef<TMPLT>* op2,
00394         StandardTypeDescriptorOrdinal nativeType)
00395         : IntegralNativeInstruction<TMPLT>(result, op1, op2, nativeType)
00396     {}
00397     virtual
00398     ~IntegralNativeShiftRight() {}
00399 
00400     virtual void exec(TProgramCounter& pc) const {
00401         pc++;
00402         // making up null semantics here
00403         if (NativeInstruction<TMPLT>::mOp1->isNull() ||
00404             NativeInstruction<TMPLT>::mOp2->isNull()) {
00405             IntegralNativeInstruction<TMPLT>::mResult->toNull();
00406         } else {
00407             IntegralNativeInstruction<TMPLT>::mResult->value(
00408                 NativeInstruction<TMPLT>::mOp1->value() >>
00409                 NativeInstruction<TMPLT>::mOp2->value());
00410         }
00411     }
00412 
00413     static const char * longName()
00414     {
00415         return "IntegralNativeShiftRight";
00416     }
00417 
00418     static const char * shortName()
00419     {
00420         return "SHFR";
00421     }
00422 
00423     static int numArgs()
00424     {
00425         return 3;
00426     }
00427 
00428     void describe(string& out, bool values) const {
00429         describeHelper(
00430             out, values, longName(), shortName(),
00431             IntegralNativeInstruction<TMPLT>::mResult,
00432             NativeInstruction<TMPLT>::mOp1,
00433             NativeInstruction<TMPLT>::mOp2);
00434     }
00435 
00436     static InstructionSignature
00437     signature(StandardTypeDescriptorOrdinal type) {
00438         vector<StandardTypeDescriptorOrdinal> v(numArgs(), type);
00439         return InstructionSignature(shortName(), v);
00440     }
00441 
00442     static Instruction*
00443     create(InstructionSignature const & sig)
00444     {
00445         assert(sig.size() == numArgs());
00446         return new
00447             IntegralNativeShiftRight(
00448                 static_cast<RegisterRef<TMPLT>*> (sig[0]),
00449                 static_cast<RegisterRef<TMPLT>*> (sig[1]),
00450                 static_cast<RegisterRef<TMPLT>*> (sig[2]),
00451                 (sig[0])->type());
00452     }
00453 };
00454 
00455 class FENNEL_CALCULATOR_EXPORT IntegralNativeInstructionRegister
00456     : InstructionRegister
00457 {
00458     // TODO: Refactor registerTypes to class InstructionRegister
00459     template < template <typename> class INSTCLASS2 >
00460     static void
00461     registerTypes(vector<StandardTypeDescriptorOrdinal> const &t) {
00462 
00463         for (uint i = 0; i < t.size(); i++) {
00464             StandardTypeDescriptorOrdinal type = t[i];
00465             // Type <char> below is a placeholder and is ignored.
00466             InstructionSignature sig = INSTCLASS2<char>::signature(type);
00467             switch (type) {
00468 #define Fennel_InstructionRegisterSwitch_Integral 1
00469 #include "fennel/calculator/InstructionRegisterSwitch.h"
00470             default:
00471                 throw std::logic_error("Default InstructionRegister");
00472             }
00473         }
00474     }
00475 
00476 public:
00477     static void
00478     registerInstructions()
00479     {
00480         vector<StandardTypeDescriptorOrdinal> t;
00481         t = InstructionSignature::typeVector(StandardTypeDescriptor::isExact);
00482 
00483         // Have to do full fennel:: qualification of template
00484         // arguments below to prevent template argument 'TMPLT', of
00485         // this encapsulating class, from perverting NativeAdd into
00486         // NativeAdd<TMPLT> or something like
00487         // that. Anyway. Fennel::NativeAdd works just fine.
00488         registerTypes<fennel::IntegralNativeMod>(t);
00489         registerTypes<fennel::IntegralNativeAnd>(t);
00490         registerTypes<fennel::IntegralNativeOr>(t);
00491         registerTypes<fennel::IntegralNativeShiftLeft>(t);
00492         registerTypes<fennel::IntegralNativeShiftRight>(t);
00493     }
00494 };
00495 
00496 
00497 FENNEL_END_NAMESPACE
00498 
00499 #endif
00500 
00501 // End IntegralNativeInstruction.h
00502 

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