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_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(),
00045 mOp2(),
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(),
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
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
00126
00127
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
00230
00231
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
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
00505 InstructionSignature sig = INSTCLASS2<char>::signature(type);
00506 switch (type) {
00507
00508
00509
00510
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
00524
00525
00526 t = InstructionSignature::typeVector(StandardTypeDescriptor::isArray);
00527
00528
00529
00530
00531
00532
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
00546