00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00030
00031
00032
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; }
00048
00049
00050
00051
00052
00053
00054
00055
00056 void RtlTest::setUp () {
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066 void RtlTest::tearDown () {
00067 }
00068
00069
00070
00071
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
00087
00088
00089
00090 }
00091
00092
00093
00094
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;
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
00126
00127
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
00152 RTL *rtl = new RTL();
00153 rtl->accept(visitor);
00154 CPPUNIT_ASSERT(visitor->a);
00155 delete rtl;
00156
00157
00158 GotoStatement *jump = new GotoStatement;
00159 jump->accept(visitor);
00160 CPPUNIT_ASSERT(visitor->b);
00161 delete jump;
00162
00163
00164 BranchStatement *jcond = new BranchStatement;
00165 jcond->accept(visitor);
00166 CPPUNIT_ASSERT(visitor->c);
00167 delete jcond;
00168
00169
00170 CaseStatement *nwayjump = new CaseStatement;
00171 nwayjump->accept(visitor);
00172 CPPUNIT_ASSERT(visitor->d);
00173 delete nwayjump;
00174
00175
00176 CallStatement *call = new CallStatement;
00177 call->accept(visitor);
00178 CPPUNIT_ASSERT(visitor->e);
00179 delete call;
00180
00181
00182 ReturnStatement *ret = new ReturnStatement;
00183 ret->accept(visitor);
00184 CPPUNIT_ASSERT(visitor->f);
00185 delete ret;
00186
00187
00188 BoolAssign *scond = new BoolAssign(0);
00189 scond->accept(visitor);
00190 CPPUNIT_ASSERT(visitor->g);
00191 delete scond;
00192
00193
00194 Assign *as = new Assign;
00195 as->accept(visitor);
00196 CPPUNIT_ASSERT(visitor->h);
00197 delete as;
00198
00199
00200 Statement* s = new CallStatement;
00201 s->accept(visitor);
00202 CPPUNIT_ASSERT(visitor->e);
00203 delete s;
00204
00205
00206 delete visitor;
00207 }
00208
00209
00210
00211
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
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
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
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
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
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
00278 CallStatement* s2 = new CallStatement();
00279 std::string name("printf");
00280 Proc* proc = new UserProc(new Prog(), name, 0x2000);
00281 s2->setDestProc(proc);
00282 s2->setCalleeReturn(new ReturnStatement);
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 }