RtlTest.cpp

Go to the documentation of this file.
00001 /*==============================================================================
00002  * FILE:       RtlTest.cc
00003  * OVERVIEW:   Provides the implementation for the RtlTest class, which
00004  *              tests the RTL and derived classes
00005  *============================================================================*/
00006 /*
00007  * $Revision: 1.22 $
00008  *
00009  * 13 May 02 - Mike: Created
00010  */
00011 
00012 #include "RtlTest.h"
00013 #include "statement.h"
00014 #include "exp.h"
00015 #include <sstream>
00016 #include "BinaryFile.h"
00017 #include "frontend.h"
00018 #include "sparcfrontend.h"
00019 #include "pentiumfrontend.h"
00020 #include "decoder.h"
00021 #include "proc.h"
00022 #include "prog.h"
00023 #include "visitor.h"
00024 
00025 #define SWITCH_SPARC        "test/sparc/switch_cc"
00026 #define SWITCH_PENT         "test/pentium/switch_cc"
00027 
00028 /*==============================================================================
00029  * FUNCTION:        RtlTest::registerTests
00030  * OVERVIEW:        Register the test functions in the given suite
00031  * PARAMETERS:      Pointer to the test suite
00032  * RETURNS:         <nothing>
00033  *============================================================================*/
00034 #define MYTEST(name) \
00035 suite->addTest(new CppUnit::TestCaller<RtlTest> ("RtlTest", \
00036     &RtlTest::name, *this))
00037 
00038 void RtlTest::registerTests(CppUnit::TestSuite* suite) {
00039     MYTEST(testAppend);
00040     MYTEST(testClone);
00041     MYTEST(testVisitor);
00042     MYTEST(testIsCompare);
00043     MYTEST(testSetConscripts);
00044 }
00045 
00046 int RtlTest::countTestCases () const
00047 { return 2; }   // ? What's this for?
00048 
00049 /*==============================================================================
00050  * FUNCTION:        RtlTest::setUp
00051  * OVERVIEW:        Set up some expressions for use with all the tests
00052  * NOTE:            Called before any tests
00053  * PARAMETERS:      <none>
00054  * RETURNS:         <nothing>
00055  *============================================================================*/
00056 void RtlTest::setUp () {
00057 }
00058 
00059 /*==============================================================================
00060  * FUNCTION:        RtlTest::tearDown
00061  * OVERVIEW:        Delete expressions created in setUp
00062  * NOTE:            Called after all tests
00063  * PARAMETERS:      <none>
00064  * RETURNS:         <nothing>
00065  *============================================================================*/
00066 void RtlTest::tearDown () {
00067 }
00068 
00069 /*==============================================================================
00070  * FUNCTION:        RtlTest::testAppend
00071  * OVERVIEW:        Test appendExp and printing of RTLs
00072  *============================================================================*/
00073 void RtlTest::testAppend () {
00074     Assign* a = new Assign(
00075             Location::regOf(8),
00076             new Binary(opPlus,
00077                 Location::regOf(9),
00078                 new Const(99)));
00079     RTL r;
00080     r.appendStmt(a);
00081     std::ostringstream ost;
00082     r.print(ost);
00083     std::string actual(ost.str());
00084     std::string expected("00000000    0 *v* r8 := r9 + 99\n");
00085     CPPUNIT_ASSERT_EQUAL(expected, actual);
00086     // No! appendExp does not copy the expression, so deleting the RTL will
00087     // delete the expression(s) in it.
00088     // Not sure if that's what we want...
00089     // delete a;
00090 }
00091 
00092 /*==============================================================================
00093  * FUNCTION:        RtlTest::testClone
00094  * OVERVIEW:        Test constructor from list of expressions; cloning of RTLs
00095  *============================================================================*/
00096 void RtlTest::testClone () {
00097     Assign* a1 = new Assign(
00098             Location::regOf(8),
00099             new Binary(opPlus,
00100                 Location::regOf(9),
00101                 new Const(99)));
00102     Assign* a2 = new Assign(new IntegerType(16),
00103             new Location(opParam, new Const("x"), NULL),
00104             new Location(opParam, new Const("y"), NULL));
00105     std::list<Statement*> ls;
00106     ls.push_back(a1);
00107     ls.push_back(a2);
00108     RTL* r = new RTL(0x1234, &ls);
00109     RTL* r2 = r->clone();
00110     std::ostringstream o1, o2;
00111     r->print(o1);
00112     delete r;           // And r2 should still stand!
00113     r2->print(o2);
00114     delete r2;
00115     std::string expected("00001234    0 *v* r8 := r9 + 99\n"
00116                          "            0 *j16* x := y\n");
00117 
00118     std::string act1(o1.str());
00119     std::string act2(o2.str());
00120     CPPUNIT_ASSERT_EQUAL(expected, act1);
00121     CPPUNIT_ASSERT_EQUAL(expected, act2);
00122 }
00123 
00124 /*==============================================================================
00125  * FUNCTION:        RtlTest::testVisitor
00126  * OVERVIEW:        Test the accept function for correct visiting behaviour.
00127  * NOTES:           Stub class to test.
00128  *============================================================================*/
00129 
00130 class StmtVisitorStub : public StmtVisitor {
00131 public:
00132     bool a, b, c, d, e, f, g, h; 
00133 
00134     void clear() { a = b = c = d = e = f = g = h = false; }
00135     StmtVisitorStub() { clear(); }
00136     virtual ~StmtVisitorStub() { }
00137     virtual bool visit(            RTL *s) { a = true; return false; }
00138     virtual bool visit(  GotoStatement *s) { b = true; return false; }
00139     virtual bool visit(BranchStatement *s) { c = true; return false; }
00140     virtual bool visit(  CaseStatement *s) { d = true; return false; }
00141     virtual bool visit(  CallStatement *s) { e = true; return false; }
00142     virtual bool visit(ReturnStatement *s) { f = true; return false; }
00143     virtual bool visit(   BoolAssign *s) { g = true; return false; }
00144     virtual bool visit(         Assign *s) { h = true; return false; }
00145 };
00146 
00147 void RtlTest::testVisitor()
00148 {
00149     StmtVisitorStub* visitor = new StmtVisitorStub();
00150 
00151     /* rtl */
00152     RTL *rtl = new RTL();
00153     rtl->accept(visitor);
00154     CPPUNIT_ASSERT(visitor->a);
00155     delete rtl;
00156 
00157     /* jump stmt */
00158     GotoStatement *jump = new GotoStatement;
00159     jump->accept(visitor);
00160     CPPUNIT_ASSERT(visitor->b);
00161     delete jump;
00162 
00163     /* branch stmt */
00164     BranchStatement *jcond = new BranchStatement;
00165     jcond->accept(visitor);
00166     CPPUNIT_ASSERT(visitor->c);
00167     delete jcond;
00168 
00169     /* nway jump stmt */
00170     CaseStatement *nwayjump = new CaseStatement;
00171     nwayjump->accept(visitor);
00172     CPPUNIT_ASSERT(visitor->d);
00173     delete nwayjump;
00174 
00175     /* call stmt */
00176     CallStatement *call = new CallStatement;
00177     call->accept(visitor);
00178     CPPUNIT_ASSERT(visitor->e);
00179     delete call;
00180 
00181     /* return stmt */
00182     ReturnStatement *ret = new ReturnStatement;
00183     ret->accept(visitor);
00184     CPPUNIT_ASSERT(visitor->f);
00185     delete ret;
00186 
00187     /* "bool" assgn */
00188     BoolAssign *scond = new BoolAssign(0);
00189     scond->accept(visitor);
00190     CPPUNIT_ASSERT(visitor->g);
00191     delete scond;
00192 
00193     /* assignment stmt */
00194     Assign *as = new Assign;
00195     as->accept(visitor);
00196     CPPUNIT_ASSERT(visitor->h);
00197     delete as;
00198 
00199     /* polymorphic */
00200     Statement* s = new CallStatement;
00201     s->accept(visitor);
00202     CPPUNIT_ASSERT(visitor->e);
00203     delete s;
00204 
00205     /* cleanup */
00206     delete visitor;
00207 }
00208 
00209 /*==============================================================================
00210  * FUNCTION:        RtlTest::testIsCompare
00211  * OVERVIEW:        Test the isCompare function
00212  *============================================================================*/
00213 void RtlTest::testIsCompare () {
00214     BinaryFileFactory bff;
00215     BinaryFile *pBF = bff.Load(SWITCH_SPARC);
00216     CPPUNIT_ASSERT(pBF != 0);
00217     CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_SPARC);
00218     Prog* prog = new Prog;
00219     FrontEnd *pFE = new SparcFrontEnd(pBF, prog, &bff);
00220     prog->setFrontEnd(pFE);
00221 
00222     // Decode second instruction: "sub      %i0, 2, %o1"
00223     int iReg;
00224     Exp* eOperand = NULL;
00225     DecodeResult inst = pFE->decodeInstruction(0x10910);
00226     CPPUNIT_ASSERT(inst.rtl != NULL);
00227     CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == false);
00228     
00229     // Decode fifth instruction: "cmp       %o1, 5"
00230     inst = pFE->decodeInstruction(0x1091c);
00231     CPPUNIT_ASSERT(inst.rtl != NULL);
00232     CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == true);
00233     CPPUNIT_ASSERT_EQUAL(9, iReg);
00234     std::string expected("5");
00235     std::ostringstream ost1;
00236     eOperand->print(ost1);
00237     std::string actual(ost1.str());
00238     CPPUNIT_ASSERT_EQUAL(expected, actual);
00239 
00240     pBF->UnLoad();
00241     delete pBF;
00242     delete pFE;
00243     pBF = bff.Load(SWITCH_PENT);
00244     CPPUNIT_ASSERT(pBF != 0);
00245     CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_PENTIUM);
00246     pFE = new PentiumFrontEnd(pBF, prog, &bff);
00247     prog->setFrontEnd(pFE);
00248 
00249     // Decode fifth instruction: "cmp   $0x5,%eax"
00250     inst = pFE->decodeInstruction(0x80488fb);
00251     CPPUNIT_ASSERT(inst.rtl != NULL);
00252     CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == true);
00253     CPPUNIT_ASSERT_EQUAL(24, iReg);
00254     std::ostringstream ost2;
00255     eOperand->print(ost2);
00256     actual = ost2.str();
00257     CPPUNIT_ASSERT_EQUAL(expected, actual);
00258     
00259     // Decode instruction: "add     $0x4,%esp"
00260     inst = pFE->decodeInstruction(0x804890c);
00261     CPPUNIT_ASSERT(inst.rtl != NULL);
00262     CPPUNIT_ASSERT(inst.rtl->isCompare(iReg, eOperand) == false);
00263     pBF->UnLoad();
00264     delete pFE;
00265 }
00266 
00267 void RtlTest::testSetConscripts() {
00268     // m[1000] = m[1000] + 1000
00269     Statement* s1 = new Assign(
00270         Location::memOf(
00271             new Const(1000), 0),
00272         new Binary(opPlus,
00273         Location::memOf(
00274             new Const(1000), NULL),
00275         new Const(1000)));
00276     
00277     // "printf("max is %d", (local0 > 0) ? local0 : global1)
00278     CallStatement* s2 = new CallStatement();
00279     std::string name("printf");
00280     Proc* proc = new UserProc(new Prog(), name, 0x2000);    // Making a true LibProc is problematic
00281     s2->setDestProc(proc);
00282     s2->setCalleeReturn(new ReturnStatement);       // So it's not a childless call
00283     Exp* e1 = new Const("max is %d");
00284     Exp* e2 = new Ternary(opTern,
00285         new Binary(opGtr,
00286             Location::local("local0", NULL),
00287             new Const(0)),
00288         Location::local("local0", NULL),
00289         Location::global("global1", NULL));
00290     StatementList args;
00291     args.append(new Assign(Location::regOf(8), e1));
00292     args.append(new Assign(Location::regOf(9), e2));
00293     s2->setArguments(args);
00294 
00295     std::list<Statement*> list;
00296     list.push_back(s1);
00297     list.push_back(s2);
00298     RTL* rtl = new RTL(0x1000, &list);
00299     rtl->setConscripts(0, false);
00300     std::string expected(
00301         "00001000    0 *v* m[1000\\1\\] := m[1000\\2\\] + 1000\\3\\\n"
00302         "            0 CALL printf(\n"
00303         "                *v* r8 := \"max is %d\"\\4\\\n"
00304         "                *v* r9 := (local0 > 0\\5\\) ? local0 : global1\n"
00305         "              )\n"
00306         "              Reaching definitions: \n"
00307         "              Live variables: \n");
00308 
00309     std::ostringstream ost;
00310     rtl->print(ost);
00311     std::string actual = ost.str();
00312     CPPUNIT_ASSERT_EQUAL(expected, actual);
00313 }

Generated on Tue Sep 19 21:18:31 2006 for Boomerang by  doxygen 1.4.6