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