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
00026
00027 #include "global.h"
00028 #include "frontend.h"
00029 #include "decoder.h"
00030 #include "rtl.h"
00031 #include "cfg.h"
00032 #include "ss.h"
00033 #include "prog.h"
00034 #include "proc.h"
00035 #include "options.h"
00036 #include "BinaryFile.h"
00037 #include "csr.h"
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 queue < ADDRESS> qLabels;
00049
00050
00051
00052
00053 void initCti();
00054
00055 struct SemCmp
00056 { bool operator() (const SemStr& ss1, const SemStr& ss2) const; };
00057 bool SemCmp::operator() (const SemStr& ss1, const SemStr& ss2) const
00058 { return ss1 < ss2; }
00059
00060
00061 static map<SemStr, int, SemCmp> condMap;
00062
00063 int arrConds[12][7] = {
00064 { idZF},
00065 { idNot, idZF},
00066 { idBitXor, idNF, idOF},
00067 { idBitOr, idBitXor, idNF, idOF, idZF},
00068 { idNot, idBitXor, idNF, idOF },
00069 { idBitAnd, idNot, idBitXor, idNF, idOF,
00070 idNot, idZF},
00071 { idCF},
00072 { idBitOr, idCF, idZF},
00073 { idNot, idCF},
00074 { idBitAnd, idNot, idCF, idNot, idZF},
00075 { idNF},
00076 { idNot, idNF},
00077 };
00078
00079
00080 int condLengths[12] = {1, 2, 3, 5, 4, 7, 1, 3, 2, 5, 1, 2};
00081
00082
00083
00084
00085
00086
00087
00088 void initFront()
00089 {
00090 for (int i=0; i < 12; i++)
00091 {
00092 SemStr ss;
00093 ss.pushArr(condLengths[i], arrConds[i]);
00094 condMap[ss] = i;
00095 }
00096 }
00097
00098
00099 JCOND_TYPE getCond(const SemStr* pCond)
00100 {
00101 map<SemStr, int, SemCmp>::const_iterator mit;
00102
00103 mit = condMap.find(*pCond);
00104 if (mit == condMap.end())
00105 {
00106 ostrstream os;
00107 os << "Condition ";
00108 pCond->print(os);
00109 os << " not known";
00110 error(os.str());
00111 return (JCOND_TYPE) 0;
00112 }
00113 return (JCOND_TYPE) (*mit).second;
00114 }
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 bool FrontEndSrc::processProc(ADDRESS uAddr, UserProc* pProc, ofstream &os,
00126 bool spec )
00127 {
00128
00129 return FrontEnd::processProc(uAddr, pProc, os, spec);
00130 }
00131
00132 #if 0
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 void processProc(ADDRESS uAddr, int delta, ADDRESS uUpper, UserProc* pProc,
00146 NJMCDecoder& decoder)
00147 {
00148 PBB pBB;
00149 INSTTYPE type;
00150
00151
00152
00153 TARGETS targets;
00154
00155
00156
00157
00158 bool sequentialDecode = true;
00159
00160 Cfg* pCfg = pProc->getCFG();
00161
00162
00163 targets.push(uAddr);
00164
00165
00166
00167
00168
00169 while ((uAddr = nextAddress(targets, pCfg)) != 0) {
00170
00171
00172 list<HRTL*>* BB_rtls = new list<HRTL*>();
00173
00174
00175
00176 ADDRESS start = uAddr;
00177 DecodeResult inst;
00178 while (sequentialDecode) {
00179
00180
00181 if (progOptions.trace)
00182 cout << "*" << hex << uAddr << "\t" << flush;
00183
00184
00185 inst = decoder.decodeInstruction(uAddr, delta, pProc);
00186
00187
00188
00189
00190 if (BB_rtls == NULL)
00191 BB_rtls = new list<HRTL*>();
00192
00193 HRTL* pRtl = inst.rtl;
00194 if (inst.numBytes == 0)
00195 {
00196
00197
00198
00199 ostrstream ost;
00200 ost << "invalid instruction at " << hex << uAddr;
00201 warning(str(ost));
00202
00203
00204 BB_rtls->push_back(new RTL(uAddr));
00205 pBB = pCfg->newBB(BB_rtls, INVALID, 0);
00206 sequentialDecode = false; BB_rtls = NULL; continue;
00207 }
00208
00209 HLJump* rtl_jump = static_cast<HLJump*>(pRtl);
00210
00211
00212 if (progOptions.rtl) pRtl->print();
00213
00214 ADDRESS uDest;
00215
00216 switch (pRtl->getKind())
00217 {
00218
00219 case JUMP_HRTL:
00220 {
00221 uDest = rtl_jump->getFixedDest();
00222
00223
00224 if (uDest != NO_ADDRESS) {
00225 BB_rtls->push_back(pRtl);
00226 sequentialDecode = false;
00227
00228 pBB = pCfg->newBB(BB_rtls,ONEWAY,1);
00229
00230
00231
00232 if (pBB == 0) {
00233 sequentialDecode = false;
00234 BB_rtls = NULL;
00235 break;
00236 }
00237
00238
00239
00240 if (uDest < uUpper) {
00241 visit(pCfg, uDest, targets, pBB);
00242 pCfg->addOutEdge(pBB, uDest, true);
00243 }
00244 else {
00245 ostrstream ost;
00246 ost << "Error: Instruction at " << hex << uAddr;
00247 ost << " branches beyond end of section, to ";
00248 ost << uDest;
00249 error(str(ost));
00250 }
00251 }
00252 break;
00253 }
00254
00255 case NWAYJUMP_HRTL:
00256 {
00257 BB_rtls->push_back(pRtl);
00258
00259
00260 pBB = pCfg->newBB(BB_rtls, COMPJUMP, 0);
00261 if (isSwitch(pBB, rtl_jump->getDest(), pProc, pBF)) {
00262 processSwitch(pBB, delta, pCfg, targets, pBF);
00263 }
00264 else {
00265
00266 ostrstream ost;
00267 string sKind("JUMP");
00268 if (type == I_COMPCALL) sKind = "CALL";
00269 ost << "COMPUTED " << sKind << " at "
00270 << hex << uAddr << endl;
00271 warning(str(ost));
00272 BB_rtls = NULL;
00273 }
00274 sequentialDecode = false;
00275 break;
00276 }
00277
00278
00279
00280 case JCOND_HRTL:
00281 {
00282 uDest = rtl_jump->getFixedDest();
00283 BB_rtls->push_back(pRtl);
00284 pBB = pCfg->newBB(BB_rtls, TWOWAY, 2);
00285
00286
00287
00288 if (pBB == 0)
00289 sequentialDecode = false;
00290 else {
00291
00292
00293
00294 if (uDest < uUpper) {
00295 visit(pCfg, uDest, targets, pBB);
00296 pCfg->addOutEdge(pBB, uDest, true);
00297 }
00298 else {
00299 ostrstream ost;
00300 ost << "Error: Instruction at " << hex << uAddr;
00301 ost << " branches beyond end of section, to ";
00302 ost << uDest;
00303 error(str(ost));
00304 }
00305
00306
00307 pCfg->addOutEdge(pBB, uAddr + inst.numBytes);
00308 }
00309
00310
00311
00312 BB_rtls = NULL;
00313 break;
00314 }
00315
00316 case CALL_HRTL:
00317 {
00318 HLCall* call = static_cast<HLCall*>(pRtl);
00319
00320
00321 if (call->isComputed()) {
00322 BB_rtls->push_back(pRtl);
00323 pBB = pCfg->newBB(BB_rtls, COMPCALL, 1);
00324
00325
00326
00327 if (pBB == 0)
00328 sequentialDecode = false;
00329 else
00330 pCfg->addOutEdge(pBB, uAddr + inst.numBytes);
00331
00332 }
00333 else {
00334
00335 BB_rtls->push_back(pRtl);
00336
00337
00338 ADDRESS uNewAddr = call->getFixedDest();
00339
00340
00341
00342 pCfg->addCall(call);
00343
00344
00345
00346 if ((uNewAddr != NO_ADDRESS) &&
00347 prog.findProc(uNewAddr) == NULL) {
00348 prog.visitProc(uNewAddr);
00349 if (progOptions.trace)
00350 cout << "p" << hex << uNewAddr << "\t" << flush;
00351 }
00352
00353
00354
00355 char* name = prog.pBF->SymbolByAddress(uNewAddr);
00356 if (name && strcmp(name, "_exit") == 0) {
00357
00358 pBB = pCfg->newBB(BB_rtls, CALL, 0);
00359
00360
00361 sequentialDecode = false;
00362 }
00363 else {
00364
00365 pBB = pCfg->newBB(BB_rtls, CALL, 1);
00366
00367 if (call->isReturnAfterCall()) {
00368
00369 list<HRTL*>* rtls = new list<HRTL*>();
00370
00371
00372 rtls->push_back(new HLReturn(0, NULL));
00373
00374 BasicBlock* returnBB = pCfg->newBB(rtls, RET, 0);
00375
00376 pCfg->addOutEdge(pBB, returnBB);
00377
00378
00379 pCfg->setLabel(returnBB);
00380 pBB->setJumpReqd();
00381
00382 pProc->setEpilogue(new CalleeEpilogue("__dummy",
00383 list<string>()));
00384
00385
00386 sequentialDecode = false;
00387 }
00388 else
00389 {
00390
00391
00392 if (pBB != NULL)
00393 pCfg->addOutEdge(pBB, uAddr + inst.numBytes);
00394 }
00395 }
00396 }
00397
00398
00399
00400 BB_rtls = NULL;
00401 break;
00402 }
00403
00404 case RET_HRTL:
00405
00406 sequentialDecode = false;
00407
00408
00409 BB_rtls->push_back(pRtl);
00410
00411 pBB = pCfg->newBB(BB_rtls, RET, 0);
00412
00413
00414
00415 BB_rtls = NULL;
00416 break;
00417
00418 case SCOND_HRTL:
00419
00420
00421 case LOW_LEVEL_HRTL:
00422
00423
00424
00425 BB_rtls->push_back(pRtl);
00426 break;
00427
00428 }
00429
00430 uAddr += inst.numBytes;
00431
00432 inst.rtl->updateNumBytes(inst.numBytes);
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 if (sequentialDecode && pCfg->existsBB(uAddr)) {
00443
00444 if (BB_rtls) {
00445 PBB pBB = pCfg->newBB(BB_rtls, FALL, 1);
00446
00447 if (pBB) {
00448 pCfg->addOutEdge(pBB, uAddr);
00449 BB_rtls = NULL;
00450 }
00451 }
00452
00453 if (!pCfg->isIncomplete(uAddr))
00454 sequentialDecode = false;
00455 }
00456
00457 }
00458
00459
00460 pProc->addRange(start, uAddr);
00461
00462
00463 sequentialDecode = true;
00464
00465 }
00466
00467
00468
00469
00470 ADDRESS a1, a2;
00471 COV_CIT ii;
00472 Coverage temp;
00473 if (pProc->getFirstGap(a1, a2, ii)) {
00474 do {
00475 int gap = a2 - a1;
00476 if (gap < 8) {
00477 bool allNops = true;
00478 for (int i=0; i < gap; i+= 2) {
00479
00480 if (getWord(a1+i+delta) != 0x4e71) {
00481 allNops = false;
00482 break;
00483 }
00484 }
00485 if (allNops)
00486
00487
00488
00489 temp.addRange(a1, a2);
00490 }
00491 } while (pProc->getNextGap(a1, a2, ii));
00492 }
00493
00494 pProc->addRanges(temp);
00495
00496 }
00497 #endif
00498
00499