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
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 }