00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <assert.h>
00026 #if defined(_MSC_VER) && _MSC_VER <= 1200
00027 #pragma warning(disable:4786)
00028 #endif
00029 #if defined(_MSC_VER) && _MSC_VER >= 1400
00030 #pragma warning(disable:4996) // Warnings about e.g. _strdup deprecated in VS 2005
00031 #endif
00032
00033 #include "cfg.h"
00034 #include "statement.h"
00035 #include "exp.h"
00036 #include "proc.h"
00037 #include "prog.h"
00038 #include "hllcode.h"
00039 #include "chllcode.h"
00040 #include "signature.h"
00041 #include "boomerang.h"
00042 #include "type.h"
00043 #include "util.h"
00044 #include "log.h"
00045 #include <sstream>
00046
00047 extern char *operStrings[];
00048
00049
00050 CHLLCode::CHLLCode() : HLLCode()
00051 {
00052 }
00053
00054
00055 CHLLCode::CHLLCode(UserProc *p) : HLLCode(p)
00056 {
00057 }
00058
00059
00060 CHLLCode::~CHLLCode()
00061 {
00062 }
00063
00064
00065 void CHLLCode::indent(std::ostringstream& str, int indLevel) {
00066
00067 for (int i=0; i < indLevel; i++)
00068 str << " ";
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 static int progress = 0;
00082 void CHLLCode::appendExp(std::ostringstream& str, Exp *exp, PREC curPrec, bool uns ) {
00083 if (exp == NULL) return;
00084
00085 if (++progress > 500) {
00086 std::cerr << 'g' << std::flush;
00087 progress = 0;
00088 }
00089
00090 OPER op = exp->getOper();
00091
00092 #if SYMS_IN_BACK_END // Should no longer be any unmapped symbols by the back end
00093
00094 if (m_proc && !exp->isTypedExp()) {
00095 char* sym = m_proc->lookupSym(exp);
00096 if (sym) {
00097 str << sym;
00098 return;
00099 }
00100 }
00101 #endif
00102
00103 Const *c = (Const*)exp;
00104 Unary *u = (Unary*)exp;
00105 Binary *b = (Binary*)exp;
00106 Ternary *t = (Ternary*)exp;
00107
00108 switch(op) {
00109 case opIntConst: {
00110 int K = c->getInt();
00111 if (uns && K < 0) {
00112
00113 unsigned rem = (unsigned)K % 100;
00114 if (rem == 0 || rem == 99 || K > -128) {
00115
00116 char num[16];
00117 sprintf(num, "%u", K);
00118 str << num << "U";
00119 } else {
00120
00121 str << "0x" << std::hex << K;
00122 }
00123 } else {
00124 if (c->getType() && c->getType()->isChar()) {
00125 if (c->getInt() == '\a')
00126 str << "'\\a'";
00127 else if (c->getInt() == '\b')
00128 str << "'\\b'";
00129 else if (c->getInt() == '\f')
00130 str << "'\\f'";
00131 else if (c->getInt() == '\n')
00132 str << "'\\n'";
00133 else if (c->getInt() == '\r')
00134 str << "'\\r'";
00135 else if (c->getInt() == '\t')
00136 str << "'\\t'";
00137 else if (c->getInt() == '\v')
00138 str << "'\\v'";
00139 else if (c->getInt() == '\\')
00140 str << "'\\\\'";
00141 else if (c->getInt() == '\?')
00142 str << "'\\?'";
00143 else if (c->getInt() == '\'')
00144 str << "'\\''";
00145 else if (c->getInt() == '\"')
00146 str << "'\\\"'";
00147 else
00148 str << "'" << (char)c->getInt() << "'";
00149 } else {
00150
00151 int K = c->getInt();
00152 if (-2048 < K && K < 2048)
00153 str << std::dec << K;
00154 else
00155 str << "0x" << std::hex << K;
00156 }
00157 }
00158 break;
00159 }
00160 case opLongConst:
00161
00162 #if defined(_MSC_VER) && _MSC_VER <= 1200 // tamlin:
00163 if ((__int64)c->getLong() < -1000i64 || (__int64)c->getLong() > 1000i64)
00164 str << "0x" << std::hex << c->getLong() << std::dec << "i64";
00165 else
00166 str << std::dec << c->getLong() << "i64";
00167 #else
00168 if ((long long)c->getLong() < -1000LL || (long long)c->getLong() > 1000LL)
00169 str << "0x" << std::hex << c->getLong() << std::dec << "LL";
00170 else
00171 str << std::dec << c->getLong() << "LL";
00172 #endif
00173 break;
00174 case opFltConst: {
00175
00176 std::ostringstream ost;
00177 ost << c->getFlt();
00178 std::string s = ost.str();
00179 str << s;
00180 if (s.find('.') == std::string::npos)
00181 str << ".";
00182 break;
00183 }
00184 case opStrConst:
00185
00186 str << "\"" << escapeStr(c->getStr()) << "\"";
00187 break;
00188 case opFuncConst:
00189 str << c->getFuncName(); break;
00190 case opAddrOf: {
00191 Exp* sub = u->getSubExp1();
00192 #if 0 // Suspect only ADHOC TA
00193 if (sub->getType() && sub->getType()->isArray()) {
00194 appendExp(str, sub, curPrec);
00195 break;
00196 }
00197 #endif
00198 if (sub->isGlobal()) {
00199 Prog* prog = m_proc->getProg();
00200 Const* con = (Const*)((Unary*)sub)->getSubExp1();
00201 Type* gt = prog->getGlobalType(con->getStr());
00202 if (gt && (gt->isArray() || (gt->isPointer() && gt->asPointer()->getPointsTo()->isChar()))) {
00203
00204 appendExp(str, sub, curPrec);
00205 break;
00206 }
00207 }
00208 #if SYMS_IN_BACK_END
00209 if (sub->isMemOf() && m_proc->lookupSym(sub) == NULL) {
00210 #else
00211 if (sub->isMemOf()) {
00212 #endif
00213
00214
00215 appendExp(str, sub->getSubExp1(), PREC_UNARY);
00216 } else {
00217 openParen(str, curPrec, PREC_UNARY);
00218 str << "&";
00219 appendExp(str, sub, PREC_UNARY);
00220 closeParen(str, curPrec, PREC_UNARY);
00221 }
00222 break;
00223 }
00224 case opParam:
00225 case opGlobal:
00226 case opLocal:
00227 c = dynamic_cast<Const*>(u->getSubExp1());
00228 assert(c && c->getOper() == opStrConst);
00229 str << c->getStr();
00230 break;
00231 case opEquals:
00232 {
00233 openParen(str, curPrec, PREC_EQUAL);
00234 appendExp(str, b->getSubExp1(), PREC_EQUAL);
00235 str << " == ";
00236 #if 0 // Suspect only for ADHOC TA
00237 Type *ty = b->getSubExp1()->getType();
00238 if (ty && ty->isPointer() && b->getSubExp2()->isIntConst() && ((Const*)b->getSubExp2())->getInt() == 0)
00239 str << "NULL";
00240 else
00241 #endif
00242 appendExp(str, b->getSubExp2(), PREC_EQUAL);
00243 closeParen(str, curPrec, PREC_EQUAL);
00244 }
00245 break;
00246 case opNotEqual:
00247 {
00248 openParen(str, curPrec, PREC_EQUAL);
00249 appendExp(str, b->getSubExp1(), PREC_EQUAL);
00250 str << " != ";
00251 #if 0 // Suspect only for ADHOC_TA
00252 Type *ty = b->getSubExp1()->getType();
00253 if (ty && ty->isPointer() && b->getSubExp2()->isIntConst() && ((Const*)b->getSubExp2())->getInt() == 0)
00254 str << "NULL";
00255 else
00256 #endif
00257 appendExp(str, b->getSubExp2(), PREC_EQUAL);
00258 closeParen(str, curPrec, PREC_EQUAL);
00259 }
00260 break;
00261 case opLess:
00262 case opLessUns:
00263 openParen(str, curPrec, PREC_REL);
00264 appendExp(str, b->getSubExp1(), PREC_REL, op == opLessUns);
00265 str << " < ";
00266 appendExp(str, b->getSubExp2(), PREC_REL, op == opLessUns);
00267 closeParen(str, curPrec, PREC_REL);
00268 break;
00269 case opGtr:
00270 case opGtrUns:
00271 openParen(str, curPrec, PREC_REL);
00272 appendExp(str, b->getSubExp1(), PREC_REL, op == opGtrUns);
00273 str << " > ";
00274 appendExp(str, b->getSubExp2(), PREC_REL, op == opGtrUns);
00275 closeParen(str, curPrec, PREC_REL);
00276 break;
00277 case opLessEq:
00278 case opLessEqUns:
00279 openParen(str, curPrec, PREC_REL);
00280 appendExp(str, b->getSubExp1(), PREC_REL, op == opLessEqUns);
00281 str << " <= ";
00282 appendExp(str, b->getSubExp2(), PREC_REL, op == opLessEqUns);
00283 closeParen(str, curPrec, PREC_REL);
00284 break;
00285 case opGtrEq:
00286 case opGtrEqUns:
00287 openParen(str, curPrec, PREC_REL);
00288 appendExp(str, b->getSubExp1(), PREC_REL, op == opGtrEqUns);
00289 str << " >= ";
00290 appendExp(str, b->getSubExp2(), PREC_REL, op == opGtrEqUns);
00291 closeParen(str, curPrec, PREC_REL);
00292 break;
00293 case opAnd:
00294 openParen(str, curPrec, PREC_LOG_AND);
00295 appendExp(str, b->getSubExp1(), PREC_LOG_AND);
00296 str << " && ";
00297 appendExp(str, b->getSubExp2(), PREC_LOG_AND);
00298 closeParen(str, curPrec, PREC_LOG_AND);
00299 break;
00300 case opOr:
00301 openParen(str, curPrec, PREC_LOG_OR);
00302 appendExp(str, b->getSubExp1(), PREC_LOG_OR);
00303 str << " || ";
00304 appendExp(str, b->getSubExp2(), PREC_LOG_OR);
00305 closeParen(str, curPrec, PREC_LOG_OR);
00306 break;
00307 case opBitAnd:
00308 openParen(str, curPrec, PREC_BIT_AND);
00309 appendExp(str, b->getSubExp1(), PREC_BIT_AND);
00310 str << " & ";
00311 if (b->getSubExp2()->getOper() == opIntConst) {
00312
00313 str << "0x" << std::hex << ((Const*)b->getSubExp2())->getInt();
00314 } else {
00315 appendExp(str, b->getSubExp2(), PREC_BIT_AND);
00316 }
00317 closeParen(str, curPrec, PREC_BIT_AND);
00318 break;
00319 case opBitOr:
00320 openParen(str, curPrec, PREC_BIT_IOR);
00321 appendExp(str, b->getSubExp1(), PREC_BIT_IOR);
00322 str << " | ";
00323 appendExp(str, b->getSubExp2(), PREC_BIT_IOR);
00324 closeParen(str, curPrec, PREC_BIT_IOR);
00325 break;
00326 case opBitXor:
00327 openParen(str, curPrec, PREC_BIT_XOR);
00328 appendExp(str, b->getSubExp1(), PREC_BIT_XOR);
00329 str << " ^ ";
00330 appendExp(str, b->getSubExp2(), PREC_BIT_XOR);
00331 closeParen(str, curPrec, PREC_BIT_XOR);
00332 break;
00333 case opNot:
00334 openParen(str, curPrec, PREC_UNARY);
00335 str << " !";
00336 appendExp(str, u->getSubExp1(), PREC_UNARY);
00337 closeParen(str, curPrec, PREC_UNARY);
00338 break;
00339 case opLNot:
00340 openParen(str, curPrec, PREC_UNARY);
00341 appendExp(str, u->getSubExp1(), PREC_UNARY);
00342 closeParen(str, curPrec, PREC_UNARY);
00343 break;
00344 case opNeg:
00345 case opFNeg:
00346 openParen(str, curPrec, PREC_UNARY);
00347 appendExp(str, u->getSubExp1(), PREC_UNARY);
00348 closeParen(str, curPrec, PREC_UNARY);
00349 break;
00350 case opAt:
00351 {
00352
00353
00354 openParen(str, curPrec, PREC_BIT_AND);
00355 appendExp(str, t->getSubExp1(), PREC_BIT_SHIFT);
00356 Const* first = (Const*) t->getSubExp2();
00357 Const* last = (Const*) t->getSubExp3();
00358 str << " >> ";
00359 appendExp(str, last, PREC_BIT_SHIFT);
00360 str << " & ";
00361
00362 unsigned int mask = (1 << (first->getInt() - last->getInt() + 1)) - 1;
00363 if ( mask < 10)
00364
00365 str << mask;
00366 else {
00367 str << "0x" << std::hex << mask;
00368 }
00369 closeParen(str, curPrec, PREC_BIT_AND);
00370 break;
00371 }
00372 case opPlus:
00373 openParen(str, curPrec, PREC_ADD);
00374 appendExp(str, b->getSubExp1(), PREC_ADD);
00375 str << " + ";
00376 appendExp(str, b->getSubExp2(), PREC_ADD);
00377 closeParen(str, curPrec, PREC_ADD);
00378 break;
00379 case opMinus:
00380 openParen(str, curPrec, PREC_ADD);
00381 appendExp(str, b->getSubExp1(), PREC_ADD);
00382 str << " - ";
00383 appendExp(str, b->getSubExp2(), PREC_ADD);
00384 closeParen(str, curPrec, PREC_ADD);
00385 break;
00386 case opMemOf:
00387 if (Boomerang::get()->noDecompile) {
00388 str << "MEMOF(";
00389 appendExp(str, u->getSubExp1(), PREC_NONE);
00390 str << ")";
00391 break;
00392 }
00393 openParen(str, curPrec, PREC_UNARY);
00394
00395 str << "*";
00396 appendExp(str, u->getSubExp1(), PREC_UNARY);
00397 closeParen(str, curPrec, PREC_UNARY);
00398 break;
00399 case opRegOf:
00400 {
00401
00402 if (VERBOSE)
00403 LOG << "WARNING: CHLLCode::appendExp: case opRegOf is deprecated\n";
00404 if (u->getSubExp1()->getOper() == opTemp) {
00405
00406 str << "tmp";
00407 break;
00408 }
00409 assert(u->getSubExp1()->getOper() == opIntConst);
00410 const char *n = m_proc->getProg()->getRegName(
00411 ((Const*)u->getSubExp1())->getInt());
00412 if (n) {
00413 if (n[0] == '%')
00414 str << n+1;
00415 else
00416 str << n;
00417 } else {
00418
00419 str << "r[";
00420 appendExp(str, u->getSubExp1(), PREC_NONE);
00421 str << "]";
00422 }
00423 }
00424 break;
00425 case opTemp:
00426
00427 if (VERBOSE)
00428 LOG << "WARNING: CHLLCode::appendExp: case opTemp is deprecated\n";
00429
00430 str << ((Const*)u->getSubExp1())->getStr();
00431 break;
00432 case opItof:
00433
00434 str << "(float)";
00435 openParen(str, curPrec, PREC_UNARY);
00436 appendExp(str, t->getSubExp3(), PREC_UNARY);
00437 closeParen(str, curPrec, PREC_UNARY);
00438 break;
00439 case opFsize:
00440
00441 if (Boomerang::get()->noDecompile && t->getSubExp3()->isMemOf()) {
00442 assert(t->getSubExp1()->isIntConst());
00443 if (((Const*)t->getSubExp1())->getInt() == 32)
00444 str << "FLOAT_MEMOF(";
00445 else
00446 str << "DOUBLE_MEMOF(";
00447 appendExp(str, t->getSubExp3()->getSubExp1(), PREC_NONE);
00448 str << ")";
00449 break;
00450 }
00451 appendExp(str, t->getSubExp3(), curPrec);
00452 break;
00453 case opMult:
00454 case opMults:
00455 openParen(str, curPrec, PREC_MULT);
00456 appendExp(str, b->getSubExp1(), PREC_MULT);
00457 str << " * ";
00458 appendExp(str, b->getSubExp2(), PREC_MULT);
00459 closeParen(str, curPrec, PREC_MULT);
00460 break;
00461 case opDiv:
00462 case opDivs:
00463 openParen(str, curPrec, PREC_MULT);
00464 appendExp(str, b->getSubExp1(), PREC_MULT);
00465 str << " / ";
00466 appendExp(str, b->getSubExp2(), PREC_MULT);
00467 closeParen(str, curPrec, PREC_MULT);
00468 break;
00469 case opMod:
00470 case opMods:
00471 openParen(str, curPrec, PREC_MULT);
00472 appendExp(str, b->getSubExp1(), PREC_MULT);
00473 str << " % ";
00474 appendExp(str, b->getSubExp2(), PREC_MULT);
00475 closeParen(str, curPrec, PREC_MULT);
00476 break;
00477 case opShiftL:
00478 openParen(str, curPrec, PREC_BIT_SHIFT);
00479 appendExp(str, b->getSubExp1(), PREC_BIT_SHIFT);
00480 str << " << ";
00481 appendExp(str, b->getSubExp2(), PREC_BIT_SHIFT);
00482 closeParen(str, curPrec, PREC_BIT_SHIFT);
00483 break;
00484 case opShiftR:
00485 case opShiftRA:
00486 openParen(str, curPrec, PREC_BIT_SHIFT);
00487 appendExp(str, b->getSubExp1(), PREC_BIT_SHIFT);
00488 str << " >> ";
00489 appendExp(str, b->getSubExp2(), PREC_BIT_SHIFT);
00490 closeParen(str, curPrec, PREC_BIT_SHIFT);
00491 break;
00492 case opTern:
00493 openParen(str, curPrec, PREC_COND);
00494 str << " (";
00495 appendExp(str, t->getSubExp1(), PREC_NONE);
00496 str << ") ? ";
00497 appendExp(str, t->getSubExp2(), PREC_COND);
00498 str << " : ";
00499 appendExp(str, t->getSubExp3(), PREC_COND);
00500 closeParen(str, curPrec, PREC_COND);
00501 break;
00502 case opFPlus:
00503 case opFPlusd:
00504 case opFPlusq:
00505 openParen(str, curPrec, PREC_ADD);
00506 appendExp(str, b->getSubExp1(), PREC_ADD);
00507 str << " + ";
00508 appendExp(str, b->getSubExp2(), PREC_ADD);
00509 closeParen(str, curPrec, PREC_ADD);
00510 break;
00511 case opFMinus:
00512 case opFMinusd:
00513 case opFMinusq:
00514 openParen(str, curPrec, PREC_ADD);
00515 appendExp(str, b->getSubExp1(), PREC_ADD);
00516 str << " - ";
00517 appendExp(str, b->getSubExp2(), PREC_ADD);
00518 closeParen(str, curPrec, PREC_ADD);
00519 break;
00520 case opFMult:
00521 case opFMultd:
00522 case opFMultq:
00523 openParen(str, curPrec, PREC_MULT);
00524 appendExp(str, b->getSubExp1(), PREC_MULT);
00525 str << " * ";
00526 appendExp(str, b->getSubExp2(), PREC_MULT);
00527 closeParen(str, curPrec, PREC_MULT);
00528 break;
00529 case opFDiv:
00530 case opFDivd:
00531 case opFDivq:
00532 openParen(str, curPrec, PREC_MULT);
00533 appendExp(str, b->getSubExp1(), PREC_MULT);
00534 str << " / ";
00535 appendExp(str, b->getSubExp2(), PREC_MULT);
00536 closeParen(str, curPrec, PREC_MULT);
00537 break;
00538 case opFround:
00539
00540 str << "round(";
00541 appendExp(str, u->getSubExp1(), PREC_NONE);
00542 str << ")";
00543 break;
00544 case opFtrunc:
00545
00546 str << "trunc(";
00547 appendExp(str, u->getSubExp1(), PREC_NONE);
00548 str << ")";
00549 break;
00550 case opFabs:
00551 str << "fabs(";
00552 appendExp(str, u->getSubExp1(), PREC_NONE);
00553 str << ")";
00554 break;
00555 case opFtoi:
00556
00557 str << "(int)";
00558 appendExp(str, u->getSubExp3(), PREC_UNARY);
00559 break;
00560 case opRotateL:
00561 str << "ROTL(";
00562 appendExp(str, u->getSubExp1(), PREC_UNARY);
00563 str << ")";
00564 break;
00565 case opRotateR:
00566 str << "ROTR(";
00567 appendExp(str, u->getSubExp1(), PREC_UNARY);
00568 str << ")";
00569 break;
00570 case opRotateLC:
00571 str << "ROTLC(";
00572 appendExp(str, u->getSubExp1(), PREC_UNARY);
00573 str << ")";
00574 break;
00575 case opRotateRC:
00576 str << "ROTRC(";
00577 appendExp(str, u->getSubExp1(), PREC_UNARY);
00578 str << ")";
00579 break;
00580 case opSize:
00581 {
00582
00583
00584
00585 appendExp(str, b->getSubExp2(), PREC_UNARY);
00586 }
00587 break;
00588 case opFMultsd:
00589 case opFMultdq:
00590 case opSQRTs:
00591 case opSQRTd:
00592 case opSQRTq:
00593 case opSignExt:
00594 case opTargetInst:
00595 case opNamedExp:
00596 case opGuard:
00597 case opVar:
00598 case opArg:
00599 case opExpand:
00600 case opCastIntStar:
00601 case opPostVar:
00602 case opForceInt:
00603 case opForceFlt:
00604 case opFpush:
00605 case opFpop:
00606 case opLoge:
00607 case opSqrt:
00608 case opExecute:
00609 case opAFP:
00610 case opAGP:
00611
00612 LOG << "WARNING: CHLLCode::appendExp: case " << operStrings[exp->getOper()] << " not implemented\n";
00613
00614 break;
00615 case opFlagCall:
00616 {
00617 assert(b->getSubExp1()->getOper() == opStrConst);
00618 str << ((Const*)b->getSubExp1())->getStr();
00619 str << "(";
00620 Binary *l = (Binary*)b->getSubExp2();
00621 for (; l && l->getOper() == opList;
00622 l = (Binary*)l->getSubExp2()) {
00623 appendExp(str, l->getSubExp1(), PREC_NONE);
00624 if (l->getSubExp2()->getOper() == opList)
00625 str << ", ";
00626 }
00627 str << ")";
00628 }
00629 break;
00630 case opList:
00631 {
00632 int elems_on_line = 0;
00633 Exp* e2 = b->getSubExp2();
00634 str << "{ ";
00635 if (b->getSubExp1()->getOper() == opList)
00636 str << "\n ";
00637 while (e2->getOper() == opList)
00638 {
00639 appendExp(str, b->getSubExp1(), PREC_NONE, uns);
00640 ++elems_on_line;
00641 if (b->getSubExp1()->getOper() == opList || elems_on_line >= 16 )
00642 {
00643 str << ",\n ";
00644 elems_on_line = 0;
00645 } else {
00646 str << ", ";
00647 }
00648 b = static_cast<Binary*>(e2);
00649 e2 = b->getSubExp2();
00650 }
00651 appendExp(str, b->getSubExp1(), PREC_NONE, uns);
00652 str << " }";
00653 }
00654 break;
00655 case opFlags:
00656 str << "flags"; break;
00657 case opPC:
00658 str << "pc"; break;
00659 break;
00660 case opZfill:
00661
00662
00663
00664
00665
00666 if (t->getSubExp3()->isMemOf() &&
00667 t->getSubExp1()->isIntConst() &&
00668 t->getSubExp2()->isIntConst() &&
00669 ((Const*)t->getSubExp2())->getInt() == 32) {
00670 unsigned sz = (unsigned)((Const*)t->getSubExp1())->getInt();
00671 if (sz == 8 || sz == 16) {
00672 bool close = false;
00673 str << "*";
00674 #if 0 // Suspect ADHOC TA only
00675 Type *ty = t->getSubExp3()->getSubExp1()->getType();
00676 if (ty == NULL || !ty->isPointer() ||
00677 !ty->asPointer()->getPointsTo()->isInteger() ||
00678 ty->asPointer()->getPointsTo()->asInteger()->getSize() != sz) {
00679 #endif
00680 str << "(unsigned ";
00681 if (sz == 8)
00682 str << "char";
00683 else
00684 str << "short";
00685 str << "*)";
00686 openParen(str, curPrec, PREC_UNARY);
00687 close = true;
00688 #if 0 // ADHOC TA as above
00689 }
00690 #endif
00691 appendExp(str, t->getSubExp3()->getSubExp1(), PREC_UNARY);
00692 if (close)
00693 closeParen(str, curPrec, PREC_UNARY);
00694 break;
00695 }
00696 }
00697 if (VERBOSE)
00698 LOG << "WARNING: CHLLCode::appendExp: case opZfill is deprecated\n";
00699 str << "(";
00700 appendExp(str, t->getSubExp3(), PREC_NONE);
00701 str << ")";
00702 break;
00703
00704 case opTypedExp: {
00705 #if SYMS_IN_BACK_END
00706 Exp* b = u->getSubExp1();
00707 char* sym = m_proc->lookupSym(exp);
00708 if (sym) {
00709 str << "(";
00710 appendType(str, ((TypedExp*)u)->getType());
00711 str << ")" << sym;
00712 break;
00713 }
00714 #endif
00715 if (u->getSubExp1()->getOper() == opTypedExp &&
00716 *((TypedExp*)u)->getType() == *((TypedExp*)u->getSubExp1())->getType()) {
00717
00718 appendExp(str, u->getSubExp1(), curPrec);
00719 } else if (u->getSubExp1()->getOper() == opMemOf) {
00720
00721 #if 0
00722 PointerType *pty = dynamic_cast<PointerType*>(u->getSubExp1()->getSubExp1()->getType());
00723 #else
00724 PointerType* pty = NULL;
00725 #endif
00726
00727 Type *tt = ((TypedExp*)u)->getType();
00728 if (pty != NULL && (*pty->getPointsTo() == *tt ||
00729 (tt->isSize() && pty->getPointsTo()->getSize() == tt->getSize())))
00730 str << "*";
00731 else {
00732 if (Boomerang::get()->noDecompile) {
00733 if (tt && tt->isFloat()) {
00734 if (tt->asFloat()->getSize() == 32)
00735 str << "FLOAT_MEMOF";
00736 else
00737 str << "DOUBLE_MEMOF";
00738 } else
00739 str << "MEMOF";
00740 } else {
00741 str << "*(";
00742 appendType(str, tt);
00743 str << "*)";
00744 }
00745 }
00746 openParen(str, curPrec, PREC_UNARY);
00747
00748 appendExp(str, ((Location*)((TypedExp*)u)->getSubExp1())->getSubExp1(), PREC_UNARY);
00749 closeParen(str, curPrec, PREC_UNARY);
00750 } else {
00751
00752 Type* tt = ((TypedExp*)u)->getType();
00753 if (dynamic_cast<PointerType*>(tt)) {
00754 #if SYMS_IN_BACK_END
00755 char* sym = m_proc->lookupSym(Location::memOf(b));
00756 if (sym) {
00757 openParen(str, curPrec, PREC_UNARY);
00758 str << "&" << sym;
00759 closeParen(str, curPrec, PREC_UNARY);
00760 break;
00761 }
00762 #endif
00763 }
00764
00765 str << "(";
00766 appendType(str, tt);
00767 str << ")";
00768 openParen(str, curPrec, PREC_UNARY);
00769 appendExp(str, u->getSubExp1(), PREC_UNARY);
00770 closeParen(str, curPrec, PREC_UNARY);
00771 }
00772 break;
00773 }
00774 case opSgnEx:
00775 case opTruncs: {
00776 Exp* s = t->getSubExp3();
00777 int toSize = ((Const*)t->getSubExp2())->getInt();
00778 switch (toSize) {
00779 case 8: str << "(char) "; break;
00780 case 16: str << "(short) "; break;
00781 case 64: str << "(long long) "; break;
00782 default: str << "(int) "; break;
00783 }
00784 appendExp(str, s, curPrec);
00785 break;
00786 }
00787 case opTruncu: {
00788 Exp* s = t->getSubExp3();
00789 int toSize = ((Const*)t->getSubExp2())->getInt();
00790 switch (toSize) {
00791 case 8: str << "(unsigned char) "; break;
00792 case 16: str << "(unsigned short) "; break;
00793 case 64: str << "(unsigned long long) "; break;
00794 default: str << "(unsigned int) "; break;
00795 }
00796 appendExp(str, s, curPrec);
00797 break;
00798 }
00799 case opMachFtr: {
00800 str << "/* machine specific */ (int) ";
00801 Exp* sub = u->getSubExp1();
00802 assert(sub->isStrConst());
00803 char* s = ((Const*)sub)->getStr();
00804 if (s[0] == '%')
00805 str << s+1;
00806 else
00807 str << s;
00808 break;
00809 }
00810 case opFflags:
00811 str << "/* Fflags() */ "; break;
00812 case opPow:
00813 str << "pow(";
00814 appendExp(str, b->getSubExp1(), PREC_COMMA);
00815 str << ", ";
00816 appendExp(str, b->getSubExp2(), PREC_COMMA);
00817 str << ")";
00818 break;
00819 case opLog2:
00820 str << "log2(";
00821 appendExp(str, u->getSubExp1(), PREC_NONE);
00822 str << ")";
00823 break;
00824 case opLog10:
00825 str << "log10(";
00826 appendExp(str, u->getSubExp1(), PREC_NONE);
00827 str << ")";
00828 break;
00829 case opSin:
00830 str << "sin(";
00831 appendExp(str, u->getSubExp1(), PREC_NONE);
00832 str << ")";
00833 break;
00834 case opCos:
00835 str << "cos(";
00836 appendExp(str, u->getSubExp1(), PREC_NONE);
00837 str << ")";
00838 break;
00839 case opTan:
00840 str << "tan(";
00841 appendExp(str, u->getSubExp1(), PREC_NONE);
00842 str << ")";
00843 break;
00844 case opArcTan:
00845 str << "atan(";
00846 appendExp(str, u->getSubExp1(), PREC_NONE);
00847 str << ")";
00848 break;
00849 case opSubscript:
00850 appendExp(str, u->getSubExp1(), curPrec);
00851 if (VERBOSE)
00852 LOG << "ERROR: CHLLCode::appendExp: subscript in code generation of proc " <<
00853 m_proc->getName() << " exp (without subscript): " << str.str().c_str()
00854 << "\n";
00855
00856 break;
00857 case opMemberAccess:
00858 {
00859 #if 0 // ADHOC TA
00860 Type *ty = b->getSubExp1()->getType();
00861 #else
00862 Type* ty = NULL;
00863 #endif
00864 if (ty == NULL) {
00865 LOG << "type failure: no type for subexp1 of " << b << "\n";
00866
00867
00868
00869
00870 }
00871
00872
00873
00874
00875 if (b->getSubExp1()->getOper() == opMemOf) {
00876 appendExp(str, b->getSubExp1()->getSubExp1(), PREC_PRIM);
00877 str << "->";
00878 } else {
00879 appendExp(str, b->getSubExp1(), PREC_PRIM);
00880 str << ".";
00881 }
00882 str << ((Const*)b->getSubExp2())->getStr();
00883 }
00884 break;
00885 case opArrayIndex:
00886 openParen(str, curPrec, PREC_PRIM);
00887 if (b->getSubExp1()->isMemOf()) {
00888 #if 0
00889 Type *ty = b->getSubExp1()->getSubExp1()->getType();
00890 #else
00891 Type* ty = NULL;
00892 #endif
00893 if (ty && ty->resolvesToPointer() &&
00894 ty->asPointer()->getPointsTo()->resolvesToArray()) {
00895
00896 appendExp(str, b->getSubExp1()->getSubExp1(), PREC_PRIM);
00897 } else
00898 appendExp(str, b->getSubExp1(), PREC_PRIM);
00899 } else
00900 appendExp(str, b->getSubExp1(), PREC_PRIM);
00901 closeParen(str, curPrec, PREC_PRIM);
00902 str << "[";
00903 appendExp(str, b->getSubExp2(), PREC_PRIM);
00904 str << "]";
00905 break;
00906 case opDefineAll:
00907 str << "<all>";
00908 if (VERBOSE)
00909 LOG << "ERROR: should not see opDefineAll in codegen\n";
00910 break;
00911 default:
00912
00913 OPER op = exp->getOper();
00914 if (op >= opZF) {
00915
00916
00917 str << operStrings[op]+2;
00918 break;
00919 }
00920 LOG << "ERROR: CHLLCode::appendExp: case " << operStrings[op] << " not implemented\n";
00921
00922 }
00923
00924 }
00925
00926
00927 void CHLLCode::appendType(std::ostringstream& str, Type *typ)
00928 {
00929 if (typ == NULL) {
00930 str << "int";
00931 return;
00932 }
00933 if (typ->resolvesToPointer() &&
00934 typ->asPointer()->getPointsTo()->resolvesToArray()) {
00935
00936
00937
00938 typ = new PointerType(typ->asPointer()->getPointsTo()->asArray()->getBaseType());
00939 }
00940 str << typ->getCtype(true);
00941 }
00942
00943
00944
00945
00946 void CHLLCode::appendTypeIdent(std::ostringstream& str, Type *typ, const char *ident) {
00947 if (typ == NULL) return;
00948 if (typ->isPointer() && typ->asPointer()->getPointsTo()->isArray()) {
00949 appendType(str, typ->asPointer()->getPointsTo()->asArray()->getBaseType());
00950 str << " *" << ident;
00951 } else if (typ->isPointer()) {
00952 appendType(str, typ);
00953 str << ident;
00954 } else if (typ->isArray()) {
00955 ArrayType *a = typ->asArray();
00956 appendTypeIdent(str, a->getBaseType(), ident);
00957 str << "[";
00958 if (!a->isUnbounded())
00959 str << a->getLength();
00960 str << "]";
00961 } else if (typ->isVoid()) {
00962
00963 #if 1
00964 if (ident == NULL) {
00965 static const char szFoo[] = "unknownVoidType";
00966 ident = szFoo;
00967 }
00968 #endif
00969 LOG << "WARNING: CHLLCode::appendTypeIdent: declaring type void as int for " << ident << "\n";
00970 str << "int " << ident;
00971 } else {
00972 appendType(str, typ);
00973 str << " " << (ident ? ident : "<null>");
00974 }
00975 }
00976
00977
00978 void CHLLCode::reset() {
00979 lines.clear();
00980 }
00981
00982
00983 void CHLLCode::AddPretestedLoopHeader(int indLevel, Exp *cond) {
00984 std::ostringstream s;
00985 indent(s, indLevel);
00986 s << "while (";
00987 appendExp(s, cond, PREC_NONE);
00988 s << ") {";
00989
00990
00991
00992 appendLine(s);
00993 }
00994
00995
00996 void CHLLCode::AddPretestedLoopEnd(int indLevel) {
00997 std::ostringstream s;
00998 indent(s, indLevel);
00999 s << "}";
01000 appendLine(s);
01001 }
01002
01003
01004 void CHLLCode::AddEndlessLoopHeader(int indLevel) {
01005 std::ostringstream s;
01006 indent(s, indLevel);
01007 s << "for(;;) {";
01008 appendLine(s);
01009 }
01010
01011
01012 void CHLLCode::AddEndlessLoopEnd(int indLevel) {
01013 std::ostringstream s;
01014 indent(s, indLevel);
01015 s << "}";
01016 appendLine(s);
01017 }
01018
01019
01020 void CHLLCode::AddPosttestedLoopHeader(int indLevel) {
01021 std::ostringstream s;
01022 indent(s, indLevel);
01023 s << "do {";
01024 appendLine(s);
01025 }
01026
01027
01028 void CHLLCode::AddPosttestedLoopEnd(int indLevel, Exp *cond)
01029 {
01030 std::ostringstream s;
01031 indent(s, indLevel);
01032 s << "} while (";
01033 appendExp(s, cond, PREC_NONE);
01034 s << ");";
01035 appendLine(s);
01036 }
01037
01038
01039 void CHLLCode::AddCaseCondHeader(int indLevel, Exp *cond)
01040 {
01041 std::ostringstream s;
01042 indent(s, indLevel);
01043 s << "switch(";
01044 appendExp(s, cond, PREC_NONE);
01045 s << ") {";
01046 appendLine(s);
01047 }
01048
01049
01050 void CHLLCode::AddCaseCondOption(int indLevel, Exp *opt)
01051 {
01052 std::ostringstream s;
01053 indent(s, indLevel);
01054 s << "case ";
01055 appendExp(s, opt, PREC_NONE);
01056 s << ":";
01057 appendLine(s);
01058 }
01059
01060
01061 void CHLLCode::AddCaseCondOptionEnd(int indLevel)
01062 {
01063 std::ostringstream s;
01064 indent(s, indLevel);
01065 s << "break;";
01066 appendLine(s);
01067 }
01068
01069
01070 void CHLLCode::AddCaseCondElse(int indLevel)
01071 {
01072 std::ostringstream s;
01073 indent(s, indLevel);
01074 s << "default:";
01075 appendLine(s);
01076 }
01077
01078
01079 void CHLLCode::AddCaseCondEnd(int indLevel)
01080 {
01081 std::ostringstream s;
01082 indent(s, indLevel);
01083 s << "}";
01084 appendLine(s);
01085 }
01086
01087
01088 void CHLLCode::AddIfCondHeader(int indLevel, Exp *cond) {
01089 std::ostringstream s;
01090 indent(s, indLevel);
01091 s << "if (";
01092 appendExp(s, cond, PREC_NONE);
01093 s << ") {";
01094 appendLine(s);
01095 }
01096
01097
01098 void CHLLCode::AddIfCondEnd(int indLevel) {
01099 std::ostringstream s;
01100 indent(s, indLevel);
01101 s << "}";
01102 appendLine(s);
01103 }
01104
01105
01106 void CHLLCode::AddIfElseCondHeader(int indLevel, Exp *cond) {
01107 std::ostringstream s;
01108 indent(s, indLevel);
01109 s << "if (";
01110 appendExp(s, cond, PREC_NONE);
01111 s << ") {";
01112 appendLine(s);
01113 }
01114
01115
01116 void CHLLCode::AddIfElseCondOption(int indLevel) {
01117 std::ostringstream s;
01118 indent(s, indLevel);
01119 s << "} else {";
01120 appendLine(s);
01121 }
01122
01123
01124 void CHLLCode::AddIfElseCondEnd(int indLevel) {
01125 std::ostringstream s;
01126 indent(s, indLevel);
01127 s << "}";
01128 appendLine(s);
01129 }
01130
01131
01132 void CHLLCode::AddGoto(int indLevel, int ord) {
01133 std::ostringstream s;
01134 indent(s, indLevel);
01135 s << "goto L" << std::dec << ord << ";";
01136 appendLine(s);
01137 usedLabels.insert(ord);
01138 }
01139
01140
01141
01142
01143
01144 void CHLLCode::RemoveUnusedLabels(int maxOrd) {
01145 for (std::list<char *>::iterator it = lines.begin(); it != lines.end();) {
01146 if ((*it)[0] == 'L' && strchr(*it, ':')) {
01147 char *s = strdup(*it);
01148 *strchr(s, ':') = 0;
01149 int n = atoi(s+1);
01150 if (usedLabels.find(n) == usedLabels.end()) {
01151 it = lines.erase(it);
01152 continue;
01153 }
01154 }
01155 it++;
01156 }
01157 }
01158
01159
01160 void CHLLCode::AddContinue(int indLevel) {
01161 std::ostringstream s;
01162 indent(s, indLevel);
01163 s << "continue;";
01164 appendLine(s);
01165 }
01166
01167
01168 void CHLLCode::AddBreak(int indLevel) {
01169 std::ostringstream s;
01170 indent(s, indLevel);
01171 s << "break;";
01172 appendLine(s);
01173 }
01174
01175
01176 void CHLLCode::AddLabel(int indLevel, int ord) {
01177 std::ostringstream s;
01178 s << "L" << std::dec << ord << ":";
01179 appendLine(s);
01180 }
01181
01182
01183 void CHLLCode::RemoveLabel(int ord) {
01184 std::ostringstream s;
01185 s << "L" << std::dec << ord << ":";
01186 for (std::list<char*>::iterator it = lines.begin(); it != lines.end(); it++) {
01187 if (!strcmp(*it, s.str().c_str())) {
01188 lines.erase(it);
01189 break;
01190 }
01191 }
01192 }
01193
01194
01195 bool isBareMemof(Exp* e, UserProc* proc) {
01196 if (!e->isMemOf()) return false;
01197 #if SYMS_IN_BACK_END
01198
01199 char* sym = proc->lookupSym(e);
01200 if (sym == NULL)
01201 sym = proc->lookupSym(e->getSubExp1());
01202 return sym == NULL;
01203 #else
01204 return true;
01205 #endif
01206 }
01207
01208
01209 void CHLLCode::AddAssignmentStatement(int indLevel, Assign *asgn) {
01210
01211 if (asgn->getLeft()->getOper() == opPC)
01212 return;
01213 Exp *result;
01214 if (asgn->getRight()->search(new Terminal(opPC), result))
01215 return;
01216
01217
01218
01219
01220 std::ostringstream s;
01221 indent(s, indLevel);
01222 Type* asgnType = asgn->getType();
01223 Exp* lhs = asgn->getLeft();
01224 Exp* rhs = asgn->getRight();
01225 UserProc* proc = asgn->getProc();
01226
01227 if (*lhs == *rhs)
01228 return;
01229
01230 if (Boomerang::get()->noDecompile && isBareMemof(rhs, proc) && lhs->getOper() == opRegOf &&
01231 m_proc->getProg()->getFrontEndId() == PLAT_SPARC) {
01232
01233 if (((Const*)lhs->getSubExp1())->getInt() >= 32 && ((Const*)lhs->getSubExp1())->getInt() <= 63)
01234 rhs = new Ternary(opFsize, new Const(32), new Const(32), rhs);
01235 else if (((Const*)lhs->getSubExp1())->getInt() >= 64 && ((Const*)lhs->getSubExp1())->getInt() <= 87)
01236 rhs = new Ternary(opFsize, new Const(64), new Const(64), rhs);
01237 }
01238
01239 if (Boomerang::get()->noDecompile && isBareMemof(lhs, proc)) {
01240 if (asgnType && asgnType->isFloat()) {
01241 if (asgnType->asFloat()->getSize() == 32)
01242 s << "FLOAT_";
01243 else
01244 s << "DOUBLE_";
01245 } else if (rhs->getOper() == opFsize) {
01246 if (((Const*)rhs->getSubExp2())->getInt() == 32)
01247 s << "FLOAT_";
01248 else
01249 s << "DOUBLE_";
01250 } else if (rhs->getOper() == opRegOf && m_proc->getProg()->getFrontEndId() == PLAT_SPARC) {
01251
01252 if (((Const*)rhs->getSubExp1())->getInt() >= 32 &&
01253 ((Const*)rhs->getSubExp1())->getInt() <= 63)
01254 s << "FLOAT_";
01255 else if (((Const*)rhs->getSubExp1())->getInt() >= 64 &&
01256 ((Const*)rhs->getSubExp1())->getInt() <= 87)
01257 s << "DOUBLE_";
01258 }
01259
01260 s << "MEMASSIGN(";
01261 appendExp(s, lhs->getSubExp1(), PREC_UNARY);
01262 s << ", ";
01263 appendExp(s, rhs, PREC_UNARY);
01264 s << ");";
01265 appendLine(s);
01266 return;
01267 }
01268
01269 if (isBareMemof(lhs, proc) && asgnType && !asgnType->isVoid())
01270 appendExp(s,
01271 new TypedExp(
01272 asgnType,
01273 lhs), PREC_ASSIGN);
01274 else if (lhs->getOper() == opGlobal && asgn->getType()->isArray())
01275 appendExp(s, new Binary(opArrayIndex,
01276 lhs,
01277 new Const(0)), PREC_ASSIGN);
01278 else if (lhs->getOper() == opAt &&
01279 ((Ternary*)lhs)->getSubExp2()->isIntConst() &&
01280 ((Ternary*)lhs)->getSubExp3()->isIntConst()) {
01281
01282 Exp* exp1 = ((Ternary*)lhs)->getSubExp1();
01283 int n = ((Const*)((Ternary*)lhs)->getSubExp2())->getInt();
01284 int m = ((Const*)((Ternary*)lhs)->getSubExp3())->getInt();
01285 appendExp(s, exp1, PREC_ASSIGN);
01286 s << " = ";
01287 int mask = ~(((1 << (m-n+1))-1) << m);
01288 rhs = new Binary(opBitAnd,
01289 exp1,
01290 new Binary(opBitOr,
01291 new Const(mask),
01292 new Binary(opShiftL,
01293 rhs,
01294 new Const(m))));
01295 rhs = rhs->simplify();
01296 appendExp(s, rhs, PREC_ASSIGN);
01297 s << ";";
01298 appendLine(s);
01299 return;
01300 } else
01301 appendExp(s, lhs, PREC_ASSIGN);
01302 if (rhs->getOper() == opPlus &&
01303 *rhs->getSubExp1() == *lhs) {
01304
01305
01306 if (rhs->getSubExp2()->isIntConst() &&
01307 (((Const*)rhs->getSubExp2())->getInt() == 1 ||
01308 (asgn->getType()->isPointer() &&
01309 asgn->getType()->asPointer()->getPointsTo()->getSize()==
01310 (unsigned) ((Const*)rhs->getSubExp2())->getInt() * 8)))
01311 s << "++";
01312 else {
01313 s << " += ";
01314 appendExp(s, rhs->getSubExp2(), PREC_ASSIGN);
01315 }
01316 } else {
01317 s << " = ";
01318 appendExp(s, rhs, PREC_ASSIGN);
01319 }
01320 s << ";";
01321 appendLine(s);
01322 }
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336 void CHLLCode::AddCallStatement(int indLevel, Proc *proc, const char *name, StatementList &args, StatementList* results)
01337 {
01338 std::ostringstream s;
01339 indent(s, indLevel);
01340 if (results->size() >= 1) {
01341
01342 Exp* firstRet = ((Assignment*)*results->begin())->getLeft();
01343 appendExp(s, firstRet, PREC_ASSIGN);
01344 s << " = ";
01345 }
01346 s << name << "(";
01347 StatementList::iterator ss;
01348 bool first = true;
01349 int n = 0;
01350 for (ss = args.begin(); ss != args.end(); ++ss, ++n) {
01351 if (first)
01352 first = false;
01353 else
01354 s << ", ";
01355 Type *t = ((Assign*)*ss)->getType();
01356 Exp* arg = ((Assign*)*ss)->getRight();
01357 bool ok = true;
01358 if (t && t->isPointer() && ((PointerType*)t)->getPointsTo()->isFunc() && arg->isIntConst()) {
01359 Proc *p = proc->getProg()->findProc(((Const*)arg)->getInt());
01360 if (p) {
01361 s << p->getName();
01362 ok = false;
01363 }
01364 }
01365 if (ok) {
01366 bool needclose = false;
01367 if (Boomerang::get()->noDecompile && proc->getSignature()->getParamType(n) &&
01368 proc->getSignature()->getParamType(n)->isPointer()) {
01369 s << "ADDR(";
01370 needclose = true;
01371 }
01372 appendExp(s, arg, PREC_COMMA);
01373 if (needclose)
01374 s << ")";
01375 }
01376 }
01377 s << ");";
01378 if (results->size() > 1) {
01379 bool first = true;
01380 s << " /* Warning: also results in ";
01381 for (ss = ++results->begin(); ss != results->end(); ++ss) {
01382 if (first)
01383 first = false;
01384 else
01385 s << ", ";
01386 appendExp(s, ((Assignment*)*ss)->getLeft(), PREC_COMMA);
01387 }
01388 s << " */";
01389 }
01390
01391 appendLine(s);
01392 }
01393
01394
01395
01396
01397
01398
01399
01400
01401 void CHLLCode::AddIndCallStatement(int indLevel, Exp *exp, StatementList &args, StatementList* results) {
01402
01403 std::ostringstream s;
01404 indent(s, indLevel);
01405 s << "(*";
01406 appendExp(s, exp, PREC_NONE);
01407 s << ")(";
01408 StatementList::iterator ss;
01409 bool first = true;
01410 for (ss = args.begin(); ss != args.end(); ++ss) {
01411 if (first)
01412 first = false;
01413 else
01414 s << ", ";
01415 Exp* arg = ((Assign*)*ss)->getRight();
01416 appendExp(s, arg, PREC_COMMA);
01417 }
01418 s << ");";
01419 appendLine(s);
01420 }
01421
01422
01423
01424
01425
01426
01427 void CHLLCode::AddReturnStatement(int indLevel, StatementList* rets) {
01428
01429
01430 StatementList::iterator rr;
01431 std::ostringstream s;
01432 indent(s, indLevel);
01433 s << "return";
01434 int n = rets->size();
01435
01436 if (n == 0 && Boomerang::get()->noDecompile && m_proc->getSignature()->getNumReturns() > 0)
01437 s << " eax";
01438
01439 if (n >= 1) {
01440 s << " ";
01441 appendExp(s, ((Assign*)*rets->begin())->getRight(), PREC_NONE);
01442 }
01443 s << ";";
01444
01445 if (n > 0) {
01446 if (n > 1)
01447 s << " /* WARNING: Also returning: ";
01448 bool first = true;
01449 for (rr = ++rets->begin(); rr != rets->end(); ++rr) {
01450 if (first)
01451 first = false;
01452 else
01453 s << ", ";
01454 appendExp(s, ((Assign*)*rr)->getLeft(), PREC_NONE);
01455 s << " := ";
01456 appendExp(s, ((Assign*)*rr)->getRight(), PREC_NONE);
01457 }
01458 if (n > 1)
01459 s << " */";
01460 }
01461 appendLine(s);
01462 }
01463
01464
01465
01466
01467 void CHLLCode::AddProcStart(UserProc* proc) {
01468 std::ostringstream s;
01469 s << "// address: 0x" << std::hex << proc->getNativeAddress() << std::dec;
01470 appendLine(s);
01471 AddProcDec(proc, true);
01472 }
01473
01474
01475 void CHLLCode::AddPrototype(UserProc* proc) {
01476 AddProcDec(proc, false);
01477 }
01478
01479
01480
01481
01482
01483 void CHLLCode::AddProcDec(UserProc* proc, bool open) {
01484 std::ostringstream s;
01485 ReturnStatement* returns = proc->getTheReturnStatement();
01486 Type *retType = NULL;
01487 if (proc->getSignature()->isForced()) {
01488 if (proc->getSignature()->getNumReturns() == 0)
01489 s << "void ";
01490 else {
01491 unsigned int n = 0;
01492 Exp *e = proc->getSignature()->getReturnExp(0);
01493 if (e->isRegN(Signature::getStackRegister(proc->getProg())))
01494 n = 1;
01495 if (n < proc->getSignature()->getNumReturns())
01496 retType = proc->getSignature()->getReturnType(n);
01497 if (retType == NULL)
01498 s << "void ";
01499 }
01500 } else if (returns == NULL || returns->getNumReturns() == 0) {
01501 s << "void ";
01502 } else {
01503 Assign* firstRet = (Assign*)*returns->begin();
01504 retType = firstRet->getType();
01505 if (retType == NULL || retType->isVoid())
01506
01507 retType = new IntegerType();
01508 }
01509 if (retType) {
01510 appendType(s, retType);
01511 if (!retType->isPointer())
01512 s << " ";
01513 }
01514 s << proc->getName() << "(";
01515 StatementList& parameters = proc->getParameters();
01516 StatementList::iterator pp;
01517
01518 if (parameters.size() > 10 && open) {
01519 LOG << "Warning: CHLLCode::AddProcDec: Proc " << proc->getName() << " has " << (int)parameters.size() <<
01520 " parameters\n";
01521 }
01522
01523 bool first = true;
01524 for (pp = parameters.begin(); pp != parameters.end(); ++pp) {
01525 if (first)
01526 first = false;
01527 else
01528 s << ", ";
01529 Assign* as = (Assign*)*pp;
01530 Exp* left = as->getLeft();
01531 Type *ty = as->getType();
01532 if (ty == NULL) {
01533 if (VERBOSE)
01534 LOG << "ERROR in CHLLCode::AddProcDec: no type for parameter " << left << "!\n";
01535 ty = new IntegerType();
01536 }
01537 char* name;
01538 if (left->isParam())
01539 name = ((Const*)((Location*)left)->getSubExp1())->getStr();
01540 else {
01541 LOG << "ERROR: parameter " << left << " is not opParam!\n";
01542 name = "??";
01543 }
01544 if (ty->isPointer() && ((PointerType*)ty)->getPointsTo()->isArray()) {
01545
01546
01547 ty = ((PointerType*)ty)->getPointsTo();
01548 Exp *foo = new Const("foo123412341234");
01549 m_proc->searchAndReplace(Location::memOf(left, NULL), foo);
01550 m_proc->searchAndReplace(left, foo);
01551 m_proc->searchAndReplace(foo, left);
01552 }
01553 appendTypeIdent(s, ty, name);
01554 }
01555 s << ")";
01556 if (open)
01557 s << " {";
01558 else
01559 s << ";";
01560 appendLine(s);
01561 }
01562
01563
01564 void CHLLCode::AddProcEnd() {
01565 appendLine("}");
01566 appendLine("");
01567 }
01568
01569
01570
01571
01572
01573 void CHLLCode::AddLocal(const char *name, Type *type, bool last) {
01574 std::ostringstream s;
01575 indent(s, 1);
01576 appendTypeIdent(s, type, name);
01577 Exp *e = m_proc->expFromSymbol(name);
01578 if (e) {
01579
01580 if (e->getOper() == opSubscript && ((RefExp*)e)->isImplicitDef() &&
01581 (e->getSubExp1()->getOper() == opParam ||
01582 e->getSubExp1()->getOper() == opGlobal)) {
01583 s << " = ";
01584 appendExp(s, e->getSubExp1(), PREC_NONE);
01585 s << ";";
01586 } else {
01587 s << "; \t\t// ";
01588 e->print(s);
01589 }
01590 } else
01591 s << ";";
01592 appendLine(s);
01593 locals[name] = type->clone();
01594 if (last)
01595 appendLine("");
01596 }
01597
01598
01599
01600
01601
01602 void CHLLCode::AddGlobal(const char *name, Type *type, Exp *init) {
01603 std::ostringstream s;
01604
01605
01606 if (type->isArray()) {
01607
01608 Type* base = ((ArrayType*)type)->getBaseType();
01609 appendType(s, base);
01610 s << " " << name << "[" << std::dec << ((ArrayType*)type)->getLength() << "]";
01611 } else if (type->isPointer() &&
01612 ((PointerType*)type)->getPointsTo()->resolvesToFunc()) {
01613
01614
01615
01616 PointerType* pt = (PointerType*)type;
01617 FuncType* ft = (FuncType*)pt->getPointsTo();
01618 const char *ret, *param;
01619 ft->getReturnAndParam(ret, param);
01620 s << ret << "(*" << name << ")" << param;
01621 } else {
01622 appendType(s, type);
01623 s << " " << name;
01624 }
01625 if (init && !init->isNil()) {
01626 s << " = ";
01627 Type *base_type = type->isArray() ? type->asArray()->getBaseType() : type;
01628 appendExp(s, init, PREC_ASSIGN, base_type->isInteger() ? !base_type->asInteger()->isSigned() : false);
01629 }
01630 s << ";";
01631 if (type->isSize())
01632 s << "// " << type->getSize() / 8 << " bytes";
01633 appendLine(s);
01634 }
01635
01636
01637 void CHLLCode::print(std::ostream &os) {
01638 for (std::list<char*>::iterator it = lines.begin(); it != lines.end(); it++)
01639 os << *it << std::endl;
01640 if (m_proc == NULL)
01641 os << std::endl;
01642 }
01643
01644
01645 void CHLLCode::AddLineComment(char* cmt) {
01646 std::ostringstream s;
01647 s << "/* " << cmt << "*/";
01648 appendLine(s);
01649 }
01650
01651
01652
01653 void CHLLCode::appendLine(const std::ostringstream& ostr) {
01654 appendLine(ostr.str());
01655 }
01656
01657 void CHLLCode::appendLine(const std::string& s) {
01658 lines.push_back(strdup(s.c_str()));
01659 }
01660