Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

/users/u3/mtikir/PMaCInstrumentor_v1601/tools/CacheSimulator.C

Go to the documentation of this file.
00001 #include <SectHeader.h>
00002 #include <Iterator.h>
00003 #include <Function.h>
00004 #include <LineInfoFinder.h>
00005 #include <XCoffFile.h>
00006 #include <CacheSimulator.h>
00007 #include <Loop.h>
00008 #include <fstream>
00009 #include <SimpleHash.h>
00010 using namespace std;
00011 
00012 CacheSimulator::CacheSimulator(XCoffFile* xcoff,char* extension,uint32_t phaseNo,char* blockFile,bool countBB,bool loopIncl)
00013     : CommonMethods(xcoff,extension,phaseNo,2,blockFile),
00014       enableBBCounting(countBB),enableLoopInclusion(loopIncl),additionalInfo(NULL)
00015 {
00016 }
00017 
00018 bool allSpace(char* str){
00019     int32_t len = strlen(str);
00020     for(int32_t i=0;i<len;i++){
00021         switch(str[i]){
00022             case ' ' :
00023             case '\n':
00024             case '\t':
00025                 break;
00026             default:
00027                 return false;
00028         }
00029     }
00030     return true;
00031 }
00032 
00033 void CacheSimulator::selectInstrumentationPoints(char* blockFile){
00034 
00035     terminationBlock = findTerminationBlock();
00036     ASSERT(terminationBlock && "FATAL : There is no exit block");
00037 
00038     char buffer[__MAX_STRING_SIZE];
00039     uint32_t howMany = 0;
00040 
00041     ifstream tmpFile;
00042     tmpFile.open(blockFile);
00043     if(!tmpFile){
00044         PRINT_ERROR("Input file can not be opened [%s]",blockFile);
00045     }
00046     while(tmpFile.getline(buffer,__MAX_STRING_SIZE))
00047         howMany++;
00048     tmpFile.close();
00049 
00050     if(!howMany){
00051         PRINT_ERROR("The instrumentation file is empty");
00052         return;
00053     }
00054 
00055     blocksToInstrument = new BasicBlock*[howMany+1];
00056 
00057     uint32_t lineNo = 0;
00058 
00059     bool insertAppExitBlock = true;
00060 
00061     ifstream inFile;
00062     inFile.open(blockFile);
00063     while(inFile.getline(buffer,__MAX_STRING_SIZE)){
00064         lineNo++;
00065 
00066         char* ptr = strchr(buffer,'#');
00067         if(ptr) *ptr = '\0';
00068 
00069         if(!strlen(buffer) || allSpace(buffer))
00070             continue;
00071 
00072         uint64_t id = 0;
00073         int32_t err = sscanf(buffer,"%lld",&id);
00074         if(err <= 0){
00075             numOfBlocksFiltered++;
00076             PRINT_ERROR("Line %d of %s has a wrong format",lineNo,blockFile);
00077         }
00078         HashCode hashCode(id);
00079         if(!hashCode.isBlock()){
00080             numOfBlocksFiltered++;
00081             PRINT_ERROR("Line %d of %s is a wrong unique id for a basic block",lineNo,blockFile);
00082         }
00083 
00084         BasicBlock* bb = xcoffFile->findBasicBlock(&hashCode);
00085 
00086         if(!bb){
00087             //PRINT_ERROR("Line %d of %s does not correspond to any basic block in this executable",lineNo,blockFile);
00088             numOfBlocksFiltered++;
00089             continue;
00090         }
00091 
00092         if(filterBlockForInst(bb)){
00093             PRINT_INFOR("Line %d of %s if filtered",lineNo,blockFile);
00094             numOfBlocksFiltered++;
00095             continue;
00096         }
00097 
00098         if(insertAppExitBlock && (bb == terminationBlock)){
00099             PRINT_INFOR("The exit block sequence id will be %d",numberOfInstPoints);
00100             insertAppExitBlock = false;
00101         }
00102 
00103         if(!Instruction::isInLoadOffsetInsnRange(bb->getNumOfMemoryOps()-1)){
00104             PRINT_ERROR("At cache simulation there can only be at most %d memops instrumented in a block",0x7fff);
00105         }
00106         blocksToInstrument[numberOfInstPoints++] = bb;
00107     }
00108 
00109     inFile.close();
00110 
00111     if(!numberOfInstPoints){
00112         PRINT_ERROR("There is no basic block passed the filter");
00113     }
00114 
00115     if(insertAppExitBlock){
00116         blocksToInstrument[numberOfInstPoints++] = terminationBlock;
00117     }
00118 
00119     if(enableLoopInclusion){
00120         SimpleHash<BasicBlock*> bbSet;
00121         uint32_t initialPointCount = numberOfInstPoints;
00122 
00123         xcoffFile->findLoops();
00124         for(uint32_t i=0;i<initialPointCount;i++){
00125             
00126             BasicBlock* bb = blocksToInstrument[i];
00127             uint32_t loopCount = bb->getFlowGraph()->getNumberOfLoops();
00128 
00129             bbSet.insert(bb->getHashCode().getValue(),bb);
00130 
00131             for(uint32_t j=0;j<loopCount;j++){
00132                 Loop* currLoop = bb->getFlowGraph()->getLoop(j);
00133                 if(currLoop->isBlockIn(bb->getIndex())){
00134                     uint32_t loopBlockCount = currLoop->getNumberOfBlocks();
00135                     BasicBlock** buffer = new BasicBlock*[loopBlockCount];
00136                     currLoop->getAllBlocks(buffer);
00137                     for(uint32_t k=0;k<loopBlockCount;k++){
00138                         BasicBlock* candidate = buffer[k];
00139                         if(filterBlockForInst(candidate)){
00140                             numOfBlocksFiltered++;
00141                             continue;
00142                         }
00143                         if(!Instruction::isInLoadOffsetInsnRange(candidate->getNumOfMemoryOps()-1)){
00144                             PRINT_ERROR("There can only be at most %d memops instrumented in a block",0x7fff);
00145                         }
00146                         bbSet.insert(candidate->getHashCode().getValue(),candidate);
00147                     }
00148                 }
00149             }
00150         }
00151 
00152         DEBUG(bbSet.print(););
00153 
00154         delete[] blocksToInstrument;
00155         numberOfInstPoints = bbSet.size();
00156         blocksToInstrument = bbSet.values();
00157 
00158         if(additionalInfo) delete[] additionalInfo;
00159         additionalInfo = new char[__MAX_STRING_SIZE];
00160         sprintf(additionalInfo,"basic cnt = %d (Loop level)\n# exted cnt = %d (Loop level)",
00161                 initialPointCount,numberOfInstPoints);
00162     }
00163 
00164     if(!Instruction::isInLoadOffsetInsnRange(numberOfInstPoints-1)){
00165         PRINT_ERROR("At cache simulation there can only be at most %d blocks instrumented",0x7fff);
00166     }
00167 
00168     PRINT_INFOR("**** Number of basic blocks considered in instrumentation %d ******",numberOfInstPoints);
00169 }
00170 
00171 uint32_t CacheSimulator::byteCountForInst(uint32_t instPointIdx,
00172                                                     uint64_t instStubAddress,TextSection* textSect)
00173 {
00174     ASSERT(extendedDataSize && dataBufferEntryCount);
00175 
00176     BasicBlock* block = blocksToInstrument[instPointIdx];
00177     ASSERT(block);
00178 
00179     uint32_t memopsToInsn = block->getNumOfMemoryOps();
00180     if(!memopsToInsn){
00181         return 0;
00182     }
00183 
00184     ASSERT(memopsToInsn < getDataBufferEntryCount());
00185     bool isApplicationExit = (block == terminationBlock);
00186 
00187     uint32_t insnCount = 0;
00188     uint32_t minInsnCount = 15;
00189     uint32_t tocUpdateInsnCount = 0;
00190     uint32_t indexAccessInsnCount = 0;
00191     uint32_t extraBBCountInsnCount = 0;
00192     uint32_t exitInsnCount = 2;
00193     uint32_t firstInstInsnCount = 14;
00194 
00195     if(tocXorUpdateVal){
00196         tocUpdateInsnCount = 2;
00197         if(SECOND_HALFWORD(tocXorUpdateVal)){
00198             tocUpdateInsnCount = 2;
00199         }
00200     }
00201     int32_t counterOffset = getDataOffsetForInst(0);
00202     if(!Instruction::isInLoadOffsetInsnRange(counterOffset)){
00203         indexAccessInsnCount = 5;
00204     } else {
00205         indexAccessInsnCount = 3;
00206     }
00207 
00208     int32_t extraCounterOffset = getExtraBlockInfoAddress(instPointIdx);
00209     if(enableBBCounting){
00210         if(!Instruction::isInLoadOffsetInsnRange(extraCounterOffset)){
00211             extraBBCountInsnCount = 5;
00212         } else {
00213             extraBBCountInsnCount = 3;
00214         }
00215     }
00216 
00217     int32_t tocLoadBackOffset = 20 * (xcoffFile->is64Bit() ? 2 : 1);
00218 
00219     uint32_t savedReg = 31;
00220     uint32_t scratchReg = 30;
00221     bool firstMemOpProcessed = false;
00222     bool nextStopDueTOC = false;
00223     for(uint32_t i=0;i<memopsToInsn;i++){
00224 
00225         MemoryOperation* memop = block->getMemoryOp(i);
00226         ASSERT(memop);
00227         uint64_t instPointAddress = memop->getInsnAddr();
00228         ASSERT(textSect->inRange(instPointAddress));
00229 
00230         if(!Instruction::isInJumpInsnRange(instPointAddress,instStubAddress)){
00231             PRINT_INFOR("mem op %#18llx,%d can not be instrumented due to branch offset limit",
00232                         block->getHashCode().getValue(),i);
00233             continue;
00234         }
00235         if(nextStopDueTOC)
00236             continue;
00237 
00238         Instruction origInsn = memop->getInstruction();
00239         Operand op1 = memop->getAddressOperand1();
00240         Operand op2 = memop->getAddressOperand2();
00241         if((origInsn.isMemoryDForm() || origInsn.isMemoryDsForm()) && !origInsn.isMemoryDFormFloat()){
00242             if((origInsn.getDFormTgt() == REG_TOC) && 
00243                op2.isInteger() && (op2.getIconst() == tocLoadBackOffset) &&
00244                op1.isGPRegister() && (op1.getRegister() != REG_TOC)) 
00245             {
00246             } else {
00247                 if(origInsn.getDFormTgt() == REG_TOC)
00248                     nextStopDueTOC = true;
00249             }
00250         }
00251 
00252         insnCount += minInsnCount;
00253         insnCount += tocUpdateInsnCount;
00254         insnCount += indexAccessInsnCount;
00255         if(!firstMemOpProcessed){
00256             firstMemOpProcessed = true;
00257             if(enableBBCounting){
00258                 insnCount += extraBBCountInsnCount;
00259             }
00260             insnCount += tocUpdateInsnCount;
00261             insnCount += firstInstInsnCount;
00262             if(isApplicationExit){
00263                 insnCount += tocUpdateInsnCount;
00264                 insnCount += exitInsnCount;
00265             }
00266         }
00267         op1 = memop->getAddressOperand1();
00268         uint32_t addrReg1 = 0;
00269         if(op1.isInteger()){
00270             addrReg1 = 0;
00271         } else if(op1.isGPRegister()) {
00272             addrReg1 = op1.getRegister();
00273         }
00274         if((addrReg1 == savedReg) || (addrReg1 == scratchReg)){
00275             insnCount += 1;
00276         }
00277         op2 = memop->getAddressOperand2();
00278         if(op2.isGPRegister()) {
00279             uint32_t addrReg2 = op2.getRegister();
00280             if((addrReg2 == savedReg) || (addrReg2 == scratchReg)){
00281                 if((addrReg1 == savedReg) || (addrReg1 == scratchReg)){
00282                     insnCount += 3;
00283                 } else {
00284                     insnCount += 1;
00285                 }
00286             }
00287         }
00288         insnCount += 1;
00289     }
00290     return (insnCount*sizeof(uint32_t));
00291 }
00292 
00293 uint32_t CacheSimulator::generateCodeForInst(uint32_t instPointIdx,
00294                                                     uint64_t instStubAddress,TextSection* textSect,
00295                                                     BaseGen* gen,uint32_t genBufferOffset)
00296 {
00297     ASSERT(extendedDataSize && dataBufferEntryCount);
00298     ASSERT(gen->getParsedBase() == (Base*)textSect);
00299 
00300     BasicBlock* block = blocksToInstrument[instPointIdx];
00301     ASSERT(block);
00302 
00303     uint32_t memopsToInsn = block->getNumOfMemoryOps();
00304     if(!memopsToInsn){
00305         return 0;
00306     }
00307 
00308     ASSERT(memopsToInsn < getDataBufferEntryCount());
00309     bool isApplicationExit = (block == terminationBlock);
00310 
00311     uint32_t maxInsnCount = memopsToInsn * (maxByteCountPerInst() / sizeof(uint32_t));
00312 
00313     uint32_t insnCount = 0;
00314     Instruction* insnBuffer = new Instruction[maxInsnCount];
00315 
00316     uint32_t savedReg = 31;
00317     uint32_t scratchReg = 30;
00318     uint32_t extraReg = 0;
00319     ASSERT(savedReg > LAST_VOLATILE_REG);
00320     ASSERT(scratchReg > LAST_VOLATILE_REG);
00321     ASSERT(!extraReg);
00322     int32_t savedRegSaveOffset   = getGPRSaveOffset(savedReg);
00323     int32_t scratchRegSaveOffset = getGPRSaveOffset(scratchReg);
00324     int32_t counterOffset = getDataOffsetForInst(0);
00325     int32_t extraCounterOffset = getExtraBlockInfoAddress(instPointIdx);
00326 
00327     int32_t tocLoadBackOffset = 20 * (xcoffFile->is64Bit() ? 2 : 1);
00328 
00329     bool firstMemOpProcessed = false;
00330     bool nextStopDueTOC = false;
00331 
00332     for(uint32_t i=0;i<memopsToInsn;i++){
00333 
00334         MemoryOperation* memop = block->getMemoryOp(i);
00335         ASSERT(memop);
00336 
00337         uint64_t instPointAddress = memop->getInsnAddr();
00338 
00339         ASSERT(textSect->inRange(instPointAddress));
00340 
00341         if(!Instruction::isInJumpInsnRange(instPointAddress,instStubAddress)){
00342             PRINT_INFOR("mem op %#18llx,%d can not be instrumented due to branch offset limit",
00343                         block->getHashCode().getValue(),i);
00344             continue;
00345         }
00346 
00347         if(nextStopDueTOC){
00348             PRINT_DEBUG("Skipping at %#18llx,%#18llx,%#18llx,%d",
00349                     instPointAddress,block->getBaseAddress(),
00350                     block->getBaseAddress()+block->getSizeInBytes(),
00351                     i);
00352             continue;
00353         }
00354 
00355         DEBUG(memop->print());
00356 
00357         uint64_t instStubAddressForMemop = instStubAddress + (insnCount * sizeof(uint32_t));
00358 
00359         bool originalFirst = false;
00360         Instruction origInsn = memop->getInstruction();
00361 
00362         Operand op1 = memop->getAddressOperand1();
00363         Operand op2 = memop->getAddressOperand2();
00364         if((origInsn.isMemoryDForm() || origInsn.isMemoryDsForm()) && !origInsn.isMemoryDFormFloat()){
00365             if((origInsn.getDFormTgt() == REG_TOC) && 
00366                op2.isInteger() && (op2.getIconst() == tocLoadBackOffset) &&
00367                op1.isGPRegister() && (op1.getRegister() != REG_TOC)) 
00368             {
00369                 originalFirst = true;
00370                 PRINT_DEBUG("Instruction at %#18llx needs first to be executed",instPointAddress);
00371                 insnBuffer[insnCount++] = origInsn;
00372             } else {
00373                 if(origInsn.getDFormTgt() == REG_TOC){
00374                     PRINT_DEBUG("Stop next due to TOC issue at %#18llx",instPointAddress);
00375                     nextStopDueTOC = true;
00376                 }
00377             }
00378         }
00379 
00380         updateTOCRegister(insnBuffer,&insnCount);
00381 
00382         insnBuffer[insnCount++] = Instruction::generateStoreDouble(savedReg,REG_TOC,savedRegSaveOffset);
00383         insnBuffer[insnCount++] = Instruction::generateStoreDouble(scratchReg,REG_TOC,scratchRegSaveOffset);
00384 
00385         if(enableBBCounting){
00386             if(!firstMemOpProcessed){
00387                 if(!Instruction::isInLoadOffsetInsnRange(extraCounterOffset)){
00388                     insnBuffer[insnCount++] = Instruction::generateLoad32BitHigh(scratchReg,extraCounterOffset);
00389                     insnBuffer[insnCount++] = Instruction::generateLoad32BitLow(scratchReg,extraCounterOffset);
00390                     insnBuffer[insnCount++] = Instruction::generateLoadDoubleIndx(savedReg,REG_TOC,scratchReg);
00391     
00392                     insnBuffer[insnCount++] = Instruction::generateIncrement(savedReg,1);
00393                     insnBuffer[insnCount++] = Instruction::generateStoreDoubleIndx(savedReg,REG_TOC,scratchReg);
00394                 } else {
00395                     insnBuffer[insnCount++] = Instruction::generateLoadDouble(savedReg,REG_TOC,extraCounterOffset);
00396                     insnBuffer[insnCount++] = Instruction::generateIncrement(savedReg,1);
00397                     insnBuffer[insnCount++] = Instruction::generateStoreDouble(savedReg,REG_TOC,extraCounterOffset);
00398                 }
00399             }
00400         }
00401 
00402         if(!Instruction::isInLoadOffsetInsnRange(counterOffset)){
00403             insnBuffer[insnCount++] = Instruction::generateLoad32BitHigh(scratchReg,counterOffset);
00404             insnBuffer[insnCount++] = Instruction::generateLoad32BitLow(scratchReg,counterOffset);
00405             insnBuffer[insnCount++] = Instruction::generateLoadWordIndx(savedReg,REG_TOC,scratchReg);
00406 
00407             insnBuffer[insnCount++] = Instruction::generateIncrement(savedReg,1);
00408             insnBuffer[insnCount++] = Instruction::generateStoreWordIndx(savedReg,REG_TOC,scratchReg);
00409         } else {
00410             insnBuffer[insnCount++] = Instruction::generateLoadWord(savedReg,REG_TOC,counterOffset);
00411             insnBuffer[insnCount++] = Instruction::generateIncrement(savedReg,1);
00412             insnBuffer[insnCount++] = Instruction::generateStoreWord(savedReg,REG_TOC,counterOffset);
00413         }
00414 
00415         if(!firstMemOpProcessed){
00416             firstMemOpProcessed = true;
00417 
00418             saveCRRegister(insnBuffer,&insnCount,scratchReg);
00419 
00420             if(isApplicationExit){
00421                 saveLNKRegister(insnBuffer,&insnCount,scratchReg);
00422             }
00423 
00424             int32_t value = getDataBufferEntryCount()-memopsToInsn + 1;
00425             insnBuffer[insnCount++] = Instruction::generateLoad32BitHigh(scratchReg,value);
00426             insnBuffer[insnCount++] = Instruction::generateLoad32BitLow(scratchReg,value);
00427             insnBuffer[insnCount++] = Instruction::generateCompare(savedReg,scratchReg,7);
00428             uint32_t condBrInsnIdx = insnCount++;
00429 
00430             if(!isApplicationExit){
00431                 saveLNKRegister(insnBuffer,&insnCount,scratchReg);
00432             }
00433 
00434             updateTOCRegister(insnBuffer,&insnCount);
00435 
00436             uint64_t fromAddr = instStubAddress + (insnCount * sizeof(uint32_t));
00437             uint64_t toAddr   = libraryFuncStubAddrs[1];
00438             insnBuffer[insnCount++] = Instruction::generateCallToImmediate(fromAddr,toAddr);
00439 
00440             updateTOCRegister(insnBuffer,&insnCount);
00441 
00442             if(!isApplicationExit){
00443                 restLNKRegister(insnBuffer,&insnCount,scratchReg);
00444             }
00445 
00446             insnBuffer[insnCount++] = Instruction::generateLoadImmediate(savedReg,1);
00447 
00448             insnBuffer[condBrInsnIdx] = Instruction::generateCondBranch(7,COMPARE_LT,COMPARE_TRUE,
00449                                                                         sizeof(uint32_t)*(insnCount-condBrInsnIdx));
00450 
00451             if(isApplicationExit){
00452                 updateTOCRegister(insnBuffer,&insnCount);
00453 
00454                 fromAddr = instStubAddress + (insnCount * sizeof(uint32_t));
00455                 toAddr   = libraryFuncStubAddrs[0];
00456                 insnBuffer[insnCount++] = Instruction::generateCallToImmediate(fromAddr,toAddr);
00457                 insnBuffer[insnCount++] = Instruction::generateLoadImmediate(savedReg,1);
00458 
00459                 updateTOCRegister(insnBuffer,&insnCount);
00460 
00461                 restLNKRegister(insnBuffer,&insnCount,scratchReg);
00462             }
00463             restCRRegister(insnBuffer,&insnCount,scratchReg);
00464 
00465         }
00466 
00467         insnBuffer[insnCount++] = Instruction::multiplyImmediate(savedReg,savedReg,bytesPerBufferEntry());
00468         insnBuffer[insnCount++] = Instruction::generateIncrement(savedReg,counterOffset);
00469         insnBuffer[insnCount++] = Instruction::generateAdd(savedReg,savedReg,REG_TOC);
00470 
00471         insnBuffer[insnCount++] = Instruction::generateLoadImmediate(scratchReg,instPointIdx);
00472         insnBuffer[insnCount++] = Instruction::generateStoreWord(scratchReg,savedReg,0);
00473 
00474         insnBuffer[insnCount++] = Instruction::generateLoadImmediate(scratchReg,i);
00475         insnBuffer[insnCount++] = Instruction::generateStoreWord(scratchReg,savedReg,4);
00476 
00477         op1 = memop->getAddressOperand1();
00478         uint32_t addrReg1 = 0;
00479         if(op1.isInteger()){
00480             ASSERT(!op1.getIconst());
00481             addrReg1 = 0;
00482         } else if(op1.isGPRegister()) {
00483             addrReg1 = op1.getRegister();
00484         }
00485         if((addrReg1 == savedReg) || (addrReg1 == scratchReg)){
00486             PRINT_DEBUG("CASE 1 Source 1 is %d for %#18llx",addrReg1,instPointAddress);
00487             if(addrReg1 == savedReg){
00488                 insnBuffer[insnCount++] = Instruction::generateLoadDouble(scratchReg,REG_TOC,savedRegSaveOffset);
00489                 addrReg1 = scratchReg;
00490             } else if(addrReg1 == scratchReg){
00491                 insnBuffer[insnCount++] = Instruction::generateLoadDouble(scratchReg,REG_TOC,scratchRegSaveOffset);
00492             }
00493         }
00494 
00495         op2 = memop->getAddressOperand2();
00496         if(op2.isInteger()){
00497             insnBuffer[insnCount++] = Instruction::generateAddImm(scratchReg,addrReg1,op2.getIconst());
00498         } else if(op2.isGPRegister()) {
00499             uint32_t addrReg2 = op2.getRegister();
00500             if((addrReg2 == savedReg) || (addrReg2 == scratchReg)){
00501                 if((addrReg1 == savedReg) || (addrReg1 == scratchReg)){
00502                     PRINT_DEBUG("CASE 2 Source 2 is %d Source 1 is %d for %#18llx",addrReg2,addrReg1,instPointAddress);
00503                     int32_t savedOffset   = getGPRSaveOffset(extraReg);
00504                     insnBuffer[insnCount++] = Instruction::generateStoreDouble(extraReg,REG_TOC,savedOffset);
00505                     if(addrReg2 == savedReg){
00506                         insnBuffer[insnCount++] = Instruction::generateLoadDouble(extraReg,REG_TOC,savedRegSaveOffset);
00507                     } else if(addrReg2 == scratchReg){
00508                         insnBuffer[insnCount++] = Instruction::generateLoadDouble(extraReg,REG_TOC,scratchRegSaveOffset);
00509                     }
00510                     insnBuffer[insnCount++] = Instruction::generateAdd(scratchReg,addrReg1,extraReg);
00511                     insnBuffer[insnCount++] = Instruction::generateLoadDouble(extraReg,REG_TOC,savedOffset);
00512                 } else {
00513                     PRINT_DEBUG("CASE 3 Source 2 is %d Source 1 is %d for %#18llx",addrReg2,addrReg1,instPointAddress);
00514                     if(addrReg2 == savedReg){
00515                         insnBuffer[insnCount++] = Instruction::generateLoadDouble(scratchReg,REG_TOC,savedRegSaveOffset);
00516                     } else if(addrReg2 == scratchReg){
00517                         insnBuffer[insnCount++] = Instruction::generateLoadDouble(scratchReg,REG_TOC,scratchRegSaveOffset);
00518                     }
00519                     insnBuffer[insnCount++] = Instruction::generateAdd(scratchReg,addrReg1,scratchReg);
00520                 }
00521             } else {
00522                 insnBuffer[insnCount++] = Instruction::generateAdd(scratchReg,addrReg1,addrReg2);
00523             }
00524         }
00525 
00526         insnBuffer[insnCount++] = Instruction::generateStoreDouble(scratchReg,savedReg,8);
00527 
00528         insnBuffer[insnCount++] = Instruction::generateLoadDouble(scratchReg,REG_TOC,scratchRegSaveOffset);
00529         insnBuffer[insnCount++] = Instruction::generateLoadDouble(savedReg,REG_TOC,savedRegSaveOffset);
00530 
00531         updateTOCRegister(insnBuffer,&insnCount);
00532 
00533         if(!originalFirst){
00534             insnBuffer[insnCount++] = origInsn;
00535         }
00536 
00537         uint64_t fromAddr = instStubAddress + (insnCount * sizeof(uint32_t));
00538         uint64_t toAddr   = instPointAddress + sizeof(uint32_t);
00539         insnBuffer[insnCount++] = Instruction::generateJumpInsn(fromAddr,toAddr);
00540 
00541         insnBuffer[insnCount++] = Instruction((instPointIdx << 16) | i);
00542 
00543         fromAddr = instPointAddress;
00544         toAddr   = instStubAddressForMemop;
00545         Instruction origJumpToStub = Instruction::generateJumpInsn(fromAddr,toAddr);
00546         gen->writeWord(instPointAddress-textSect->getSectHeader()->GET(s_vaddr),origJumpToStub.bits());
00547     }
00548 
00549     ASSERT(insnCount <= maxInsnCount);
00550     gen->writeInstructions(genBufferOffset,insnCount,insnBuffer);
00551 
00552     delete[] insnBuffer;
00553 
00554     return (insnCount*sizeof(uint32_t));
00555 }
00556 
00557 bool CacheSimulator::filterBlockForInst(BasicBlock* bb){
00558     if(!bb)
00559         return true;
00560     if(bb->isTrace() || bb->isJumpTable())
00561         return true;
00562     if(bb->getNumOfMemoryOps() == 0)
00563        return true;
00564     return false;
00565 }
00566 
00567 void CacheSimulator::getSharedLibraryPathAndObj(char** path,char** name,char** obj){
00568     *path = getPathToInstLib();
00569     *obj  = "";
00570     if(enableBBCounting){
00571         if(xcoffFile->is64Bit()){
00572             *name = "libsimuCntr_64.a";
00573         } else {
00574             *name = "libsimuCntr.a";
00575         }
00576     } else {
00577         if(xcoffFile->is64Bit()){
00578             *name = "libsimuFunc_64.a";
00579         } else {
00580             *name = "libsimuFunc.a";
00581         }
00582     }
00583     ASSERT(path && name && obj);
00584 }
00585 
00586 void CacheSimulator::initializeReservedData(DataSection* dataSect,BaseGen* gen){
00587     gen->writeString(commentAddress-dataSect->getSectHeader()->GET(s_vaddr),
00588                      sharedLibraryInfoStr,strlen(sharedLibraryInfoStr) + 1);
00589 
00590     if(!enableBBCounting){
00591         uint32_t offset = extraBlockInfoAddress-dataSect->getSectHeader()->GET(s_vaddr);
00592         for (uint32_t i = 0; i < numberOfInstPoints; i++){
00593             uint16_t memOpCount = blocksToInstrument[i]->getNumOfMemoryOps();
00594             gen->writeHalfWord(offset,memOpCount);
00595             offset += sizeof(uint16_t);
00596         }
00597     }
00598 }

Generated on Mon Jan 28 11:08:33 2008 for PMaCInstrumentor by doxygen 1.3.5