FrontSparcTest.cpp

Go to the documentation of this file.
00001 /*==============================================================================
00002  * FILE:       FrontSparcTest.cc
00003  * OVERVIEW:   Provides the implementation for the FrontSparcTest class, which
00004  *              tests the sparc front end
00005  *============================================================================*/
00006 /*
00007  * $Revision: 1.28 $
00008  *
00009  * 05 Apr 02 - Mike: Created
00010  * 21 May 02 - Mike: Mods for gcc 3.1
00011  * 04 Dec 02 - Mike: Changed all r[0] to 0
00012  */
00013 
00014 #define HELLO_SPARC     "test/sparc/hello"
00015 #define BRANCH_SPARC    "test/sparc/branch"
00016 
00017 #include "types.h"
00018 #include "FrontSparcTest.h"
00019 #include "proc.h"
00020 #include "prog.h"
00021 #include "frontend.h"
00022 #include "sparcfrontend.h"
00023 #include "cfg.h"
00024 #include "BinaryFile.h"
00025 #include "BinaryFileStub.h"
00026 
00027 /*==============================================================================
00028  * FUNCTION:        FrontSparcTest::registerTests
00029  * OVERVIEW:        Register the test functions in the given suite
00030  * PARAMETERS:      Pointer to the test suite
00031  * RETURNS:         <nothing>
00032  *============================================================================*/
00033 #define MYTEST(name) \
00034 suite->addTest(new CppUnit::TestCaller<FrontSparcTest> ("FrontSparcTest", \
00035     &FrontSparcTest::name, *this))
00036 
00037 void FrontSparcTest::registerTests(CppUnit::TestSuite* suite) {
00038     MYTEST(test1);
00039     MYTEST(test2);
00040     MYTEST(test3);
00041     MYTEST(testBranch);
00042     MYTEST(testDelaySlot);
00043 }
00044 
00045 int FrontSparcTest::countTestCases () const
00046 { return 3; }   // ? What's this for?
00047 
00048 /*==============================================================================
00049  * FUNCTION:        FrontSparcTest::setUp
00050  * OVERVIEW:        Set up anything needed before all tests
00051  * NOTE:            Called before any tests
00052  * NOTE:            Also appears to be called before all tests!
00053  * PARAMETERS:      <none>
00054  * RETURNS:         <nothing>
00055  *============================================================================*/
00056 void FrontSparcTest::setUp () {
00057 }
00058 
00059 /*==============================================================================
00060  * FUNCTION:        FrontSparcTest::tearDown
00061  * OVERVIEW:        Delete objects created in setUp
00062  * NOTE:            Called after all tests
00063  * PARAMETERS:      <none>
00064  * RETURNS:         <nothing>
00065  *============================================================================*/
00066 void FrontSparcTest::tearDown () {
00067 }
00068 
00069 /*==============================================================================
00070  * FUNCTION:        FrontSparcTest::test1
00071  * OVERVIEW:        Test decoding some sparc instructions
00072  *============================================================================*/
00073 void FrontSparcTest::test1 () {
00074     std::ostringstream ost;
00075 
00076     BinaryFileFactory bff;
00077     BinaryFile *pBF = bff.Load(HELLO_SPARC);
00078     if (pBF == NULL)
00079         pBF = new BinaryFileStub();    // fallback on stub
00080     CPPUNIT_ASSERT(pBF != 0);
00081     CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_SPARC);
00082     Prog* prog = new Prog;
00083     FrontEnd *pFE = new SparcFrontEnd(pBF, prog, &bff);
00084     prog->setFrontEnd(pFE);
00085 
00086     bool gotMain;
00087     ADDRESS addr = pFE->getMainEntryPoint(gotMain);
00088     CPPUNIT_ASSERT (addr != NO_ADDRESS);
00089 
00090     // Decode first instruction
00091     DecodeResult inst = pFE->decodeInstruction(addr);
00092     CPPUNIT_ASSERT(inst.rtl != NULL);
00093     inst.rtl->print(ost);
00094     
00095     std::string expected(
00096         "00010684    0 *32* tmp := r14 - 112\n"
00097         "            0 *32* m[r14] := r16\n"
00098         "            0 *32* m[r14 + 4] := r17\n"
00099         "            0 *32* m[r14 + 8] := r18\n"
00100         "            0 *32* m[r14 + 12] := r19\n"
00101         "            0 *32* m[r14 + 16] := r20\n"
00102         "            0 *32* m[r14 + 20] := r21\n"
00103         "            0 *32* m[r14 + 24] := r22\n"
00104         "            0 *32* m[r14 + 28] := r23\n"
00105         "            0 *32* m[r14 + 32] := r24\n"
00106         "            0 *32* m[r14 + 36] := r25\n"
00107         "            0 *32* m[r14 + 40] := r26\n"
00108         "            0 *32* m[r14 + 44] := r27\n"
00109         "            0 *32* m[r14 + 48] := r28\n"
00110         "            0 *32* m[r14 + 52] := r29\n"
00111         "            0 *32* m[r14 + 56] := r30\n"
00112         "            0 *32* m[r14 + 60] := r31\n"
00113         "            0 *32* r24 := r8\n"
00114         "            0 *32* r25 := r9\n"
00115         "            0 *32* r26 := r10\n"
00116         "            0 *32* r27 := r11\n"
00117         "            0 *32* r28 := r12\n"
00118         "            0 *32* r29 := r13\n"
00119         "            0 *32* r30 := r14\n"
00120         "            0 *32* r31 := r15\n"
00121         "            0 *32* r14 := tmp\n");
00122     CPPUNIT_ASSERT_EQUAL(expected, std::string(ost.str()));
00123 
00124     std::ostringstream o2;
00125     addr += inst.numBytes;
00126     inst = pFE->decodeInstruction(addr);
00127     inst.rtl->print(o2);
00128     expected = std::string("00010688    0 *32* r8 := 0x10400\n");
00129     CPPUNIT_ASSERT_EQUAL(expected, std::string(o2.str()));
00130 
00131     std::ostringstream o3;
00132     addr += inst.numBytes;
00133     inst = pFE->decodeInstruction(addr);
00134     inst.rtl->print(o3);
00135     expected = std::string("0001068c    0 *32* r8 := r8 | 848\n");
00136     CPPUNIT_ASSERT_EQUAL(expected, std::string(o3.str()));
00137 
00138     delete pFE;
00139     //delete pBF;
00140 }
00141 
00142 void FrontSparcTest::test2() {
00143     DecodeResult inst;
00144     std::string expected;
00145 
00146     BinaryFileFactory bff;
00147     BinaryFile *pBF = bff.Load(HELLO_SPARC);
00148     if (pBF == NULL)
00149         pBF = new BinaryFileStub();    // fallback on stub
00150     CPPUNIT_ASSERT(pBF != 0);
00151     CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_SPARC);
00152     Prog* prog = new Prog;
00153     FrontEnd *pFE = new SparcFrontEnd(pBF, prog, &bff);
00154     prog->setFrontEnd(pFE);
00155 
00156     std::ostringstream o1;
00157     inst = pFE->decodeInstruction(0x10690);
00158     inst.rtl->print(o1);
00159     // This call is to out of range of the program's text limits (to the Program Linkage Table (PLT), calling printf)
00160     // This is quite normal.
00161     expected = std::string("00010690    0 CALL printf(\n"
00162         "              )\n"
00163         "              Reaching definitions: \n"
00164         "              Live variables: \n");
00165     CPPUNIT_ASSERT_EQUAL(expected, std::string(o1.str()));
00166 
00167     std::ostringstream o2;
00168     inst = pFE->decodeInstruction(0x10694);
00169     inst.rtl->print(o2);
00170     expected = std::string("00010694\n");
00171     CPPUNIT_ASSERT_EQUAL(expected, std::string(o2.str()));
00172 
00173     std::ostringstream o3;
00174     inst = pFE->decodeInstruction(0x10698);
00175     inst.rtl->print(o3);
00176     expected = std::string("00010698    0 *32* r8 := 0\n");
00177     CPPUNIT_ASSERT_EQUAL(expected, std::string(o3.str()));
00178 
00179     std::ostringstream o4;
00180     inst = pFE->decodeInstruction(0x1069c);
00181     inst.rtl->print(o4);
00182     expected = std::string("0001069c    0 *32* r24 := r8\n");
00183     CPPUNIT_ASSERT_EQUAL(expected, std::string(o4.str()));
00184 
00185     delete pFE;
00186     // delete pBF;
00187 }
00188 
00189 void FrontSparcTest::test3() {
00190     DecodeResult inst;
00191     std::string expected;
00192 
00193     BinaryFileFactory bff;
00194     BinaryFile *pBF = bff.Load(HELLO_SPARC);
00195     if (pBF == NULL)
00196         pBF = new BinaryFileStub();    // fallback on stub
00197     CPPUNIT_ASSERT(pBF != 0);
00198     CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_SPARC);
00199     Prog* prog = new Prog;
00200     FrontEnd *pFE = new SparcFrontEnd(pBF, prog, &bff);
00201     prog->setFrontEnd(pFE);
00202 
00203     std::ostringstream o1;
00204     inst = pFE->decodeInstruction(0x106a0);
00205     inst.rtl->print(o1);
00206     expected = std::string("000106a0\n");
00207     CPPUNIT_ASSERT_EQUAL(expected, std::string(o1.str()));
00208 
00209     std::ostringstream o2;
00210     inst = pFE->decodeInstruction(0x106a4);
00211     inst.rtl->print(o2);
00212     expected = std::string("000106a4    0 RET\n"
00213         "              Modifieds: \n"
00214         "              Reaching definitions: \n");
00215     CPPUNIT_ASSERT_EQUAL(expected, std::string(o2.str()));
00216 
00217     std::ostringstream o3;
00218     inst = pFE->decodeInstruction(0x106a8);
00219     inst.rtl->print(o3);
00220     expected = std::string(
00221         "000106a8    0 *32* tmp := 0\n"
00222         "            0 *32* r8 := r24\n"
00223         "            0 *32* r9 := r25\n"
00224         "            0 *32* r10 := r26\n"
00225         "            0 *32* r11 := r27\n"
00226         "            0 *32* r12 := r28\n"
00227         "            0 *32* r13 := r29\n"
00228         "            0 *32* r14 := r30\n"
00229         "            0 *32* r15 := r31\n"
00230         "            0 *32* r0 := tmp\n"
00231         "            0 *32* r16 := m[r14]\n"
00232         "            0 *32* r17 := m[r14 + 4]\n"
00233         "            0 *32* r18 := m[r14 + 8]\n"
00234         "            0 *32* r19 := m[r14 + 12]\n"
00235         "            0 *32* r20 := m[r14 + 16]\n"
00236         "            0 *32* r21 := m[r14 + 20]\n"
00237         "            0 *32* r22 := m[r14 + 24]\n"
00238         "            0 *32* r23 := m[r14 + 28]\n"
00239         "            0 *32* r24 := m[r14 + 32]\n"
00240         "            0 *32* r25 := m[r14 + 36]\n"
00241         "            0 *32* r26 := m[r14 + 40]\n"
00242         "            0 *32* r27 := m[r14 + 44]\n"
00243         "            0 *32* r28 := m[r14 + 48]\n"
00244         "            0 *32* r29 := m[r14 + 52]\n"
00245         "            0 *32* r30 := m[r14 + 56]\n"
00246         "            0 *32* r31 := m[r14 + 60]\n"
00247         "            0 *32* r0 := tmp\n");
00248     CPPUNIT_ASSERT_EQUAL(expected, std::string(o3.str()));
00249 
00250     delete pFE;
00251     // delete pBF;
00252 }
00253 
00254 void FrontSparcTest::testBranch() {
00255     DecodeResult inst;
00256     std::string expected;
00257 
00258     BinaryFileFactory bff;
00259     BinaryFile *pBF = bff.Load(BRANCH_SPARC);
00260     if (pBF == NULL)
00261         pBF = new BinaryFileStub();    // fallback on stub
00262     CPPUNIT_ASSERT(pBF != 0);
00263     CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_SPARC);
00264     Prog* prog = new Prog;
00265     FrontEnd *pFE = new SparcFrontEnd(pBF, prog, &bff);
00266     prog->setFrontEnd(pFE);
00267 
00268     // bne
00269     std::ostringstream o1;
00270     inst = pFE->decodeInstruction(0x10ab0);
00271     inst.rtl->print(o1);
00272     expected = std::string(
00273       "00010ab0    0 BRANCH 0x10ac8, condition not equals\n"
00274       "High level: %flags\n");
00275     CPPUNIT_ASSERT_EQUAL(expected, std::string(o1.str()));
00276 
00277     // bg
00278     std::ostringstream o2;
00279     inst = pFE->decodeInstruction(0x10af8);
00280     inst.rtl->print(o2);
00281     expected = std::string("00010af8    0 BRANCH 0x10b10, condition "
00282       "signed greater\n"
00283       "High level: %flags\n");
00284     CPPUNIT_ASSERT_EQUAL(expected, std::string(o2.str()));
00285 
00286     // bleu
00287     std::ostringstream o3;
00288     inst = pFE->decodeInstruction(0x10b44);
00289     inst.rtl->print(o3);
00290     expected = std::string(
00291         "00010b44    0 BRANCH 0x10b54, condition unsigned less or equals\n"
00292         "High level: %flags\n");
00293     CPPUNIT_ASSERT_EQUAL(expected, std::string(o3.str()));
00294 
00295     delete pFE;
00296     // delete pBF;
00297 }
00298 
00299 void FrontSparcTest::testDelaySlot() {
00300     
00301     BinaryFileFactory bff;
00302     BinaryFile *pBF = bff.Load(BRANCH_SPARC);
00303     if (pBF == NULL)
00304         pBF = new BinaryFileStub();    // fallback on stub
00305     CPPUNIT_ASSERT(pBF != 0);
00306     CPPUNIT_ASSERT(pBF->GetMachine() == MACHINE_SPARC);
00307     Prog* prog = new Prog;
00308     FrontEnd *pFE = new SparcFrontEnd(pBF, prog, &bff);
00309     prog->setFrontEnd(pFE);
00310     // decode calls readLibraryCatalog(), which needs to have definitions for non-sparc architectures cleared
00311     Type::clearNamedTypes();
00312     pFE->decode(prog);
00313 
00314     bool gotMain;
00315     ADDRESS addr = pFE->getMainEntryPoint(gotMain);
00316     CPPUNIT_ASSERT (addr != NO_ADDRESS);
00317 
00318     std::string name("testDelaySlot");
00319     UserProc* pProc = new UserProc(prog, name, addr);
00320     std::ofstream dummy;
00321     bool res = pFE->processProc(addr, pProc, dummy, false);
00322 
00323     CPPUNIT_ASSERT(res == 1);
00324     Cfg* cfg = pProc->getCFG();
00325     BB_IT it;
00326     PBB bb = cfg->getFirstBB(it);
00327     std::ostringstream o1;
00328     bb->print(o1);
00329     std::string expected("Call BB:\n"
00330         "00010a80    0 *32* tmp := r14 - 120\n"
00331         "            0 *32* m[r14] := r16\n"
00332         "            0 *32* m[r14 + 4] := r17\n"
00333         "            0 *32* m[r14 + 8] := r18\n"
00334         "            0 *32* m[r14 + 12] := r19\n"
00335         "            0 *32* m[r14 + 16] := r20\n"
00336         "            0 *32* m[r14 + 20] := r21\n"
00337         "            0 *32* m[r14 + 24] := r22\n"
00338         "            0 *32* m[r14 + 28] := r23\n"
00339         "            0 *32* m[r14 + 32] := r24\n"
00340         "            0 *32* m[r14 + 36] := r25\n"
00341         "            0 *32* m[r14 + 40] := r26\n"
00342         "            0 *32* m[r14 + 44] := r27\n"
00343         "            0 *32* m[r14 + 48] := r28\n"
00344         "            0 *32* m[r14 + 52] := r29\n"
00345         "            0 *32* m[r14 + 56] := r30\n"
00346         "            0 *32* m[r14 + 60] := r31\n"
00347         "            0 *32* r24 := r8\n"
00348         "            0 *32* r25 := r9\n"
00349         "            0 *32* r26 := r10\n"
00350         "            0 *32* r27 := r11\n"
00351         "            0 *32* r28 := r12\n"
00352         "            0 *32* r29 := r13\n"
00353         "            0 *32* r30 := r14\n"
00354         "            0 *32* r31 := r15\n"
00355         "            0 *32* r14 := tmp\n"
00356         "00010a84    0 *32* r16 := 0x11400\n"
00357         "00010a88    0 *32* r16 := r16 | 808\n"
00358         "00010a8c    0 *32* r8 := r16\n"
00359         "00010a90    0 *32* tmp := r30\n"
00360         "            0 *32* r9 := r30 - 20\n"
00361         "00010a90    0 CALL scanf(\n"
00362         "              )\n"
00363         "              Reaching definitions: \n"
00364         "              Live variables: \n");
00365 
00366     std::string actual(o1.str());
00367     CPPUNIT_ASSERT_EQUAL(expected, actual);
00368 
00369     bb = cfg->getNextBB(it);
00370     CPPUNIT_ASSERT(bb);
00371     std::ostringstream o2;
00372     bb->print(o2);
00373     expected = std::string("Call BB:\n"
00374         "00010a98    0 *32* r8 := r16\n"
00375         "00010a9c    0 *32* tmp := r30\n"
00376         "            0 *32* r9 := r30 - 24\n"
00377         "00010a9c    0 CALL scanf(\n"
00378         "              )\n"
00379         "              Reaching definitions: \n"
00380         "              Live variables: \n");
00381 
00382     actual = std::string(o2.str());
00383     CPPUNIT_ASSERT_EQUAL(expected, actual);
00384 
00385     bb = cfg->getNextBB(it);
00386     CPPUNIT_ASSERT(bb);
00387     std::ostringstream o3;
00388     bb->print(o3);
00389     expected = std::string("Twoway BB:\n"
00390     "00010aa4    0 *32* r8 := m[r30 - 20]\n"
00391     "00010aa8    0 *32* r16 := 5\n"
00392     "00010aac    0 *32* tmp := r16\n"
00393     "            0 *32* r0 := r16 - r8\n"
00394     "            0 *v* %flags := SUBFLAGS( tmp, r8, r0 )\n"
00395     "00010ab0    0 *32* r8 := 0x11400\n"
00396     "00010ab0    0 BRANCH 0x10ac8, condition not equals\n"
00397     "High level: %flags\n");
00398     actual = std::string(o3.str());
00399     CPPUNIT_ASSERT_EQUAL(expected, actual);
00400 
00401     bb = cfg->getNextBB(it);
00402     CPPUNIT_ASSERT(bb);
00403     std::ostringstream o4;
00404     bb->print(o4);
00405     expected = std::string("L1: Twoway BB:\n"
00406         "00010ac8    0 *32* r8 := 0x11400\n"
00407         "00010ac8    0 BRANCH 0x10ad8, condition equals\n"
00408         "High level: %flags\n");
00409     actual = std::string(o4.str());
00410     CPPUNIT_ASSERT_EQUAL(expected, actual);
00411 
00412     bb = cfg->getNextBB(it);
00413     CPPUNIT_ASSERT(bb);
00414     std::ostringstream o5;
00415     bb->print(o5);
00416     expected = std::string("Call BB:\n"
00417         "00010ab8    0 *32* r8 := r8 | 816\n"
00418         "00010ab8    0 CALL printf(\n"
00419         "              )\n"
00420         "              Reaching definitions: \n"
00421         "              Live variables: \n");
00422 
00423     actual = std::string(o5.str());
00424     CPPUNIT_ASSERT_EQUAL(expected, actual);
00425 
00426     delete prog;
00427 }

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