PointerPointerInstruction.h

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/calculator/PointerPointerInstruction.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 // PointerPointerInstruction
00023 //
00024 // Instruction->PointerInstruction->PointerPointerInstruction
00025 //
00026 // PointerInstructions that return a Pointer
00027 */
00028 #ifndef Fennel_PointerPointerInstruction_Included
00029 #define Fennel_PointerPointerInstruction_Included
00030 
00031 #include "fennel/calculator/PointerInstruction.h"
00032 
00033 FENNEL_BEGIN_NAMESPACE
00034 
00035 template<typename PTR_TYPE, typename OP2T>
00036 class PointerPointerInstruction : public PointerInstruction
00037 {
00038 public:
00039     explicit
00040     PointerPointerInstruction(
00041         RegisterRef<PTR_TYPE>* result,
00042         StandardTypeDescriptorOrdinal pointerType)
00043         : mResult(result),
00044           mOp1(),            // unused
00045           mOp2(),            // unused
00046           mPointerType(pointerType)
00047     {
00048         assert(StandardTypeDescriptor::isArray(pointerType));
00049     }
00050     explicit
00051     PointerPointerInstruction(
00052         RegisterRef<PTR_TYPE>* result,
00053         RegisterRef<PTR_TYPE>* op1,
00054         StandardTypeDescriptorOrdinal pointerType)
00055         : mResult(result),
00056           mOp1(op1),
00057           mOp2(),            // unused
00058           mPointerType(pointerType)
00059     {
00060         assert(StandardTypeDescriptor::isArray(pointerType));
00061     }
00062     explicit
00063     PointerPointerInstruction(
00064         RegisterRef<PTR_TYPE>* result,
00065         RegisterRef<PTR_TYPE>* op1,
00066         RegisterRef<OP2T>* op2,
00067         StandardTypeDescriptorOrdinal pointerType)
00068         : mResult(result),
00069           mOp1(op1),
00070           mOp2(op2),
00071           mPointerType(pointerType)
00072     {
00073         assert(StandardTypeDescriptor::isArray(pointerType));
00074     }
00075     ~PointerPointerInstruction() {
00076 #ifndef __MSVC__
00077         // If (0) to reduce performance impact of template type checking
00078         if (0) {
00079             PointerInstruction_NotAPointerType<PTR_TYPE>();
00080         }
00081 #endif
00082     }
00083 
00084 protected:
00085     RegisterRef<PTR_TYPE>* mResult;
00086     RegisterRef<PTR_TYPE>* mOp1;
00087     RegisterRef<OP2T>* mOp2;
00088     StandardTypeDescriptorOrdinal mPointerType;
00089 };
00090 
00093 template <typename PTR_TYPE>
00094 class PointerAdd : public PointerPointerInstruction<PTR_TYPE, PointerOperandT>
00095 {
00096 public:
00097     explicit
00098     PointerAdd(
00099         RegisterRef<PTR_TYPE>* result,
00100         RegisterRef<PTR_TYPE>* op1,
00101         RegisterRef<PointerOperandT>* op2,
00102         StandardTypeDescriptorOrdinal pointerType)
00103         : PointerPointerInstruction<PTR_TYPE, PointerOperandT>(
00104             result,
00105             op1,
00106             op2,
00107             pointerType)
00108     {}
00109 
00110     virtual
00111     ~PointerAdd() {}
00112 
00113     virtual void exec(TProgramCounter& pc) const {
00114         pc++;
00115         if (PointerPointerInstruction<
00116                 PTR_TYPE, PointerOperandT>::mOp1->isNull() ||
00117             PointerPointerInstruction<
00118                 PTR_TYPE, PointerOperandT>::mOp2->isNull())
00119         {
00120             PointerPointerInstruction<
00121                 PTR_TYPE, PointerOperandT>::mResult->toNull();
00122             PointerPointerInstruction<
00123                 PTR_TYPE, PointerOperandT>::mResult->length(0);
00124         } else {
00125             // Educated guess: Length decreases. If incorrect, compiler is
00126             // responsible for resetting the length correctly with
00127             // Instruction PointerPutSize
00128             uint oldLength =
00129                 PointerPointerInstruction<
00130                     PTR_TYPE, PointerOperandT>::mOp1->length();
00131             uint delta =
00132                 PointerPointerInstruction<
00133                     PTR_TYPE, PointerOperandT>::mOp2->value();
00134             uint newLength;
00135             if (oldLength > delta) {
00136                 newLength = oldLength - delta;
00137             } else {
00138                 newLength = 0;
00139             }
00140             PointerPointerInstruction<
00141                 PTR_TYPE, PointerOperandT>::mResult->pointer(
00142                     static_cast<PTR_TYPE>(
00143                         PointerPointerInstruction<
00144                             PTR_TYPE, PointerOperandT>::mOp1->pointer()) +
00145                     PointerPointerInstruction<
00146                         PTR_TYPE, PointerOperandT>::mOp2->value(),
00147                 newLength);
00148         }
00149     }
00150 
00151     static const char* longName()
00152     {
00153         return "PointerAdd";
00154     }
00155 
00156     static const char* shortName()
00157     {
00158         return "ADD";
00159     }
00160 
00161     static int numArgs()
00162     {
00163         return 3;
00164     }
00165 
00166     void describe(string& out, bool values) const {
00167         describeHelper(
00168             out, values, longName(), shortName(),
00169             PointerPointerInstruction<PTR_TYPE, PointerOperandT>::mResult,
00170             PointerPointerInstruction<PTR_TYPE, PointerOperandT>::mOp1,
00171             PointerPointerInstruction<PTR_TYPE, PointerOperandT>::mOp2);
00172     }
00173 
00174     static InstructionSignature
00175     signature(StandardTypeDescriptorOrdinal type) {
00176         return InstructionSignature(
00177             shortName(),
00178             regDesc(0, numArgs() - 1, type, 1));
00179     }
00180 
00181     static Instruction*
00182     create(InstructionSignature const & sig)
00183     {
00184         assert(sig.size() == numArgs());
00185         return new PointerAdd(
00186             static_cast<RegisterRef<PTR_TYPE>*> (sig[0]),
00187             static_cast<RegisterRef<PTR_TYPE>*> (sig[1]),
00188             static_cast<RegisterRef<PointerOperandT>*> (sig[2]),
00189             (sig[0])->type());
00190     }
00191 };
00192 
00198 template <typename PTR_TYPE>
00199 class PointerSub : public PointerPointerInstruction<PTR_TYPE, PointerOperandT>
00200 {
00201 public:
00202     explicit
00203     PointerSub(
00204         RegisterRef<PTR_TYPE>* result,
00205         RegisterRef<PTR_TYPE>* op1,
00206         RegisterRef<PointerOperandT>* op2,
00207         StandardTypeDescriptorOrdinal pointerType)
00208         : PointerPointerInstruction<PTR_TYPE, PointerOperandT>(
00209             result,
00210             op1,
00211             op2,
00212             pointerType)
00213     {}
00214 
00215     virtual
00216     ~PointerSub() {}
00217 
00218     virtual void exec(TProgramCounter& pc) const {
00219         pc++;
00220         if (PointerPointerInstruction<
00221                 PTR_TYPE, PointerOperandT>::mOp1->isNull() ||
00222             PointerPointerInstruction<
00223                 PTR_TYPE, PointerOperandT>::mOp2->isNull()) {
00224             PointerPointerInstruction<
00225                 PTR_TYPE, PointerOperandT>::mResult->toNull();
00226             PointerPointerInstruction<
00227                 PTR_TYPE, PointerOperandT>::mResult->length(0);
00228         } else {
00229             // Educated guess: Length increases. If incorrect, compiler is
00230             // responsible for resetting the length correctly with
00231             // Instruction PointerPutLength
00232             uint newLength =
00233                 PointerPointerInstruction<
00234                     PTR_TYPE, PointerOperandT>::mOp1->length() +
00235                 PointerPointerInstruction<
00236                     PTR_TYPE, PointerOperandT>::mOp2->value();
00237             uint maxLength =
00238                 PointerPointerInstruction<
00239                     PTR_TYPE, PointerOperandT>::mOp1->storage();
00240             if (newLength > maxLength) {
00241                 newLength = maxLength;
00242             }
00243             PointerPointerInstruction<
00244                 PTR_TYPE, PointerOperandT>::mResult->pointer(
00245                     static_cast<PTR_TYPE>(
00246                         PointerPointerInstruction<
00247                             PTR_TYPE, PointerOperandT>::mOp1->pointer()) -
00248                     PointerPointerInstruction<
00249                         PTR_TYPE, PointerOperandT>::mOp2->value(),
00250                 newLength);
00251         }
00252     }
00253 
00254     static const char* longName()
00255     {
00256         return "PointerSub";
00257     }
00258 
00259     static const char* shortName()
00260     {
00261         return "SUB";
00262     }
00263 
00264     static int numArgs()
00265     {
00266         return 3;
00267     }
00268 
00269     void describe(string& out, bool values) const {
00270         describeHelper(
00271             out, values, longName(), shortName(),
00272             PointerPointerInstruction<PTR_TYPE, PointerOperandT>::mResult,
00273             PointerPointerInstruction<PTR_TYPE, PointerOperandT>::mOp1,
00274             PointerPointerInstruction<PTR_TYPE, PointerOperandT>::mOp2);
00275     }
00276 
00277     static InstructionSignature
00278     signature(StandardTypeDescriptorOrdinal type) {
00279         return InstructionSignature(
00280             shortName(),
00281             regDesc(0, numArgs() - 1, type, 1));
00282     }
00283 
00284     static Instruction*
00285     create(InstructionSignature const & sig)
00286     {
00287         assert(sig.size() == numArgs());
00288         return new PointerSub(
00289             static_cast<RegisterRef<PTR_TYPE>*> (sig[0]),
00290             static_cast<RegisterRef<PTR_TYPE>*> (sig[1]),
00291             static_cast<RegisterRef<PointerOperandT>*> (sig[2]),
00292             (sig[0])->type());
00293     }
00294 };
00295 
00296 
00297 template <typename PTR_TYPE>
00298 class PointerMove : public PointerPointerInstruction<PTR_TYPE, PTR_TYPE>
00299 {
00300 public:
00301     explicit
00302     PointerMove(
00303         RegisterRef<PTR_TYPE>* result,
00304         RegisterRef<PTR_TYPE>* op1,
00305         StandardTypeDescriptorOrdinal pointerType)
00306         : PointerPointerInstruction<PTR_TYPE, PTR_TYPE>(
00307             result,
00308             op1,
00309             pointerType)
00310     {}
00311 
00312     virtual
00313     ~PointerMove() {}
00314 
00315     virtual void exec(TProgramCounter& pc) const {
00316         pc++;
00317         if (PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mOp1->isNull()) {
00318             PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mResult->toNull();
00319             PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mResult->length(0);
00320         } else {
00321             PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mResult->pointer(
00322                PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mOp1->pointer(),
00323                PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mOp1->length());
00324         }
00325     }
00326     static const char* longName()
00327     {
00328         return "PointerMove";
00329     }
00330 
00331     static const char* shortName()
00332     {
00333         return "MOVE";
00334     }
00335 
00336     static int numArgs()
00337     {
00338         return 2;
00339     }
00340 
00341     void describe(string& out, bool values) const {
00342         describeHelper(
00343             out, values, longName(), shortName(),
00344             PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mResult,
00345             PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mOp1,
00346             PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mOp2);
00347     }
00348 
00349     static InstructionSignature
00350     signature(StandardTypeDescriptorOrdinal type) {
00351         return InstructionSignature(
00352             shortName(),
00353             regDesc(0, numArgs(), type, 0));
00354     }
00355 
00356     static Instruction*
00357     create(InstructionSignature const & sig)
00358     {
00359         assert(sig.size() == numArgs());
00360         return new PointerMove(
00361             static_cast<RegisterRef<PTR_TYPE>*> (sig[0]),
00362             static_cast<RegisterRef<PTR_TYPE>*> (sig[1]),
00363             (sig[0])->type());
00364     }
00365 };
00366 
00367 template <typename PTR_TYPE>
00368 class PointerRef : public PointerPointerInstruction<PTR_TYPE, PTR_TYPE>
00369 {
00370 public:
00371     explicit
00372     PointerRef(
00373         RegisterRef<PTR_TYPE>* result,
00374         RegisterRef<PTR_TYPE>* op1,
00375         StandardTypeDescriptorOrdinal pointerType)
00376         : PointerPointerInstruction<PTR_TYPE, PTR_TYPE>(
00377             result,
00378             op1,
00379             pointerType)
00380     {}
00381 
00382     virtual
00383     ~PointerRef() {}
00384 
00385     virtual void exec(TProgramCounter& pc) const {
00386         pc++;
00387         PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mResult->
00388             refer(PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mOp1);
00389     }
00390 
00391     static const char* longName()
00392     {
00393         return "PointerRef";
00394     }
00395 
00396     static const char* shortName()
00397     {
00398         return "REF";
00399     }
00400 
00401     static int numArgs()
00402     {
00403         return 2;
00404     }
00405 
00406     void describe(string& out, bool values) const {
00407         describeHelper(
00408             out, values, longName(), shortName(),
00409             PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mResult,
00410             PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mOp1,
00411             PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mOp2);
00412     }
00413 
00414     static InstructionSignature
00415     signature(StandardTypeDescriptorOrdinal type) {
00416         return InstructionSignature(
00417             shortName(),
00418             regDesc(0, numArgs(), type, 0));
00419     }
00420 
00421     static Instruction*
00422     create(InstructionSignature const & sig)
00423     {
00424         assert(sig.size() == numArgs());
00425         return new PointerRef(
00426             static_cast<RegisterRef<PTR_TYPE>*> (sig[0]),
00427             static_cast<RegisterRef<PTR_TYPE>*> (sig[1]),
00428             (sig[0])->type());
00429     }
00430 };
00431 
00432 
00433 template <typename PTR_TYPE>
00434 class PointerToNull : public PointerPointerInstruction<PTR_TYPE, PTR_TYPE>
00435 {
00436 public:
00437     explicit
00438     PointerToNull(
00439         RegisterRef<PTR_TYPE>* result,
00440         StandardTypeDescriptorOrdinal pointerType)
00441         : PointerPointerInstruction<PTR_TYPE, PTR_TYPE>(result, pointerType)
00442     {}
00443 
00444     virtual
00445     ~PointerToNull() {}
00446 
00447     virtual void exec(TProgramCounter& pc) const {
00448         pc++;
00449         PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mResult->toNull();
00450         PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mResult->length(0);
00451     }
00452 
00453     static const char* longName()
00454     {
00455         return "PointerToNull";
00456     }
00457 
00458     static const char* shortName()
00459     {
00460         return "TONULL";
00461     }
00462 
00463     static int numArgs()
00464     {
00465         return 1;
00466     }
00467 
00468     void describe(string& out, bool values) const {
00469         describeHelper(
00470             out, values, longName(), shortName(),
00471             PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mResult,
00472             PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mOp1,
00473             PointerPointerInstruction<PTR_TYPE, PTR_TYPE>::mOp2);
00474     }
00475 
00476     static InstructionSignature
00477     signature(StandardTypeDescriptorOrdinal type) {
00478         return InstructionSignature(
00479             shortName(),
00480             regDesc(0, numArgs(), type, 0));
00481     }
00482 
00483     static Instruction*
00484     create(InstructionSignature const & sig)
00485     {
00486         assert(sig.size() == numArgs());
00487         return new PointerToNull(
00488             static_cast<RegisterRef<PTR_TYPE>*> (sig[0]),
00489             (sig[0])->type());
00490     }
00491 };
00492 
00493 
00494 class FENNEL_CALCULATOR_EXPORT PointerPointerInstructionRegister
00495     : InstructionRegister
00496 {
00497     // TODO: Refactor registerTypes to class InstructionRegister
00498     template < template <typename> class INSTCLASS2 >
00499     static void
00500     registerTypes(vector<StandardTypeDescriptorOrdinal> const &t) {
00501 
00502         for (uint i = 0; i < t.size(); i++) {
00503             StandardTypeDescriptorOrdinal type = t[i];
00504             // Type <char> below is a placeholder and is ignored.
00505             InstructionSignature sig = INSTCLASS2<char>::signature(type);
00506             switch (type) {
00507                 // Array_Text, below, does not allow assembly programs
00508                 // of to have say, pointer to int16s, but the language
00509                 // does not have pointers defined other than
00510                 // c,vc,b,vb, so this is OK for now.
00511 #define Fennel_InstructionRegisterSwitch_Array 1
00512 #include "fennel/calculator/InstructionRegisterSwitch.h"
00513             default:
00514                 throw std::logic_error("Default InstructionRegister");
00515             }
00516         }
00517     }
00518 
00519 public:
00520     static void
00521     registerInstructions() {
00522         vector<StandardTypeDescriptorOrdinal> t;
00523         // isArray, below, does not allow assembly programs of to
00524         // have say, pointer to int16s, but the language does not have
00525         // pointers defined other than c,vc,b,vb, so this is OK for now.
00526         t = InstructionSignature::typeVector(StandardTypeDescriptor::isArray);
00527 
00528         // Have to do full fennel:: qualification of template
00529         // arguments below to prevent template argument 'TMPLT', of
00530         // this encapsulating class, from perverting NativeAdd into
00531         // NativeAdd<TMPLT> or something like
00532         // that. Anyway. Fennel::NativeAdd works just fine.
00533         registerTypes<fennel::PointerAdd>(t);
00534         registerTypes<fennel::PointerSub>(t);
00535         registerTypes<fennel::PointerMove>(t);
00536         registerTypes<fennel::PointerRef>(t);
00537         registerTypes<fennel::PointerToNull>(t);
00538     }
00539 };
00540 
00541 FENNEL_END_NAMESPACE
00542 
00543 #endif
00544 
00545 // End PointerPointerInstruction.h
00546 

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