00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "ExpTest.h"
00018 #include "statement.h"
00019 #include "visitor.h"
00020 #include <map>
00021 #include <sstream>
00022
00023
00024
00025
00026
00027
00028
00029 #define MYTEST(name) \
00030 suite->addTest(new CppUnit::TestCaller<ExpTest> ("testExp", \
00031 &ExpTest::name, *this))
00032
00033 void ExpTest::registerTests(CppUnit::TestSuite* suite) {
00034 MYTEST(testFixSuccessor);
00035 MYTEST(test99);
00036 MYTEST(testFlt);
00037 MYTEST(testRegOf2);
00038 MYTEST(testBinaries);
00039 MYTEST(testUnaries);
00040 MYTEST(testIsAfpTerm);
00041 MYTEST(testCompare1);
00042 MYTEST(testCompare2);
00043 MYTEST(testCompare3);
00044 MYTEST(testCompare4);
00045 MYTEST(testCompare5);
00046 MYTEST(testCompare6);
00047 MYTEST(testSearchReplace1);
00048 MYTEST(testSearchReplace2);
00049 MYTEST(testSearchReplace3);
00050 MYTEST(testSearchReplace4);
00051 MYTEST(testSearch1);
00052 MYTEST(testSearch2);
00053 MYTEST(testSearch3);
00054 MYTEST(testSearchAll);
00055 MYTEST(testAccumulate);
00056 MYTEST(testPartitionTerms);
00057 MYTEST(testSimplifyArith);
00058 MYTEST(testSimplifyUnary);
00059 MYTEST(testSimplifyBinary);
00060 MYTEST(testSimplifyAddr);
00061 MYTEST(testSimpConstr);
00062
00063 MYTEST(testLess);
00064 MYTEST(testMapOfExp);
00065 MYTEST(testList);
00066 MYTEST(testParen);
00067 MYTEST(testFixSuccessor);
00068 MYTEST(testKillFill);
00069 MYTEST(testAssociativity);
00070 MYTEST(testSubscriptVar);
00071 MYTEST(testTypeOf);
00072 MYTEST(testSetConscripts);
00073 MYTEST(testAddUsedLocs);
00074 MYTEST(testSubscriptVars);
00075 MYTEST(testVisitors);
00076 }
00077
00078 int ExpTest::countTestCases () const
00079 { return 2; }
00080
00081
00082
00083
00084
00085
00086
00087
00088 void ExpTest::setUp () {
00089 m_99 = new Const(99);
00090 m_rof2 = new Location(opRegOf, new Const(2), NULL);
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100 void ExpTest::tearDown () {
00101 delete m_99;
00102 delete m_rof2;
00103 }
00104
00105
00106
00107
00108
00109 void ExpTest::test99 () {
00110 std::ostringstream ost;
00111 m_99->print(ost);
00112 CPPUNIT_ASSERT (std::string("99") == std::string(ost.str()));
00113 }
00114
00115
00116
00117 void ExpTest::testFlt () {
00118 std::ostringstream ost;
00119 Const *c = new Const(3.14);
00120 c->print(ost);
00121 CPPUNIT_ASSERT_EQUAL (std::string("3.1400"), std::string(ost.str()));
00122 delete c;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131 void ExpTest::testRegOf2 () {
00132 std::ostringstream ost;
00133 ost << m_rof2;
00134 CPPUNIT_ASSERT_EQUAL (std::string("r2"), std::string(ost.str()));
00135 }
00136
00137
00138
00139
00140
00141 void ExpTest::testBinaries () {
00142 std::ostringstream ost1;
00143 Binary* b = new Binary(opPlus, m_99->clone(), m_rof2->clone());
00144 b->print(ost1);
00145 CPPUNIT_ASSERT_EQUAL (std::string("99 + r2"), std::string(ost1.str()));
00146 delete b;
00147
00148 std::ostringstream ost2;
00149 b = new Binary(opMinus, m_99->clone(), m_rof2->clone());
00150 b->print(ost2);
00151 CPPUNIT_ASSERT_EQUAL (std::string("99 - r2"), std::string(ost2.str()));
00152 delete b;
00153
00154 std::ostringstream ost3;
00155 b = new Binary(opMult, m_99->clone(), m_rof2->clone());
00156 b->print(ost3);
00157 CPPUNIT_ASSERT_EQUAL (std::string("99 * r2"), std::string(ost3.str()));
00158 delete b;
00159
00160 std::ostringstream ost4;
00161 b = new Binary(opDiv, m_99->clone(), m_rof2->clone());
00162 b->print(ost4);
00163 CPPUNIT_ASSERT_EQUAL (std::string("99 / r2"), std::string(ost4.str()));
00164 delete b;
00165
00166 std::ostringstream ost5;
00167 b = new Binary(opMults, m_99->clone(), m_rof2->clone());
00168 b->print(ost5);
00169 CPPUNIT_ASSERT_EQUAL (std::string("99 *! r2"), std::string(ost5.str()));
00170 delete b;
00171
00172 std::ostringstream ost6;
00173 b = new Binary(opDivs, m_99->clone(), m_rof2->clone());
00174 b->print(ost6);
00175 CPPUNIT_ASSERT_EQUAL (std::string("99 /! r2"), std::string(ost6.str()));
00176 delete b;
00177
00178 std::ostringstream ost7;
00179 b = new Binary(opMod, m_99->clone(), m_rof2->clone());
00180 b->print(ost7);
00181 CPPUNIT_ASSERT_EQUAL (std::string("99 % r2"), std::string(ost7.str()));
00182 delete b;
00183
00184 std::ostringstream ost8;
00185 b = new Binary(opMods, m_99->clone(), m_rof2->clone());
00186 b->print(ost8);
00187 CPPUNIT_ASSERT_EQUAL (std::string("99 %! r2"), std::string(ost8.str()));
00188 delete b;
00189 }
00190
00191
00192
00193
00194
00195 void ExpTest::testUnaries () {
00196 std::ostringstream ost1;
00197 Unary* u = new Unary(opNot, new Terminal(opZF));
00198 u->print(ost1);
00199 CPPUNIT_ASSERT_EQUAL (std::string("~%ZF"), std::string(ost1.str()));
00200 delete u;
00201
00202 std::ostringstream ost2;
00203 u = new Unary(opLNot, new Terminal(opCF));
00204 u->print(ost2);
00205 CPPUNIT_ASSERT_EQUAL (std::string("L~%CF"), std::string(ost2.str()));
00206 delete u;
00207
00208 std::ostringstream ost3;
00209 u = new Unary(opNeg, m_rof2->clone());
00210 u->print(ost3);
00211 CPPUNIT_ASSERT_EQUAL (std::string("-r2"), std::string(ost3.str()));
00212 delete u;
00213
00214 }
00215
00216
00217
00218
00219 void ExpTest::testIsAfpTerm () {
00220 Terminal afp(opAFP);
00221 Binary plus(opPlus, afp.clone(), new Const(-99));
00222 Binary minus(opMinus, afp.clone(), m_99->clone());
00223 CPPUNIT_ASSERT( afp. isAfpTerm());
00224 CPPUNIT_ASSERT( plus. isAfpTerm());
00225 CPPUNIT_ASSERT( minus.isAfpTerm());
00226 CPPUNIT_ASSERT(!m_99 ->isAfpTerm());
00227 CPPUNIT_ASSERT(!m_rof2->isAfpTerm());
00228
00229 TypedExp tafp(new IntegerType(), afp.clone());
00230
00231 Unary tplus (opTypedExp, plus.clone());
00232 Unary tminus(opTypedExp, minus.clone());
00233 CPPUNIT_ASSERT(tafp. isAfpTerm());
00234 CPPUNIT_ASSERT(tplus. isAfpTerm());
00235 CPPUNIT_ASSERT(tminus.isAfpTerm());
00236 }
00237
00238
00239
00240
00241
00242 void ExpTest::testCompare1 () {
00243 CPPUNIT_ASSERT(! (*m_99 == *m_rof2));
00244 }
00245 void ExpTest::testCompare2 () {
00246 Const nineNine(99);
00247 CPPUNIT_ASSERT(*m_99 == nineNine);
00248 }
00249 void ExpTest::testCompare3 () {
00250 Const minus(-99);
00251 CPPUNIT_ASSERT(! (*m_99 == minus));
00252 }
00253 void ExpTest::testCompare4 () {
00254 Location regOf2(opRegOf, new Const(2), NULL);
00255 CPPUNIT_ASSERT(regOf2 == *m_rof2);
00256 }
00257 void ExpTest::testCompare5 () {
00258 Binary one(opMult, m_99->clone(), m_rof2->clone());
00259 Binary two(opMult, m_rof2->clone(), m_99->clone());
00260 CPPUNIT_ASSERT(! (one == two) );
00261 }
00262 void ExpTest::testCompare6 () {
00263 Binary one(opMult, m_99->clone(), m_rof2->clone());
00264 Binary two(opMult, m_99->clone(), m_rof2->clone());
00265 CPPUNIT_ASSERT( (one == two) );
00266 }
00267
00268
00269
00270
00271
00272 void ExpTest::testSearchReplace1() {
00273
00274 Exp* p; bool change;
00275 p = new Ternary(opAt, m_rof2->clone(), new Const(15), new Const(8));
00276 p = p->searchReplace(m_99, m_rof2, change);
00277 std::string expected("r2@15:8");
00278 std::ostringstream ost;
00279 p->print(ost);
00280 std::string actual(ost.str());
00281 CPPUNIT_ASSERT_EQUAL(expected, actual);
00282 Ternary t2(*(Ternary*)p);
00283 CPPUNIT_ASSERT (*p == t2);
00284 p = p->searchReplaceAll(m_99, m_rof2, change);
00285 CPPUNIT_ASSERT (*p == t2);
00286 delete p;
00287 }
00288
00289 void ExpTest::testSearchReplace2() {
00290
00291 bool change;
00292 Exp* p1 = new Const (55);
00293 Const p2(*(Const*)p1);
00294 Const c2(1234);
00295 p1 = p1->searchReplace(&p2, &c2, change);
00296 CPPUNIT_ASSERT(*p1 == c2);
00297 CPPUNIT_ASSERT(p1 != &c2);
00298 p1 = p1->searchReplace(&c2, m_rof2, change);
00299 CPPUNIT_ASSERT(*p1 == *m_rof2);
00300 delete p1;
00301 }
00302
00303 void ExpTest::testSearchReplace3() {
00304
00305 bool change;
00306 Const two(2);
00307 Const three(3);
00308 Exp* p = m_rof2->clone();
00309 p = p->searchReplaceAll(&two, &three, change);
00310 std::string expected("r3");
00311 std::ostringstream ost;
00312 p->print(ost);
00313 std::string actual(ost.str());
00314 CPPUNIT_ASSERT_EQUAL(expected, actual);
00315 delete p;
00316 }
00317 void ExpTest::testSearchReplace4() {
00318
00319 bool change;
00320 Const two(2);
00321 Exp* p = m_rof2->clone();
00322
00323
00324 p = p->searchReplaceAll(&two, m_rof2, change);
00325 std::string expected("r[r2]");
00326 std::ostringstream ost;
00327 p->print(ost);
00328 std::string actual(ost.str());
00329 CPPUNIT_ASSERT_EQUAL(expected, actual);
00330 delete p;
00331 }
00332
00333
00334
00335
00336
00337 void ExpTest::testSearch1() {
00338 Const two(2);
00339 Exp* result;
00340
00341 CPPUNIT_ASSERT(m_rof2->search(&two, result));
00342 CPPUNIT_ASSERT(*result == two);
00343
00344
00345 CPPUNIT_ASSERT(! m_99->search(&two, result));
00346 CPPUNIT_ASSERT(! m_rof2->search(m_99, result));
00347
00348
00349 Binary e(opMult, m_rof2->clone(), m_99->clone());
00350 Const three(3);
00351 CPPUNIT_ASSERT(! e.search(&three, result));
00352 }
00353
00354 void ExpTest::testSearch2() {
00355
00356 Binary e(opDivs, m_rof2->clone(), m_99->clone());
00357 Exp* result;
00358 Location search(opRegOf, new Terminal(opWild), NULL);
00359 CPPUNIT_ASSERT(e.search(&search, result));
00360 CPPUNIT_ASSERT(*result == *m_rof2);
00361
00362 Const three(3);
00363 CPPUNIT_ASSERT(! e.search(&three, result));
00364 CPPUNIT_ASSERT(e.search(m_99, result));
00365 }
00366
00367 void ExpTest::testSearch3() {
00368
00369
00370 Exp* result;
00371 Binary e(opPlus, new Binary(opMult, m_rof2->clone(), m_99->clone()),
00372 new Binary(opMult,
00373 Location::memOf(new Const(1000)),
00374 new Const(4)));
00375 Const four(4);
00376 Location mem1000(opMemOf, new Const(1000), NULL);
00377 Binary prod(opMult, m_rof2->clone(), m_99->clone());
00378 CPPUNIT_ASSERT(e.search(&four, result));
00379 CPPUNIT_ASSERT(e.search(&mem1000,result));
00380 CPPUNIT_ASSERT(e.search(&prod, result));
00381 CPPUNIT_ASSERT(e.search(m_99, result));
00382 Const three(3);
00383 CPPUNIT_ASSERT(! e.search(&three, result));
00384 }
00385
00386 void ExpTest::testSearchAll() {
00387
00388
00389 Location search(opRegOf, new Terminal(opWild), NULL);
00390 std::list<Exp*> result;
00391 Binary e(opPlus, new Binary(opMult, m_rof2->clone(), m_99->clone()),
00392 new Binary(opMult,
00393 Location::regOf(8),
00394 new Const(4)));
00395 CPPUNIT_ASSERT(e.searchAll(&search, result));
00396 CPPUNIT_ASSERT(result.size() == 2);
00397 CPPUNIT_ASSERT(*result.front() == *m_rof2);
00398 Location rof8(opRegOf, new Const(8), NULL);
00399 CPPUNIT_ASSERT(*result.back() == rof8);
00400 }
00401
00402
00403
00404
00405 void ExpTest::testAccumulate () {
00406 Location rof2(opRegOf, new Const(2), NULL);
00407 Const nineNine(99);
00408
00409 std::list<Exp*> le;
00410 Exp* res = Exp::Accumulate(le);
00411 Const zero(0);
00412 CPPUNIT_ASSERT(*res == zero);
00413 delete res;
00414
00415
00416 le.push_back(&rof2);
00417 res = Exp::Accumulate(le);
00418 CPPUNIT_ASSERT(*res == rof2);
00419 delete res;
00420
00421
00422 Exp* nn = nineNine.clone();
00423 le.push_back(nn);
00424 res = Exp::Accumulate(le);
00425 Binary expected2(opPlus, rof2.clone(), nineNine.clone());
00426 CPPUNIT_ASSERT(*res == expected2);
00427 delete res;
00428
00429
00430 le.push_back(&nineNine);
00431 res = Exp::Accumulate(le);
00432 Binary expected3(opPlus, rof2.clone(),
00433 new Binary(opPlus, nineNine.clone(), nineNine.clone()));
00434 CPPUNIT_ASSERT(*res == expected3);
00435 delete res;
00436
00437
00438 Terminal afp(opAFP);
00439 le.push_back(&afp);
00440 res = Exp::Accumulate(le);
00441 Binary expected4(opPlus, rof2.clone(),
00442 new Binary(opPlus, nineNine.clone(),
00443 new Binary(opPlus, nineNine.clone(), new Terminal(opAFP))));
00444 CPPUNIT_ASSERT(*res == expected4);
00445 delete res;
00446 delete nn;
00447 }
00448
00449
00450
00451
00452
00453 void ExpTest::testPartitionTerms() {
00454 std::ostringstream ost;
00455
00456 Binary e(opMinus,
00457 new Binary(opPlus,
00458 new Binary(opPlus, new Terminal(opAFP), new Const(108)),
00459 new Unary(opVar, new Const("n"))),
00460 new Binary(opPlus, new Terminal(opAFP), new Const(92))
00461 );
00462 std::list<Exp*> positives, negatives;
00463 std::vector<int> integers;
00464 e.partitionTerms(positives, negatives, integers, false);
00465 Exp* res = Exp::Accumulate(positives);
00466 Binary expected1(opPlus, new Terminal(opAFP),
00467 new Unary(opVar, new Const("n")));
00468 CPPUNIT_ASSERT(*res == expected1);
00469 delete res;
00470
00471 res = Exp::Accumulate(negatives);
00472 Terminal expected2(opAFP);
00473 CPPUNIT_ASSERT(*res == expected2);
00474 int size = integers.size();
00475 CPPUNIT_ASSERT_EQUAL(2, size);
00476 CPPUNIT_ASSERT_EQUAL(108, integers.front());
00477 CPPUNIT_ASSERT_EQUAL(-92, integers.back());
00478 delete res;
00479 }
00480
00481
00482
00483
00484
00485 void ExpTest::testSimplifyArith() {
00486 std::ostringstream ost;
00487
00488 Exp* e = new Binary(opMinus,
00489 new Binary(opPlus,
00490 new Binary(opPlus, new Terminal(opAFP), new Const(108)),
00491 new Unary(opVar, new Const("n"))),
00492 new Binary(opPlus, new Terminal(opAFP), new Const(92))
00493 );
00494 e = e->simplifyArith();
00495 e->print(ost);
00496 std::string expected ("v[n] + 16");
00497 CPPUNIT_ASSERT_EQUAL(expected, std::string(ost.str()));
00498 delete e;
00499
00500
00501 Exp* mm = Location::memOf(
00502 new Binary(opPlus,
00503 new Binary(opPlus,
00504 Location::regOf(28),
00505 new Const(-4)),
00506 new Const(8)));
00507 mm = mm->simplifyArith();
00508 std::ostringstream ost2;
00509 mm->print(ost2);
00510 expected = "m[r28 + 4]";
00511 CPPUNIT_ASSERT_EQUAL(expected, std::string(ost2.str()));
00512 delete mm;
00513
00514
00515 mm = new Binary(opPlus,
00516 Location::regOf(24),
00517 Location::memOf(
00518 new Binary(opMinus,
00519 new Binary(opMinus,
00520 Location::regOf(28),
00521 new Const(4)),
00522 new Const(4))));
00523 mm = mm->simplifyArith();
00524 std::ostringstream ost3;
00525 mm->print(ost3);
00526 expected = "r24 + m[r28 - 8]";
00527 CPPUNIT_ASSERT_EQUAL(expected, std::string(ost3.str()));
00528 delete mm;
00529 }
00530
00531
00532
00533
00534
00535 void ExpTest::testSimplifyUnary() {
00536
00537 Exp* u = new Unary(opNeg, new Const (55));
00538 u = u->simplify();
00539 Const minus55(-55);
00540 CPPUNIT_ASSERT(*u == minus55);
00541 delete u;
00542
00543 u = new Unary(opNot, new Const(0x55AA));
00544 u = u->simplify();
00545 Const exp((int)0xFFFFAA55);
00546 CPPUNIT_ASSERT(*u == exp);
00547 delete u;
00548
00549 u = new Unary(opLNot, new Const(55));
00550 u = u->simplify();
00551 Const zero(0);
00552 CPPUNIT_ASSERT(*u == zero);
00553 delete u;
00554
00555 u = new Unary(opLNot, zero.clone());
00556 u = u->simplify();
00557 Const one(1);
00558 CPPUNIT_ASSERT(*u == one);
00559 delete u;
00560
00561
00562 u = new Unary(opNeg, new Unary(opVar, new Const("abc")));
00563 Unary abc(opNeg, new Unary(opVar, new Const("abc")));
00564 CPPUNIT_ASSERT(*u == abc);
00565 delete u;
00566 }
00567
00568
00569
00570
00571
00572 void ExpTest::testSimplifyBinary() {
00573
00574 Exp* b = new Binary(opPlus, new Const(2), new Const(3));
00575 b = b->simplify();
00576 Const five(5);
00577 CPPUNIT_ASSERT(*b == five);
00578 delete b;
00579
00580
00581 b = new Binary(opMult, new Const(2), new Const(3));
00582 b = b->simplify();
00583 Const six(6);
00584 CPPUNIT_ASSERT(*b == six);
00585 delete b;
00586
00587
00588 b = new Binary(opShiftL, new Const(2), new Const(3));
00589 b = b->simplify();
00590 Const sixteen(16);
00591 CPPUNIT_ASSERT(*b == sixteen);
00592 delete b;
00593
00594
00595 b = new Binary(opShiftRA, new Const(-144), new Const(3));
00596 b = b->simplify();
00597 Const minus18(-18);
00598 CPPUNIT_ASSERT(*b == minus18);
00599 delete b;
00600
00601
00602 b = new Binary(opBitXor, new Const(0x55), new Const(0xF));
00603 b = b->simplify();
00604 Const fiveA(0x5A);
00605 CPPUNIT_ASSERT(*b == fiveA);
00606 delete b;
00607
00608
00609 b = new Binary(opBitXor, m_rof2->clone(), m_rof2->clone());
00610 b = b->simplify();
00611 Const zero(0);
00612 CPPUNIT_ASSERT(*b == zero);
00613 delete b;
00614
00615
00616
00617 b = new Binary(opMults, new Const(77), m_rof2->clone());
00618 b = b->simplify();
00619
00620 Binary exp(opMults, m_rof2->clone(), new Const(77));
00621 CPPUNIT_ASSERT(*b == exp);
00622
00623
00624 ((Const*)b->getSubExp2())->setInt(1);
00625 b = b->simplify();
00626 CPPUNIT_ASSERT(*b == *m_rof2);
00627 delete b;
00628
00629
00630 b = new Binary(opBitOr, new Const(0), m_rof2->clone());
00631 b = b->simplify();
00632 CPPUNIT_ASSERT(*b == *m_rof2);
00633 delete b;
00634
00635
00636 b = new Binary(opShiftL, m_rof2->clone(), new Const(0));
00637 b = b->simplify();
00638 CPPUNIT_ASSERT(*b == *m_rof2);
00639 delete b;
00640
00641 b = new Binary(opShiftL, m_rof2->clone(), new Const(2));
00642 b = b->simplify();
00643 Binary expb1(opMult, m_rof2->clone(), new Const(4));
00644 CPPUNIT_ASSERT(*b == expb1);
00645 delete b;
00646
00647
00648
00649 b = new Binary(opPlus, m_rof2->clone(), new Const(-99));
00650
00651 Exp* expb2 = new Binary(opMinus, m_rof2->clone(), new Const(99));
00652
00653
00654
00655 #define OLD_WAY 1
00656 #if OLD_WAY
00657 b = b->simplify();
00658 #else
00659 expb2 = expb2->simplify();
00660 #endif
00661 CPPUNIT_ASSERT(*b == *expb2);
00662 delete b; delete expb2;
00663
00664 std::string expected("((0 + v[a]) - 0) | 0");
00665 std::ostringstream ost;
00666 Exp* e =
00667 new Binary(opBitOr,
00668 new Binary(opMinus,
00669 new Binary(opPlus,
00670 new Const(0),
00671 new Unary(opVar,
00672 new Const("a")
00673 )
00674 ),
00675 new Const(0)
00676 ),
00677 new Const(0)
00678 );
00679 e->print(ost);
00680 CPPUNIT_ASSERT_EQUAL(expected, std::string(ost.str()));
00681
00682 e = e->simplify();
00683 Unary a(opVar, new Const("a"));
00684 expected = "v[a]";
00685 std::ostringstream ost2;
00686 e->print(ost2);
00687 CPPUNIT_ASSERT_EQUAL(expected, ost2.str());
00688 delete e;
00689
00690
00691 Assign* as = new Assign(
00692 Location::regOf(27),
00693 Location::memOf(
00694 new Binary(opPlus,
00695 Location::regOf(29),
00696 new Const(-4))));
00697 as->simplify();
00698 expected = " 0 *v* r27 := m[r29 - 4]";
00699 std::ostringstream ost3;
00700 as->print(ost3);
00701 CPPUNIT_ASSERT_EQUAL(expected, ost3.str());
00702 delete as;
00703
00704
00705 e = new Binary(opOr,
00706 new Binary(opAnd,
00707 new Terminal(opFalse),
00708 new Terminal(opTrue)),
00709 new Binary(opEquals,
00710 new Unary(opTypeOf, Location::regOf(24)),
00711 new TypeVal(new IntegerType(32, 1))));
00712 e = e->simplify();
00713 expected = "T[r24] = <int>";
00714 std::ostringstream ost4;
00715 e->print(ost4);
00716 CPPUNIT_ASSERT_EQUAL(expected, ost4.str());
00717 delete e;
00718 }
00719
00720
00721
00722
00723
00724 void ExpTest::testSimplifyAddr() {
00725
00726 Exp* e = new Binary(opMinus,
00727 new Unary(opAddrOf,
00728 Location::memOf(
00729 new Const(1000))),
00730 new Ternary(opAt,
00731 new Unary(opAddrOf,
00732 new Binary(opSize,
00733 new Const(64),
00734 Location::memOf(
00735 Location::regOf(2)
00736 ))),
00737 new Const(0),
00738 new Const(15)));
00739 e = e->simplifyAddr();
00740 std::ostringstream ost;
00741 e->print(ost);
00742 std::string actual(ost.str());
00743 std::string expected("1000 - (r2@0:15)");
00744 CPPUNIT_ASSERT_EQUAL(expected, actual);
00745
00746
00747 delete e;
00748 e = new Unary(opAddrOf,
00749 Location::memOf(
00750 new Const(1000)));
00751 expected = "1000";
00752 e = e->simplifyAddr();
00753 std::ostringstream ost2;
00754 e->print(ost2);
00755 actual = ost2.str();
00756 CPPUNIT_ASSERT_EQUAL(expected, actual);
00757 delete e;
00758
00759 }
00760
00761
00762
00763
00764
00765 void ExpTest::testSimpConstr() {
00766
00767
00768
00769
00770
00771
00772 Exp* e = new Binary(opOr,
00773 new Binary(opEquals,
00774 new TypeVal(new PointerType(new CharType())),
00775 new TypeVal(new IntegerType())),
00776 new Binary(opEquals,
00777 new TypeVal(new PointerType(new CharType())),
00778 new TypeVal(PointerType::newPtrAlpha())));
00779 e = e->simplifyConstraint();
00780 std::string expected("<char *> = <alpha0 *>");
00781 std::ostringstream ost;
00782 e->print(ost);
00783 std::string actual = ost.str();
00784 CPPUNIT_ASSERT_EQUAL(expected, actual);
00785 delete e;
00786
00787
00788
00789
00790
00791
00792
00793 e = new Binary(opAnd,
00794 new Binary(opEquals,
00795 new TypeVal(new PointerType(new CharType())),
00796 new TypeVal(new PointerType(new CharType()))),
00797 new Binary(opEquals,
00798 new Unary(opTypeOf, new Const(0x123456)),
00799 new TypeVal(new PointerType(new CharType()))));
00800 e = e->simplifyConstraint();
00801 expected = "T[0x123456] = <char *>";
00802 std::ostringstream ost2;
00803 e->print(ost2);
00804 actual = ost2.str();
00805 CPPUNIT_ASSERT_EQUAL(expected, actual);
00806 }
00807
00808
00809
00810
00811
00812 void ExpTest::testLess() {
00813
00814 Const two(2), three(3), mThree(-3), twoPointTwo(2.2), threePointThree(3.3);
00815 Const mThreePointThree(-3.3);
00816 CPPUNIT_ASSERT(two < three);
00817 CPPUNIT_ASSERT(mThree < two);
00818 CPPUNIT_ASSERT(twoPointTwo < threePointThree);
00819 CPPUNIT_ASSERT(mThreePointThree < twoPointTwo);
00820
00821 Terminal afp(opAFP), agp(opAGP);
00822 if (opAFP < opAGP)
00823 CPPUNIT_ASSERT(afp < agp);
00824 else
00825 CPPUNIT_ASSERT(agp < afp);
00826
00827 Unary negTwo(opNeg, new Const(2)), negThree(opNeg, new Const(3));
00828
00829 CPPUNIT_ASSERT(negTwo < negThree);
00830
00831 Binary twoByThr(opMult, new Const(2), new Const(3));
00832 Binary twoByFou(opMult, new Const(2), new Const(4));
00833 Binary thrByThr(opMult, new Const(3), new Const(3));
00834 CPPUNIT_ASSERT(twoByThr < twoByFou);
00835 CPPUNIT_ASSERT(twoByThr < thrByThr);
00836
00837 Ternary twoAtThrToFou(opAt, new Const(2), new Const(3), new Const(4));
00838 Ternary twoAtThrToFiv(opAt, new Const(2), new Const(3), new Const(5));
00839 CPPUNIT_ASSERT(twoAtThrToFou < twoAtThrToFiv);
00840
00841 }
00842
00843
00844
00845
00846 void ExpTest::testMapOfExp() {
00847 std::map<Exp*, int, lessExpStar> m;
00848 m[m_rof2] = 200;
00849 m[m_99] = 99;
00850 Exp* e = new Binary(opPlus, new Const(0),
00851 new Binary(opMinus,
00852 new Binary(opMult, new Const(2), new Const(3)),
00853 new Binary(opMult, new Const(4), new Const(5))));
00854 m[e] = -100;
00855 Location rof2(opRegOf, new Const(2), NULL);
00856 m[&rof2] = 2;
00857
00858 int i = m.size();
00859 CPPUNIT_ASSERT_EQUAL(3, i);
00860 i = m[m_rof2];
00861 CPPUNIT_ASSERT_EQUAL(2, i);
00862 i = m[&rof2];
00863 CPPUNIT_ASSERT_EQUAL(2, i);
00864 i = m[m_99];
00865 CPPUNIT_ASSERT_EQUAL(99, i);
00866 i = m[e];
00867 CPPUNIT_ASSERT_EQUAL(-100, i);
00868
00869 delete e;
00870 }
00871
00872
00873
00874
00875
00876 void ExpTest::testList () {
00877 std::ostringstream o0, o1, o2, o3, o4;
00878 Exp *l0, *l1, *l2, *l3, *l4;
00879
00880 l0 = new Binary(opList, new Terminal(opNil), new Terminal(opNil));
00881 o0 << l0;
00882 std::string expected0("");
00883 std::string actual0(o0.str());
00884 CPPUNIT_ASSERT_EQUAL(expected0, actual0);
00885 delete l0;
00886
00887
00888 l1 = new Binary(opList,
00889 new Location(opParam, new Const("a"), NULL),
00890 new Terminal(opNil));
00891 o1 << l1;
00892 std::string expected1("a");
00893 std::string actual1(o1.str());
00894 CPPUNIT_ASSERT_EQUAL(expected1, actual1);
00895 delete l1;
00896
00897
00898 l2 = new Binary(opList,
00899 new Location(opParam, new Const("a"), NULL),
00900 new Binary(opList,
00901 new Location(opParam, new Const("b"), NULL),
00902 new Terminal(opNil)));
00903 o2 << l2;
00904 std::string expected2("a, b");
00905 std::string actual2(o2.str());
00906 CPPUNIT_ASSERT_EQUAL(expected2, actual2);
00907 delete l2;
00908
00909
00910 l3 = new Binary(opList,
00911 new Location(opParam, new Const("a"), NULL),
00912 new Binary(opList,
00913 new Location(opParam, new Const("b"), NULL),
00914 new Binary(opList,
00915 new Location(opParam, new Const("c"), NULL),
00916 new Terminal(opNil))));
00917 o3 << l3;
00918 std::string expected3("a, b, c");
00919 std::string actual3(o3.str());
00920 CPPUNIT_ASSERT_EQUAL(expected3, actual3);
00921 delete l3;
00922
00923
00924 l4 = new Binary(opList,
00925 new Location(opParam, new Const("a"), NULL),
00926 new Binary(opList,
00927 new Location(opParam, new Const("b"), NULL),
00928 new Binary(opList,
00929 new Location(opParam, new Const("c"), NULL),
00930 new Binary(opList,
00931 new Location(opParam, new Const("d"), NULL),
00932 new Terminal(opNil)))));
00933 o4 << l4;
00934 std::string expected4("a, b, c, d");
00935 std::string actual4(o4.str());
00936 CPPUNIT_ASSERT_EQUAL(expected4, actual4);
00937 delete l4;
00938 }
00939
00940
00941
00942
00943
00944 void ExpTest::testParen () {
00945 Assign a(
00946 Location::regOf(
00947 new Location(opParam, new Const("rd"), NULL)),
00948 new Binary(opBitAnd,
00949 Location::regOf(
00950 new Location(opParam, new Const("rs1"), NULL)),
00951 new Binary(opMinus,
00952 new Binary(opMinus,
00953 new Const(0),
00954 new Location(opParam, new Const("reg_or_imm"), NULL)),
00955 new Const(1))));
00956 std::string expected(" 0 *v* r[rd] := r[rs1] & ((0 - reg_or_imm) - 1)");
00957 std::ostringstream o;
00958 a.print(o);
00959
00960 std::string actual(o.str());
00961 CPPUNIT_ASSERT_EQUAL(expected, actual);
00962 }
00963
00964
00965
00966
00967
00968 void ExpTest::testFixSuccessor() {
00969
00970 Binary* b = new Binary(opMinus,
00971 m_99->clone(),
00972 m_rof2->clone());
00973 std::ostringstream o1;
00974 Exp* e = b->fixSuccessor();
00975 e->print(o1);
00976 std::string expected("99 - r2");
00977 std::string actual(o1.str());
00978 CPPUNIT_ASSERT_EQUAL(expected, actual);
00979 delete e;
00980
00981 Unary* u = new Unary(opSuccessor,
00982 Location::regOf(2));
00983 std::ostringstream o2;
00984 e = u->fixSuccessor();
00985 e->print(o2);
00986 expected = "r3";
00987 actual = o2.str();
00988 CPPUNIT_ASSERT_EQUAL(expected, actual);
00989 delete e;
00990 }
00991
00992
00993
00994
00995
00996 void ExpTest::testKillFill() {
00997
00998 Binary e(opPlus,
00999 Location::regOf(18),
01000 new Ternary(opSgnEx, new Const(16), new Const(32),
01001 Location::memOf(
01002 new Binary(opPlus,
01003 Location::regOf(16),
01004 new Const(16)))));
01005 Exp* res = e.killFill();
01006 std::string expected("r18 + m[r16 + 16]");
01007 std::ostringstream ost1;
01008 res->print(ost1);
01009 std::string actual(ost1.str());
01010 CPPUNIT_ASSERT_EQUAL(expected, actual);
01011
01012
01013
01014 Ternary* e2 = new Ternary(opZfill, new Const(16), new Const(32),
01015 Location::memOf(
01016 new Binary(opPlus,
01017 Location::regOf(16),
01018 new Const(16))));
01019
01020 res = e2->killFill();
01021 expected = "m[r16 + 16]";
01022 std::ostringstream ost2;
01023 res->print(ost2);
01024 actual = ost2.str();
01025 CPPUNIT_ASSERT_EQUAL(expected, actual);
01026 delete res;
01027
01028 }
01029
01030
01031
01032
01033
01034 void ExpTest::testAssociativity() {
01035
01036
01037 Binary e1(opPlus,
01038 new Binary(opPlus,
01039 Location::regOf(8),
01040 Location::memOf(
01041 new Binary(opPlus,
01042 Location::memOf(
01043 new Binary(opPlus,
01044 Location::regOf(8),
01045 new Const(12))),
01046 new Const(-12)))),
01047 new Const(12));
01048
01049 Binary e2(opPlus,
01050 new Binary(opPlus,
01051 Location::regOf(8),
01052 new Const(12)),
01053 Location::memOf(
01054 new Binary(opPlus,
01055 Location::memOf(
01056 new Binary(opPlus,
01057 Location::regOf(8),
01058 new Const(12))),
01059 new Const(-12))));
01060
01061
01062 Exp* p1 = e1.simplify()->simplifyArith();
01063 Exp* p2 = e2.simplify()->simplifyArith();
01064 std::ostringstream os1, os2;
01065 p1->print(os1); p2->print(os2);
01066 std::string expected(os1.str());
01067 std::string actual (os2.str());
01068 CPPUNIT_ASSERT_EQUAL(expected, actual);
01069 }
01070
01071
01072
01073
01074
01075 void ExpTest::testSubscriptVar() {
01076
01077 Exp* left = Location::memOf(
01078 new Binary(opMinus,
01079 Location::regOf(28),
01080 new Const(4)));
01081 Assign* ae = new Assign(
01082 left->clone(),
01083 new Binary(opPlus,
01084 Location::regOf(28),
01085 Location::regOf(29)));
01086
01087 Statement* s = dynamic_cast<Statement*>(ae);
01088
01089 Exp* r28 = Location::regOf(28);
01090 Statement* def1 = dynamic_cast<Statement*>(new Assign(r28->clone(), r28->clone()));
01091 def1->setNumber(12);
01092 def1->subscriptVar(left, def1);
01093 std::string expected1;
01094 expected1 = " 0 *v* m[r28 - 4] := r28 + r29";
01095 std::ostringstream actual1;
01096 actual1 << s;
01097 CPPUNIT_ASSERT_EQUAL(expected1, actual1.str());
01098
01099
01100
01101 s->subscriptVar(r28, def1);
01102 std::string expected2(" 0 *v* m[r28{12} - 4] := r28{12} + r29");
01103 std::ostringstream actual2;
01104 actual2 << s;
01105 CPPUNIT_ASSERT_EQUAL(expected2, actual2.str());
01106
01107
01108
01109
01110 Statement* def3 = new Assign(Location::regOf(28), new Const(0));
01111 def3->setNumber(99);
01112 s->subscriptVar(r28, def3);
01113 std::string expected3(" 0 *v* m[r28{12} - 4] := r28{12} + r29");
01114 std::ostringstream actual3;
01115 actual3 << s;
01116 CPPUNIT_ASSERT_EQUAL(expected3, actual3.str());
01117
01118 delete ae; delete def1; delete def3; delete r28; delete left;
01119 }
01120
01121
01122
01123
01124
01125 void ExpTest::testTypeOf() {
01126
01127 std::string expected1("T[r24{5}] = T[r25{9}]");
01128 Statement* s5 = new Assign;
01129 Statement* s9 = new Assign;
01130 s5->setNumber(5);
01131 s9->setNumber(9);
01132 Exp* e = new Binary(opEquals,
01133 new Unary(opTypeOf,
01134 new RefExp(Location::regOf(24), s5)),
01135 new Unary(opTypeOf,
01136 new RefExp(Location::regOf(25), s9)));
01137 std::ostringstream actual1;
01138 actual1 << e;
01139 CPPUNIT_ASSERT_EQUAL(expected1, actual1.str());
01140
01141
01142 std::string expected2("T[r24{5}] = <float>");
01143 delete e;
01144 Type* t = new FloatType(32);
01145 e = new Binary(opEquals,
01146 new Unary(opTypeOf,
01147 new RefExp(Location::regOf(24), s5)),
01148 new TypeVal(t));
01149 std::ostringstream actual2;
01150 actual2 << e;
01151 CPPUNIT_ASSERT_EQUAL(expected2, actual2.str());
01152 }
01153
01154
01155
01156
01157 void ExpTest::testSetConscripts() {
01158
01159 Exp* e = new Binary(opPlus,
01160 Location::memOf(
01161 new Const(1000), NULL),
01162 new Const(1000));
01163 e->setConscripts(0, false);
01164 std::string expected("m[1000\\1\\] + 1000\\2\\");
01165 std::ostringstream actual;
01166 actual << e;
01167 CPPUNIT_ASSERT_EQUAL(expected, actual.str());
01168
01169
01170 e->setConscripts(0, true);
01171 expected = "m[1000] + 1000";
01172 std::ostringstream actual1;
01173 actual1 << e;
01174 CPPUNIT_ASSERT_EQUAL(expected, actual1.str());
01175
01176
01177 e = Location::memOf(
01178 new Binary(opPlus,
01179 Location::regOf(28),
01180 new Const(1000)));
01181 e->setConscripts(0, false);
01182 expected = "m[r28 + 1000\\1\\]";
01183 std::ostringstream act2;
01184 act2 << e;
01185 CPPUNIT_ASSERT_EQUAL(expected, act2.str());
01186
01187
01188 e->setConscripts(0, true);
01189 expected = "m[r28 + 1000]";
01190 std::ostringstream act3;
01191 act3 << e;
01192 CPPUNIT_ASSERT_EQUAL(expected, act3.str());
01193 }
01194
01195
01196
01197
01198
01199 void ExpTest::testAddUsedLocs() {
01200
01201 Exp* e = new Terminal(opNil);
01202 LocationSet l;
01203 e->addUsedLocs(l);
01204 CPPUNIT_ASSERT(l.size() == 0);
01205
01206
01207 e = new Const("foo");
01208 e->addUsedLocs(l);
01209 CPPUNIT_ASSERT(l.size() == 0);
01210
01211
01212 e = new Terminal(opPC);
01213 e->addUsedLocs(l);
01214 std::string expected = "%pc";
01215 std::ostringstream ost1;
01216 l.print(ost1);
01217 std::string actual = ost1.str();
01218 CPPUNIT_ASSERT_EQUAL(expected, actual);
01219
01220
01221 l.clear();
01222 e = Location::regOf(28);
01223 e->addUsedLocs(l);
01224 expected = "r28";
01225 std::ostringstream ost2;
01226 l.print(ost2);
01227 actual = ost2.str();
01228 CPPUNIT_ASSERT_EQUAL(expected, actual);
01229
01230
01231 l.clear();
01232 e = Location::memOf(
01233 new Binary(opMinus,
01234 Location::regOf(28),
01235 new Const(4)));
01236 e->addUsedLocs(l);
01237 expected = "r28,\tm[r28 - 4]";
01238 std::ostringstream ost3;
01239 l.print(ost3);
01240 actual = ost3.str();
01241 CPPUNIT_ASSERT_EQUAL(expected, actual);
01242
01243
01244 l.clear();
01245 e = new Unary(opAddrOf, e);
01246 e->addUsedLocs(l);
01247 expected = "r28,\tm[r28 - 4]";
01248 std::ostringstream ost4;
01249 l.print(ost4);
01250 actual = ost4.str();
01251 CPPUNIT_ASSERT_EQUAL(expected, actual);
01252
01253
01254 l.clear();
01255 e = new Binary(opPlus,
01256 Location::regOf(24),
01257 Location::regOf(25));
01258 e->addUsedLocs(l);
01259 expected = "r24,\tr25";
01260 std::ostringstream ost5;
01261 l.print(ost5);
01262 actual = ost5.str();
01263 CPPUNIT_ASSERT_EQUAL(expected, actual);
01264
01265
01266 l.clear();
01267 e = new Ternary(opAt,
01268 Location::regOf(24),
01269 Location::regOf(25),
01270 Location::regOf(26));
01271 e->addUsedLocs(l);
01272 expected = "r24,\tr25,\tr26";
01273 std::ostringstream ost6;
01274 l.print(ost6);
01275 actual = ost6.str();
01276 CPPUNIT_ASSERT_EQUAL(expected, actual);
01277
01278
01279 l.clear();
01280 Assign a(e, e);
01281 a.setNumber(2);
01282 e = new RefExp(Location::regOf(28), &a);
01283 e->addUsedLocs(l);
01284 expected = "r28{2}";
01285 std::ostringstream ost7;
01286 l.print(ost7);
01287 actual = ost7.str();
01288 CPPUNIT_ASSERT_EQUAL(expected, actual);
01289
01290
01291 Assign t(e, e);
01292 t.setNumber(3);
01293 e = new RefExp(
01294 Location::memOf(
01295 new Binary(opMinus,
01296 new RefExp(
01297 Location::regOf(28), &a),
01298 new Const(4))), &t);
01299 e->addUsedLocs(l);
01300 expected = "r28{2},\tm[r28{2} - 4]{3}";
01301 std::ostringstream ost8;
01302 l.print(ost8);
01303 actual = ost8.str();
01304 CPPUNIT_ASSERT_EQUAL(expected, actual);
01305
01306 }
01307
01308
01309
01310
01311
01312 void ExpTest::testSubscriptVars() {
01313
01314 Assign s9(new Terminal(opNil), new Terminal(opNil));
01315 s9.setNumber(9);
01316 Exp* search = Location::regOf(28);
01317 Exp* e = new Terminal(opPC);
01318 e = e->expSubscriptVar(search, &s9);
01319 std::string expected("%pc");
01320 std::ostringstream ost1;
01321 ost1 << e;
01322 std::string actual = ost1.str();
01323 CPPUNIT_ASSERT_EQUAL(expected, actual);
01324
01325
01326 e = search->clone();
01327 e = e->expSubscriptVar(search, &s9);
01328 expected = "r28{9}";
01329 std::ostringstream ost2;
01330 ost2 << e;
01331 actual = ost2.str();
01332 CPPUNIT_ASSERT_EQUAL(expected, actual);
01333
01334
01335 e = Location::tempOf(new Const("tmp1"));
01336 e = e->expSubscriptVar(e->clone(), &s9);
01337 expected = "tmp1{9}";
01338 std::ostringstream ost3;
01339 ost3 << e;
01340 actual = ost3.str();
01341 CPPUNIT_ASSERT_EQUAL(expected, actual);
01342
01343
01344 e = new Binary(opPlus,
01345 Location::memOf(Location::regOf(28)),
01346 Location::regOf(28));
01347 e = e->expSubscriptVar(search, &s9);
01348 expected = "m[r28{9}] + r28{9}";
01349 std::ostringstream ost4;
01350 ost4 << e;
01351 actual = ost4.str();
01352 CPPUNIT_ASSERT_EQUAL(expected, actual);
01353
01354
01355
01356 Assign s7(new Terminal(opNil), new Terminal(opNil));
01357 s7.setNumber(7);
01358 e = new RefExp(search->clone(), &s7);
01359 e = e->expSubscriptVar(search, &s9);
01360 expected = "r28{7}";
01361 std::ostringstream ost5;
01362 ost5 << e;
01363 actual = ost5.str();
01364 CPPUNIT_ASSERT_EQUAL(expected, actual);
01365
01366
01367 Assign s8(new Terminal(opNil), new Terminal(opNil));
01368 s8.setNumber(8);
01369 e = new RefExp(
01370 Location::memOf(
01371 new Binary(opPlus,
01372 new RefExp(
01373 Location::regOf(28), &s7),
01374 new Const(4))), &s8);
01375 e = e->expSubscriptVar(search, &s9);
01376 expected = "m[r28{7} + 4]{8}";
01377 std::ostringstream ost6;
01378 ost6 << e;
01379 actual = ost6.str();
01380 CPPUNIT_ASSERT_EQUAL(expected, actual);
01381
01382
01383
01384 e = new RefExp(Location::regOf(24), &s7);
01385 e = e->expSubscriptVar(e->clone(), NULL);
01386 expected = "r24{7}";
01387 std::ostringstream ost7;
01388 ost7 << e;
01389 actual = ost7.str();
01390 CPPUNIT_ASSERT_EQUAL(expected, actual);
01391
01392
01393 }
01394
01395
01396
01397
01398
01399 void ExpTest::testVisitors() {
01400 Assign s7(new Terminal(opNil), new Terminal(opNil));
01401
01402 s7.setNumber(7);
01403 FlagsFinder ff;
01404 Exp* e1 = new RefExp(
01405 Location::memOf(
01406 new Binary(opFlagCall,
01407 new Const("SETFFLAGS"),
01408 new Binary(opList,
01409 Location::memOf(
01410 new Const(0x1000)),
01411 new Binary(opList,
01412 Location::regOf(8),
01413 new Terminal(opNil))))),
01414 &s7);
01415
01416
01417 Exp* e2 = Location::memOf(new Const(0x2000));
01418
01419
01420 Exp* e3 = new Binary(opPlus,
01421 Location::regOf(1),
01422 new Binary(opMult,
01423 new RefExp(
01424 Location::memOf(new Const(1000)),
01425 &s7),
01426 new Const(4)));
01427
01428 int res = e1->containsFlags();
01429 CPPUNIT_ASSERT_EQUAL(1, res);
01430 res = e2->containsFlags();
01431 CPPUNIT_ASSERT_EQUAL(0, res);
01432 res = e3->containsFlags();
01433 CPPUNIT_ASSERT_EQUAL(0, res);
01434
01435 #if 0 // No longer used
01436 res = e1->containsBareMemof();
01437 CPPUNIT_ASSERT_EQUAL(1, res);
01438 res = e2->containsBareMemof();
01439 CPPUNIT_ASSERT_EQUAL(1, res);
01440 res = e3->containsBareMemof();
01441 CPPUNIT_ASSERT_EQUAL(0, res);
01442 #endif
01443 }
01444