Fennel: /home/pub/open/dev/fennel/calculator/PointerPointerInstruction.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_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* 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* result,
00053 RegisterRef* 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* result,
00065 RegisterRef* op1,
00066 RegisterRef* 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();
00080 }
00081 #endif
00082 }
00083
00084 protected:
00085 RegisterRef* mResult;
00086 RegisterRef* mOp1;
00087 RegisterRef* mOp2;
00088 StandardTypeDescriptorOrdinal mPointerType;
00089 };
00090
00093 template
00094 class PointerAdd : public PointerPointerInstruction<PTR_TYPE, PointerOperandT>
00095 {
00096 public:
00097 explicit
00098 PointerAdd(
00099 RegisterRef* result,
00100 RegisterRef* op1,
00101 RegisterRef* 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(
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> (sig[0]),
00187 static_cast<RegisterRef> (sig[1]),
00188 static_cast<RegisterRef> (sig[2]),
00189 (sig[0])->type());
00190 }
00191 };
00192
00198 template
00199 class PointerSub : public PointerPointerInstruction<PTR_TYPE, PointerOperandT>
00200 {
00201 public:
00202 explicit
00203 PointerSub(
00204 RegisterRef result,
00205 RegisterRef* op1,
00206 RegisterRef* 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(
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> (sig[0]),
00290 static_cast<RegisterRef> (sig[1]),
00291 static_cast<RegisterRef> (sig[2]),
00292 (sig[0])->type());
00293 }
00294 };
00295
00296
00297 template
00298 class PointerMove : public PointerPointerInstruction<PTR_TYPE, PTR_TYPE>
00299 {
00300 public:
00301 explicit
00302 PointerMove(
00303 RegisterRef result,
00304 RegisterRef* 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> (sig[0]),
00362 static_cast<RegisterRef> (sig[1]),
00363 (sig[0])->type());
00364 }
00365 };
00366
00367 template
00368 class PointerRef : public PointerPointerInstruction<PTR_TYPE, PTR_TYPE>
00369 {
00370 public:
00371 explicit
00372 PointerRef(
00373 RegisterRef* result,
00374 RegisterRef* 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> (sig[0]),
00427 static_cast<RegisterRef> (sig[1]),
00428 (sig[0])->type());
00429 }
00430 };
00431
00432
00433 template
00434 class PointerToNull : public PointerPointerInstruction<PTR_TYPE, PTR_TYPE>
00435 {
00436 public:
00437 explicit
00438 PointerToNull(
00439 RegisterRef* 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*> (sig[0]),
00489 (sig[0])->type());
00490 }
00491 };
00492
00493
00494 class FENNEL_CALCULATOR_EXPORT PointerPointerInstructionRegister
00495 : InstructionRegister
00496 {
00497
00498 template < template class INSTCLASS2 >
00499 static void
00500 registerTypes(vector const &t) {
00501
00502 for (uint i = 0; i < t.size(); i++) {
00503 StandardTypeDescriptorOrdinal type = t[i];
00504
00505 InstructionSignature sig = INSTCLASS2::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 t;
00523
00524
00525
00526 t = InstructionSignature::typeVector(StandardTypeDescriptor::isArray);
00527
00528
00529
00530
00531
00532
00533 registerTypesfennel::PointerAdd(t);
00534 registerTypesfennel::PointerSub(t);
00535 registerTypesfennel::PointerMove(t);
00536 registerTypesfennel::PointerRef(t);
00537 registerTypesfennel::PointerToNull(t);
00538 }
00539 };
00540
00541 FENNEL_END_NAMESPACE
00542
00543 #endif
00544
00545
00546