00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
00038
00039
00040
00041
00042
00043
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
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
00118 if (NativeInstruction<TMPLT>::mOp1->isNull() ||
00119 NativeInstruction<TMPLT>::mOp2->isNull()) {
00120 IntegralNativeInstruction<TMPLT>::mResult->toNull();
00121 } else {
00122
00123 TMPLT o2 = NativeInstruction<TMPLT>::mOp2->value();
00124 if (o2 == 0) {
00125 IntegralNativeInstruction<TMPLT>::mResult->toNull();
00126
00127
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
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
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
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
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
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
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
00484
00485
00486
00487
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
00502