00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "fennel/common/CommonPreamble.h"
00024 #include "fennel/test/TestBase.h"
00025 #include "fennel/common/TraceSource.h"
00026
00027 #include "fennel/tuple/TupleDataWithBuffer.h"
00028 #include "fennel/tuple/TuplePrinter.h"
00029 #include "fennel/calculator/CalcCommon.h"
00030 #include "fennel/calculator/StringToHex.h"
00031 #include "fennel/common/FennelExcn.h"
00032
00033 #include <boost/test/test_tools.hpp>
00034 #include <boost/scoped_array.hpp>
00035 #include <string>
00036 #include <limits>
00037
00038
00039 using namespace fennel;
00040 using namespace std;
00041
00042
00043 class CalcMiscTest : virtual public TestBase, public TraceSource
00044 {
00045 void testCalcStatusReg();
00046 void testCalcStatusRegZero();
00047 void testCalcRefInst();
00048 void testCalcReturn();
00049 void testCalcRaise();
00050 void testCalcContinueOnException();
00051
00052 public:
00053 explicit CalcMiscTest()
00054 : TraceSource(shared_from_this(),"CalcMiscTest")
00055 {
00056 srand(time(NULL));
00057 CalcInit::instance();
00058 FENNEL_UNIT_TEST_CASE(CalcMiscTest, testCalcStatusReg);
00059 FENNEL_UNIT_TEST_CASE(CalcMiscTest, testCalcStatusRegZero);
00060 FENNEL_UNIT_TEST_CASE(CalcMiscTest, testCalcRefInst);
00061 FENNEL_UNIT_TEST_CASE(CalcMiscTest, testCalcReturn);
00062 FENNEL_UNIT_TEST_CASE(CalcMiscTest, testCalcRaise);
00063 FENNEL_UNIT_TEST_CASE(CalcMiscTest, testCalcContinueOnException);
00064 }
00065
00066 virtual ~CalcMiscTest()
00067 {
00068 }
00069 };
00070
00071 void
00072 CalcMiscTest::testCalcStatusReg()
00073 {
00074 ostringstream pg("");
00075
00076 pg << "L u2;" << endl;
00077 pg << "O u2;" << endl;
00078 pg << "S u2, u2, u2;" << endl;
00079 pg << "C u2, u2, u2;" << endl;
00080 pg << "V 4, 5, 6;" << endl;
00081 pg << "T;" << endl;
00082 pg << "MOVE S 0, C 0;" << endl;
00083 pg << "MOVE L 0, C 1;" << endl;
00084 pg << "REF O 0, C 2;" << endl;
00085 pg << "MOVE S 1, L 0;" << endl;
00086 pg << "MOVE S 2, O 0;" << endl;
00087
00088
00089
00090 Calculator calc(0);
00091
00092 try {
00093 calc.assemble(pg.str().c_str());
00094 } catch (FennelExcn& ex) {
00095 BOOST_MESSAGE("Assemble exception " << ex.getMessage());
00096 BOOST_REQUIRE(0);
00097 }
00098
00099 TupleDataWithBuffer outTuple(calc.getOutputRegisterDescriptor());
00100 TupleDataWithBuffer inTuple(calc.getInputRegisterDescriptor());
00101
00102 calc.bind(&inTuple, &outTuple);
00103 calc.exec();
00104
00105 TupleData const * const statusTuple = calc.getStatusRegister();
00106 #if 0
00107 TupleDescriptor statusDesc = calc.getStatusRegisterDescriptor();
00108 TuplePrinter tuplePrinter;
00109 tuplePrinter.print(cout, statusDesc, *statusTuple);
00110 cout << endl;
00111 #endif
00112
00113 BOOST_CHECK_EQUAL(
00114 *(reinterpret_cast<uint16_t *>(
00115 const_cast<PBuffer>((*statusTuple)[0].pData))),
00116 4);
00117 BOOST_CHECK_EQUAL(
00118 *(reinterpret_cast<uint16_t *>(
00119 const_cast<PBuffer>((*statusTuple)[1].pData))),
00120 5);
00121 BOOST_CHECK_EQUAL(
00122 *(reinterpret_cast<uint16_t *>(
00123 const_cast<PBuffer>((*statusTuple)[2].pData))),
00124 6);
00125 }
00126
00127 void
00128 CalcMiscTest::testCalcStatusRegZero()
00129 {
00130 ostringstream pg("");
00131
00132 pg << "L u2;" << endl;
00133 pg << "O u2;" << endl;
00134 pg << "S u2, u2;" << endl;
00135 pg << "C u2, u2;" << endl;
00136 pg << "V 1, 2;" << endl;
00137 pg << "T;" << endl;
00138 pg << "MOVE L 0, S 0;" << endl;
00139 pg << "ADD S 0, L 0, C 0;" << endl;
00140 pg << "MOVE L 0, S 1;" << endl;
00141 pg << "ADD S 1, L 0, C 1;" << endl;
00142
00143
00144
00145 Calculator calc(0);
00146
00147 try {
00148 calc.assemble(pg.str().c_str());
00149 } catch (FennelExcn& ex) {
00150 BOOST_MESSAGE("Assemble exception " << ex.getMessage());
00151 BOOST_REQUIRE(0);
00152 }
00153
00154 TupleDataWithBuffer outTuple(calc.getOutputRegisterDescriptor());
00155 TupleDataWithBuffer inTuple(calc.getInputRegisterDescriptor());
00156
00157 calc.bind(&inTuple, &outTuple);
00158
00159 TupleData const * const statusTuple = calc.getStatusRegister();
00160
00161 for (int i = 1; i <= 3; i++) {
00162 calc.exec();
00163
00164 BOOST_CHECK_EQUAL(
00165 *(reinterpret_cast<uint16_t *>(
00166 const_cast<PBuffer>((*statusTuple)[0].pData))),
00167 i);
00168 BOOST_CHECK_EQUAL(
00169 *(reinterpret_cast<uint16_t *>(
00170 const_cast<PBuffer>((*statusTuple)[1].pData))),
00171 i * 2);
00172 }
00173
00174 calc.zeroStatusRegister();
00175
00176 BOOST_CHECK_EQUAL(
00177 *(reinterpret_cast<uint16_t *>(
00178 const_cast<PBuffer>((*statusTuple)[0].pData))),
00179 0);
00180 BOOST_CHECK_EQUAL(
00181 *(reinterpret_cast<uint16_t *>(
00182 const_cast<PBuffer>((*statusTuple)[1].pData))),
00183 0);
00184
00185 calc.exec();
00186
00187 BOOST_CHECK_EQUAL(
00188 *(reinterpret_cast<uint16_t *>(
00189 const_cast<PBuffer>((*statusTuple)[0].pData))),
00190 1);
00191 BOOST_CHECK_EQUAL(
00192 *(reinterpret_cast<uint16_t *>(
00193 const_cast<PBuffer>((*statusTuple)[1].pData))),
00194 2);
00195 }
00196
00197 void
00198 CalcMiscTest::testCalcRefInst()
00199 {
00200 ostringstream pg("");
00201
00202 char const * const all =
00203 "bo, s1, u1, s2, u2, s4, u4, s8, u8, r, d, vc,2, c,2";
00204
00205 int const numTypes = 13;
00206 char regs[] = { 'I', 'L', 'C' };
00207 int const numRegSets = 3;
00208
00209
00210 pg << "I " << all << ";" << endl;
00211 pg << "O " << all << ", " << endl;
00212 pg << " " << all << ", " << endl;
00213 pg << " " << all << ";" << endl;
00214 pg << "L " << all << ";" << endl;
00215 pg << "C " << all << ";" << endl;
00216 pg << "V 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.0, 10.0, 0x";
00217 pg << stringToHex("11") << ", 0x" << stringToHex("12") << ";" << endl;
00218 pg << "T;" << endl;
00219
00220 int outReg = 0, regSet, regFrom;
00221
00222 for (regFrom = 0; regFrom < numTypes; regFrom++) {
00223 pg << "MOVE L" << regFrom << ", C" << regFrom << ";" << endl;
00224 }
00225
00226
00227 for (regSet = 0; regSet < numRegSets; regSet++) {
00228 for (regFrom = 0; regFrom < numTypes; regFrom++) {
00229 pg << "REF O" << outReg++ << ", " << regs[regSet];
00230 pg << regFrom << ";" << endl;
00231 }
00232 }
00233
00234
00235
00236 Calculator calc(0);
00237
00238 try {
00239 calc.assemble(pg.str().c_str());
00240 } catch (FennelExcn& ex) {
00241 BOOST_MESSAGE("Assemble exception " << ex.getMessage());
00242 BOOST_REQUIRE(0);
00243 }
00244
00245 TupleDataWithBuffer outTuple(calc.getOutputRegisterDescriptor());
00246 TupleDataWithBuffer inTuple(calc.getInputRegisterDescriptor());
00247
00248 calc.bind(&inTuple, &outTuple);
00249 calc.exec();
00250
00251 outReg = 0;
00252 for (regSet = 0; regSet < numRegSets; regSet++) {
00253 for (regFrom = 0; regFrom < numTypes; regFrom++) {
00254 switch (regs[regSet]) {
00255 case 'I':
00256
00257 BOOST_CHECK_EQUAL(
00258 outTuple[outReg].pData,
00259 inTuple[regFrom].pData);
00260 break;
00261 case 'L':
00262 case 'C':
00263
00264
00265
00266
00267 if (regFrom <= 8) {
00268
00269
00270 BOOST_CHECK_EQUAL(
00271 *(outTuple[outReg].pData),
00272 regFrom);
00273 } else if (regFrom == 9) {
00274
00275 BOOST_CHECK_EQUAL(
00276 *(reinterpret_cast<float const *>(
00277 outTuple[outReg].pData)),
00278 static_cast<float>(regFrom));
00279 } else if (regFrom == 10) {
00280
00281 BOOST_CHECK_EQUAL(
00282 *(reinterpret_cast<double const*>(
00283 outTuple[outReg].pData)),
00284 static_cast<double>(regFrom));
00285 } else if (regFrom == 11) {
00286
00287 BOOST_CHECK_EQUAL(
00288 0,
00289 strncmp(
00290 reinterpret_cast<char const *>(
00291 outTuple[outReg].pData),
00292 "11",
00293 2));
00294 } else if (regFrom == 12) {
00295
00296 BOOST_CHECK_EQUAL(
00297 0,
00298 strncmp(
00299 reinterpret_cast<char const *>(
00300 outTuple[outReg].pData),
00301 "12",
00302 2));
00303 } else {
00304 BOOST_FAIL("logic error");
00305 }
00306 break;
00307 }
00308 outReg++;
00309 }
00310 }
00311 }
00312
00313 void
00314 CalcMiscTest::testCalcReturn()
00315 {
00316 ostringstream pg("");
00317
00318 pg << "S u4;" << endl;
00319 pg << "C u4, u4, u4;" << endl;
00320 pg << "V 4, 5, 6;" << endl;
00321 pg << "T;" << endl;
00322 pg << "MOVE S 0, C 0;" << endl;
00323 pg << "RETURN;" << endl;
00324 pg << "MOVE S 0, C 1;" << endl;
00325
00326
00327
00328 Calculator calc(0);
00329
00330 try {
00331 calc.assemble(pg.str().c_str());
00332 } catch (FennelExcn& ex) {
00333 BOOST_MESSAGE("Assemble exception " << ex.getMessage());
00334 BOOST_REQUIRE(0);
00335 }
00336
00337 TupleDataWithBuffer outTuple(calc.getOutputRegisterDescriptor());
00338 TupleDataWithBuffer inTuple(calc.getInputRegisterDescriptor());
00339
00340 calc.bind(&inTuple, &outTuple);
00341 calc.exec();
00342
00343 TupleData const * const statusTuple = calc.getStatusRegister();
00344 #if 0
00345 TupleDescriptor statusDesc = calc.getStatusRegisterDescriptor();
00346 TuplePrinter tuplePrinter;
00347 tuplePrinter.print(cout, statusDesc, *statusTuple);
00348 cout << endl;
00349 #endif
00350
00351 BOOST_CHECK_EQUAL(
00352 *(reinterpret_cast<uint32_t *>(
00353 const_cast<PBuffer>((*statusTuple)[0].pData))),
00354 4);
00355 }
00356
00357
00358 void
00359 CalcMiscTest::testCalcRaise()
00360 {
00361 ostringstream pg("");
00362
00363 pg << "I u4;" << endl;
00364 pg << "S u4;" << endl;
00365 pg << "C u4, u4, vc,5, vc,5;" << endl;
00366 pg << "V 4, 5, 0x" << stringToHex("12345") << ",;" << endl;
00367 pg << "T;" << endl;
00368 pg << "MOVE S0, C0;" << endl;
00369 pg << "RAISE C2;" << endl;
00370 pg << "RAISE C3;" << endl;
00371 pg << "MOVE S0, C1;" << endl;
00372 pg << "RETURN;" << endl;
00373
00374
00375
00376 Calculator calc(0);
00377
00378 try {
00379 calc.assemble(pg.str().c_str());
00380 } catch (FennelExcn& ex) {
00381 BOOST_MESSAGE("Assemble exception " << ex.getMessage());
00382 BOOST_REQUIRE(0);
00383 }
00384
00385 TupleDataWithBuffer outTuple(calc.getOutputRegisterDescriptor());
00386 TupleDataWithBuffer inTuple(calc.getInputRegisterDescriptor());
00387
00388 calc.bind(&inTuple, &outTuple);
00389 calc.exec();
00390
00391 TupleData const * const statusTuple = calc.getStatusRegister();
00392 #if 0
00393 TupleDescriptor statusDesc = calc.getStatusRegisterDescriptor();
00394 TuplePrinter tuplePrinter;
00395 tuplePrinter.print(cout, statusDesc, *statusTuple);
00396 cout << endl;
00397 #endif
00398
00399 BOOST_CHECK_EQUAL(
00400 *(reinterpret_cast<uint32_t *>(
00401 const_cast<PBuffer>((*statusTuple)[0].pData))),
00402 5);
00403
00404 deque<CalcMessage>::iterator iter = calc.mWarnings.begin();
00405 deque<CalcMessage>::iterator end = calc.mWarnings.end();
00406
00407
00408
00409 BOOST_CHECK(iter != end);
00410 BOOST_CHECK_EQUAL(iter->pc, 1);
00411 BOOST_CHECK_EQUAL(0, strcmp(iter->str, "12345"));
00412 iter++;
00413 BOOST_CHECK(iter == end);
00414 }
00415
00416 void
00417 CalcMiscTest::testCalcContinueOnException()
00418 {
00419 ostringstream pg("");
00420
00421 pg << "I u4;" << endl;
00422 pg << "S u4;" << endl;
00423 pg << "C u4, u4, vc,5, vc,5;" << endl;
00424 pg << "V 4, 5, 0x" << stringToHex("12345") << ",;" << endl;
00425 pg << "T;" << endl;
00426 pg << "MOVE S0, C0;" << endl;
00427 pg << "RAISE C2;" << endl;
00428 pg << "MOVE S0, C1;" << endl;
00429 pg << "RETURN;" << endl;
00430
00431 BOOST_MESSAGE(pg.str());
00432
00433 Calculator calc(0);
00434
00435 try {
00436 calc.assemble(pg.str().c_str());
00437 } catch (FennelExcn& ex) {
00438 BOOST_MESSAGE("Assemble exception " << ex.getMessage());
00439 BOOST_REQUIRE(0);
00440 }
00441
00442 TupleDataWithBuffer outTuple(calc.getOutputRegisterDescriptor());
00443 TupleDataWithBuffer inTuple(calc.getInputRegisterDescriptor());
00444
00445 calc.bind(&inTuple, &outTuple);
00446
00447 calc.exec();
00448
00449 TupleData const * const statusTuple = calc.getStatusRegister();
00450 #if 0
00451 TupleDescriptor statusDesc = calc.getStatusRegisterDescriptor();
00452 TuplePrinter tuplePrinter;
00453 tuplePrinter.print(cout, statusDesc, *statusTuple);
00454 cout << endl;
00455 #endif
00456
00457 BOOST_CHECK_EQUAL(
00458 *(reinterpret_cast<uint32_t *>(
00459 const_cast<PBuffer>((*statusTuple)[0].pData))),
00460 5);
00461
00462 deque<CalcMessage>::iterator iter = calc.mWarnings.begin();
00463 deque<CalcMessage>::iterator end = calc.mWarnings.end();
00464
00465 BOOST_MESSAGE("warnings: |" << calc.warnings() << "|");
00466
00467 BOOST_CHECK(iter != end);
00468 BOOST_CHECK_EQUAL(
00469 iter->pc, 1);
00470 BOOST_CHECK_EQUAL(
00471 0, strcmp(iter->str, "12345"));
00472 iter++;
00473 BOOST_CHECK(iter == end);
00474
00475
00476 calc.continueOnException(false);
00477 calc.exec();
00478
00479 BOOST_CHECK_EQUAL(
00480 *(reinterpret_cast<uint32_t *>(
00481 const_cast<PBuffer>((*statusTuple)[0].pData))),
00482 4);
00483
00484 iter = calc.mWarnings.begin();
00485 end = calc.mWarnings.end();
00486
00487 BOOST_MESSAGE("warnings: |" << calc.warnings() << "|");
00488
00489 BOOST_CHECK(iter != end);
00490 BOOST_CHECK_EQUAL(
00491 iter->pc, 1);
00492 BOOST_CHECK_EQUAL(
00493 0, strcmp(iter->str, "12345"));
00494 iter++;
00495 BOOST_CHECK(iter == end);
00496
00497 }
00498
00499 FENNEL_UNIT_TEST_SUITE(CalcMiscTest);
00500
00501