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

/users/u3/mtikir/PMaCInstrumentor_v1601/tools/CommonMethods.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 <CommonMethods.h>
00007 #include <Loop.h>
00008 #include <fstream>
00009 using namespace std;
00010 
00011 
00012 char*  CommonMethods::staticPrintExtension = "static";
00013 
00014 CommonMethods::CommonMethods(XCoffFile* xcoff,char* extension,uint32_t phaseNo,uint32_t callCount,char* inpFile)
00015     : XCoffFileGen(xcoff,extension,phaseNo,inpFile),libraryFunctionCount(callCount),
00016       blocksToInstrument(NULL),terminationBlock(NULL),numOfBlocksFiltered(0),
00017       extendedBeginAddr(0),
00018       execTOCAddress(0),tocXorUpdateVal(0),tocDistUpdateVal(0),
00019       sharedLibraryInfoStr(NULL),enableExtendedPrint(false)
00020 {
00021 }
00022 
00023 BasicBlock* CommonMethods::findTerminationBlock(){
00024 
00025     char* tmpStr = "";
00026     uint32_t allBlocksCount = xcoffFile->getNumberOfBlocks();
00027     if(!allBlocksCount)
00028         return NULL;
00029 
00030     BasicBlock** allBlocks = new BasicBlock*[allBlocksCount];
00031     xcoffFile->getAllBlocks(allBlocks);
00032 
00033     BasicBlock* mpiexit = NULL;
00034     BasicBlock* regexit = NULL;
00035     BasicBlock* pmacexit = NULL;
00036 
00037     for (uint32_t i = 0; i < allBlocksCount; i++){
00038         BasicBlock* bb = allBlocks[i];
00039         if (bb->isTrace() || bb->isJumpTable() || bb->getIndex())
00040             continue;
00041         Function* owner = bb->getFlowGraph()->getFunction();
00042         if (!pmacexit && owner->isAnySymbolA(".__pmac_time_mod_NMOD_end_pmac_clock")){
00043             tmpStr = ".__pmac_time_mod_NMOD_end_pmac_clock";
00044             pmacexit = bb;
00045         }
00046         if (!pmacexit && owner->isAnySymbolA(".end_pmac_fromc")){
00047             tmpStr = ".end_pmac_fromc";
00048             pmacexit = bb;
00049         } 
00050         if (!mpiexit && 
00051             (owner->isAnySymbolA(".mpi_finalize") ||
00052              owner->isAnySymbolA(".MPI_Finalize"))){
00053             mpiexit = bb;
00054         } 
00055         if (!regexit && owner->isAnySymbolA(".exit")){
00056             regexit = bb;
00057         }
00058     }
00059     delete[] allBlocks;
00060 
00061     if (pmacexit) {
00062         PRINT_INFOR("The exit function .end_pmac_fromc(%s) is taken",tmpStr);
00063         return pmacexit;
00064     }
00065     if (mpiexit){
00066         PRINT_INFOR("The exit function .mpi_finalize is taken");
00067         return mpiexit;
00068     }
00069     if (regexit){
00070         PRINT_INFOR("The exit function .exit is taken");
00071         return regexit;
00072     }
00073     return NULL;
00074 }
00075 
00076 void CommonMethods::printInstrumentationPoints(){
00077 
00078     char instBlockFileName[__MAX_STRING_SIZE];
00079     if (!getPhaseIndex()){
00080         sprintf(instBlockFileName,"%s.%s.%s",xcoffFile->getXCoffFileName(),getFileExtension(),staticPrintExtension);
00081     } else {
00082         sprintf(instBlockFileName,"%s.phase.%d.%s.%s",xcoffFile->getXCoffFileName(),getPhaseIndex(),
00083                 getFileExtension(),staticPrintExtension);
00084     }
00085 
00086     ofstream instBlockFile;
00087     instBlockFile.open(instBlockFileName);
00088     if (!instBlockFile){
00089          PRINT_ERROR("Instrumented block infor can not be opened [%s]",instBlockFileName);
00090     }
00091 
00092     uint32_t memOpCount = 0;
00093     uint32_t fpOpCount = 0;
00094     uint32_t insnCount = 0;
00095 
00096     for (uint32_t i=0;i<numberOfInstPoints;i++){
00097         memOpCount += blocksToInstrument[i]->getNumOfMemoryOps();
00098         fpOpCount += blocksToInstrument[i]->getNumOfFloatPOps();
00099         insnCount += blocksToInstrument[i]->getInstructionCount();
00100     }
00101 
00102     TextSection* lineInfoSect = (TextSection*)xcoffFile->getRawSection(xcoffFile->getTextSectionIndex());
00103     LineInfoFinder* lineInfoFinder = lineInfoSect->getLineInfoFinder();
00104 
00105     instBlockFile << "# appname   = " << xcoffFile->getXCoffFileName() << endl;
00106     instBlockFile << "# appsize   = " << xcoffFile->getFileSize() << endl;
00107     instBlockFile << "# extension = " << getFileExtension() << endl;
00108     instBlockFile << "# phase     = " << getPhaseIndex() << endl;
00109     instBlockFile << "# type      = " << getGenClassName() << endl;
00110     instBlockFile << "# candidate = " << xcoffFile->getNumberOfBlocks() << endl;
00111     instBlockFile << "# blocks    = " << numberOfInstPoints << endl;
00112     instBlockFile << "# memops    = " << memOpCount << endl;
00113     instBlockFile << "# fpops     = " << fpOpCount << endl;
00114     instBlockFile << "# insns     = " << insnCount << endl;
00115     instBlockFile << "# buffer    = " << howManyBufferEntry() << endl;
00116     instBlockFile << "# library   = " << getPathToInstLib() << endl;
00117     instBlockFile << "# libTag    = " << VersionTag::getLibraryVersionTag() << endl;
00118     instBlockFile << "# " << additionalInfoToPrint() << endl;
00119     if(isExtendedPrint()){
00120         instBlockFile << "# <sequence> <block_uid> <memop> <fpop> <insn> <line> <fname>";
00121         instBlockFile << " <loopcnt> <loopid> <ldepth> <hex_uid> <vaddr>" << endl;
00122     } else {
00123         instBlockFile << "# <sequence> <block_uid> <memop> <fpop> <insn> <line> <fname>";
00124         instBlockFile << " <hex_uid> <vaddr>" << endl;
00125     }
00126 
00127     for (uint32_t i = 0; i < numberOfInstPoints; i++){
00128         BasicBlock* bb = blocksToInstrument[i];
00129         uint64_t unq = bb->getHashCode().getValue();
00130         Function* owner = bb->getFlowGraph()->getFunction();
00131         char names[__MAX_STRING_SIZE];
00132         names[0] = '\0';
00133         owner->getAllSymbolNames(names,__MAX_STRING_SIZE,true);
00134         if(!strlen(names)){
00135             strcpy(names,"__name__unknown__");
00136         }
00137         char* absFile = NULL;
00138         uint32_t absLine  =0;
00139         if(lineInfoFinder){
00140             uint64_t addr = bb->getBaseAddress();
00141             absFile = lineInfoFinder->getFileName(addr);
00142             absLine = lineInfoFinder->getLineNumberInFile(addr);
00143         }
00144 
00145         uint32_t loopId = Invalid_UInteger_ID;
00146         uint32_t loopDepth = 0;
00147         uint32_t loopCount = bb->getFlowGraph()->getNumberOfLoops();
00148 
00149         if(isExtendedPrint()){
00150             for(uint32_t j=0;j<loopCount;j++){
00151                 Loop* currLoop = bb->getFlowGraph()->getLoop(j);
00152                 if(currLoop->isBlockIn(bb->getIndex())){
00153                     loopDepth++;
00154                     loopId = currLoop->getIndex();
00155                 }
00156             }
00157         }
00158 
00159         instBlockFile << i << "\t" << unq 
00160                       << "\t" << bb->getNumOfMemoryOps()
00161                       << "\t" << bb->getNumOfFloatPOps()
00162                       << "\t" << bb->getInstructionCount()
00163                       << "\t" << (absFile ? absFile : "__FILE_UNK__") << ":" << absLine 
00164                       << "\t" << names << "\t#";
00165         if(isExtendedPrint()){
00166             instBlockFile << "\t" << loopCount << "\t" << (int32_t)loopId << "\t" << loopDepth;
00167         }
00168         instBlockFile << "\t 0x" << hex << unq << "\t0x" << bb->getBaseAddress() << dec 
00169                       << endl;    
00170     }
00171     instBlockFile.close();
00172 
00173     char sysCommand[__MAX_STRING_SIZE];
00174     sprintf(sysCommand,"chmod a-w %s",instBlockFileName);
00175 //  system(sysCommand);
00176 }
00177 
00178 void CommonMethods::reserveDataForInstrumentation(){
00179 
00180     extendedDataSize = 0;
00181     extendedBeginAddr = 0;
00182     dataBufferEntryCount = 0;
00183 
00184     uint64_t dataSectionBeginAddr = xcoffFile->getDataSectionVAddr();
00185     uint32_t dataSectionSize = xcoffFile->getDataSectionSize();
00186 
00187     execTOCAddress = xcoffFile->getTOCAddress();
00188 
00189     uint64_t currentFreeAddress = dataSectionBeginAddr + dataSectionSize;
00190 
00191     uint32_t incrementSize = 0;
00192     if (xcoffFile->is64Bit()){
00193         currentFreeAddress = nextAlignAddressDouble(currentFreeAddress);
00194         incrementSize = sizeof(uint64_t);
00195     } else {
00196         currentFreeAddress = nextAlignAddressWord(currentFreeAddress);
00197         incrementSize = sizeof(uint32_t);
00198     }
00199 
00200     extendedBeginAddr = currentFreeAddress;
00201 
00202     for (uint32_t i = 0; i < getNumOfSharedLibFuncs(); i++){
00203         libraryFunctionStubAddrLocs[i] = currentFreeAddress;
00204         currentFreeAddress += incrementSize;
00205     }
00206 
00207     currentFreeAddress = nextAlignAddressWord(currentFreeAddress);
00208 
00209     saveAddressCondReg = currentFreeAddress;
00210     currentFreeAddress += sizeof(uint32_t);
00211     saveAddressFPCondReg = currentFreeAddress;
00212     currentFreeAddress += sizeof(uint32_t);
00213 
00214     currentFreeAddress = nextAlignAddressDouble(currentFreeAddress);
00215 
00216     saveAddressLinkReg = currentFreeAddress;
00217     currentFreeAddress += sizeof(uint64_t);
00218     saveAddressCtrReg = currentFreeAddress;
00219     currentFreeAddress += sizeof(uint64_t);
00220     saveAddressExpReg = currentFreeAddress;
00221     currentFreeAddress += sizeof(uint64_t);
00222 
00223     saveAddressGprRegs = currentFreeAddress;
00224     currentFreeAddress += (sizeof(uint64_t) * NUM_OF_GPR_REGS);
00225     saveAddressFprRegs = currentFreeAddress;
00226     currentFreeAddress += (sizeof(uint64_t) * NUM_OF_FPR_REGS);
00227         
00228     char* ptr = xcoffFile->getXCoffFileName();
00229     char* sepPtr = strrchr(ptr,'/');
00230     if(sepPtr){
00231         ptr = (sepPtr + 1);
00232     }
00233     char tmpStr[__MAX_STRING_SIZE];
00234     if(!phaseIndex){
00235         sprintf(tmpStr,"%s 0 %s %d",ptr,getFileExtension(),
00236                 getNumberOfInstPoints(NULL));
00237     } else {
00238         sprintf(tmpStr,"%s %d %s %d",ptr,getPhaseIndex(),getFileExtension(),
00239                 getNumberOfInstPoints(NULL));
00240     }
00241 
00242     commentAddress = currentFreeAddress;
00243     sharedLibraryInfoStr = strdup(tmpStr);
00244     currentFreeAddress += (strlen(sharedLibraryInfoStr) + 1);
00245 
00246     dataBufferEntryCount = howManyBufferEntry();
00247     incrementSize = bytesPerBufferEntry();
00248 
00249     if(incrementSize == sizeof(uint32_t)){
00250         currentFreeAddress = nextAlignAddressWord(currentFreeAddress);
00251     } else {
00252         currentFreeAddress = nextAlignAddressDouble(currentFreeAddress);
00253     }
00254 
00255     dataBufferAddress = currentFreeAddress;
00256     currentFreeAddress += (dataBufferEntryCount * incrementSize);
00257 
00258     extraBlockInfoAddress = currentFreeAddress;
00259     currentFreeAddress += spaceForBlockInfo();
00260 
00261     currentFreeAddress = nextAlignAddressDouble(currentFreeAddress);
00262 
00263     extendedDataSize = currentFreeAddress - (dataSectionBeginAddr + dataSectionSize);
00264 
00265     tocXorUpdateVal = 0;
00266     if(!Instruction::isInLoadOffsetInsnRange((int32_t)(dataBufferAddress-execTOCAddress))){
00267         tocXorUpdateVal = (uint32_t)(extendedBeginAddr ^ execTOCAddress);
00268         tocDistUpdateVal = (uint32_t)(extendedBeginAddr - execTOCAddress);
00269     }
00270 
00271     PRINT_INFOR("**** Additional data section inc  is %d ***",extendedDataSize);
00272     PRINT_INFOR("**** Number of entries to process is %18d ***",dataBufferEntryCount);
00273     PRINT_INFOR("**** Start address for toc        is %#18llx (%lld) ***",
00274         execTOCAddress,execTOCAddress-dataSectionBeginAddr);
00275     PRINT_INFOR("**** Start address for additional is %#18llx (%lld) ***",
00276         extendedBeginAddr,extendedBeginAddr-execTOCAddress);
00277     PRINT_INFOR("**** The tocXorUpdateVal for save is %x %d ***",
00278         tocXorUpdateVal,tocDistUpdateVal);
00279     PRINT_INFOR("**** Start address for the gprs   is %#18llx (%lld) ***",
00280         saveAddressGprRegs,saveAddressGprRegs-execTOCAddress);
00281     PRINT_INFOR("**** Start address for the comm   is %#18llx (%lld) ***",
00282         commentAddress,commentAddress-execTOCAddress);
00283     PRINT_INFOR("**** Start address for the buffer is %#18llx (%lld) ***",
00284         dataBufferAddress,dataBufferAddress-execTOCAddress);
00285     PRINT_INFOR("**** End address for the buffer   is %#18llx (%lld) ***",
00286         currentFreeAddress,currentFreeAddress-execTOCAddress);
00287 }
00288 
00289 void CommonMethods::updateTOCRegister(Instruction* insnBuffer,uint32_t* insnIndex){
00290     uint16_t tocUpdateValLow = FIRST_HALFWORD(tocXorUpdateVal);
00291     uint16_t tocUpdateValHigh = SECOND_HALFWORD(tocXorUpdateVal);
00292     if(tocXorUpdateVal){
00293         if(tocUpdateValHigh){
00294             insnBuffer[(*insnIndex)++] = Instruction::generateXorImmShifted(REG_TOC,REG_TOC,tocUpdateValHigh);
00295         }
00296         insnBuffer[(*insnIndex)++] = Instruction::generateXorImm(REG_TOC,REG_TOC,tocUpdateValLow);
00297     }
00298 }
00299 void CommonMethods::saveCTRRegister(Instruction* insnBuffer,uint32_t* insnIndex,uint32_t reg){
00300     int32_t saveOffset = getCTRSaveOffset();
00301     insnBuffer[(*insnIndex)++] = Instruction::generateMoveFromSPR(reg,REG_CTR);
00302     insnBuffer[(*insnIndex)++] = Instruction::generateStoreDouble(reg,REG_TOC,saveOffset);
00303 }
00304 void CommonMethods::restCTRRegister(Instruction* insnBuffer,uint32_t* insnIndex,uint32_t reg){
00305     int32_t saveOffset = getCTRSaveOffset();
00306     insnBuffer[(*insnIndex)++] = Instruction::generateLoadDouble(reg,REG_TOC,saveOffset);
00307     insnBuffer[(*insnIndex)++] = Instruction::generateMoveToSPR(reg,REG_CTR);
00308 }
00309 void CommonMethods::saveEXRRegister(Instruction* insnBuffer,uint32_t* insnIndex,uint32_t reg){
00310     int32_t saveOffset = getEXRSaveOffset();
00311     insnBuffer[(*insnIndex)++] = Instruction::generateMoveFromSPR(reg,REG_XER);
00312     insnBuffer[(*insnIndex)++] = Instruction::generateStoreDouble(reg,REG_TOC,saveOffset);
00313 }
00314 void CommonMethods::restEXRRegister(Instruction* insnBuffer,uint32_t* insnIndex,uint32_t reg){
00315     int32_t saveOffset = getEXRSaveOffset();
00316     insnBuffer[(*insnIndex)++] = Instruction::generateLoadDouble(reg,REG_TOC,saveOffset);
00317     insnBuffer[(*insnIndex)++] = Instruction::generateMoveToSPR(reg,REG_XER);
00318 }
00319 void CommonMethods::saveFPSCRRegister(Instruction* insnBuffer,uint32_t* insnIndex,uint32_t reg){
00320     int32_t saveOffset = getFPSCRSaveOffset();
00321     insnBuffer[(*insnIndex)++] = Instruction::generateMoveFromFPSCR(reg);
00322     insnBuffer[(*insnIndex)++] = Instruction::generateStoreWordFloat(reg,REG_TOC,saveOffset);
00323 }
00324 void CommonMethods::restFPSCRRegister(Instruction* insnBuffer,uint32_t* insnIndex,uint32_t reg){
00325     int32_t saveOffset = getFPSCRSaveOffset();
00326     insnBuffer[(*insnIndex)++] = Instruction::generateLoadWordFloat(reg,REG_TOC,saveOffset);
00327     insnBuffer[(*insnIndex)++] = Instruction::generateMoveToFPSCR(reg);
00328 }
00329 void CommonMethods::saveCRRegister(Instruction* insnBuffer,uint32_t* insnIndex,uint32_t reg){
00330     int32_t saveOffset   = getCRSaveOffset();
00331     insnBuffer[(*insnIndex)++] = Instruction::generateMoveFromCR(reg);
00332     insnBuffer[(*insnIndex)++] = Instruction::generateStoreWord(reg,REG_TOC,saveOffset);
00333 }
00334 void CommonMethods::restCRRegister(Instruction* insnBuffer,uint32_t* insnIndex,uint32_t reg){
00335     int32_t saveOffset   = getCRSaveOffset();
00336     insnBuffer[(*insnIndex)++] = Instruction::generateLoadWord(reg,REG_TOC,saveOffset);
00337     insnBuffer[(*insnIndex)++] = Instruction::generateMoveToCR(reg);
00338 }
00339 void CommonMethods::saveLNKRegister(Instruction* insnBuffer,uint32_t* insnIndex,uint32_t reg){
00340     int32_t saveOffset   = getLNKSaveOffset();
00341     insnBuffer[(*insnIndex)++] = Instruction::generateMoveFromSPR(reg,REG_LNK);
00342     insnBuffer[(*insnIndex)++] = Instruction::generateStoreDouble(reg,REG_TOC,saveOffset);
00343 }
00344 void CommonMethods::restLNKRegister(Instruction* insnBuffer,uint32_t* insnIndex,uint32_t reg){
00345     int32_t saveOffset   = getLNKSaveOffset();
00346     insnBuffer[(*insnIndex)++] = Instruction::generateLoadDouble(reg,REG_TOC,saveOffset);
00347     insnBuffer[(*insnIndex)++] = Instruction::generateMoveToSPR(reg,REG_LNK);
00348 }
00349 
00350 
00351 void CommonMethods::generateFuncCallFull(Instruction* insnBuffer,uint32_t* insnIndex,
00352                                                 uint32_t reg,uint64_t stubAddr,uint64_t funcAddr)
00353 {
00354 //    PRINT_INFOR("Generating a function call with args %d %d %#llx %#llx", *insnIndex, reg, stubAddr, funcAddr);
00355 
00356     saveCRRegister(insnBuffer,insnIndex,reg);
00357     saveLNKRegister(insnBuffer,insnIndex,reg);
00358 
00359     updateTOCRegister(insnBuffer,insnIndex);
00360 
00361     uint64_t fromAddr = stubAddr + ((*insnIndex) * sizeof(uint32_t));
00362     uint64_t toAddr   = funcAddr;
00363     insnBuffer[(*insnIndex)++] = Instruction::generateCallToImmediate(fromAddr,toAddr);
00364 
00365     updateTOCRegister(insnBuffer,insnIndex);
00366 
00367     restLNKRegister(insnBuffer,insnIndex,reg);
00368     restCRRegister(insnBuffer,insnIndex,reg);
00369 }
00370 
00371 uint32_t CommonMethods::generateSharedLibFuncWrapper(
00372     uint32_t libFuncIdx,uint64_t funcCallAddr,uint32_t genBufferOffset,BaseGen* gen)
00373 {
00374 
00375 
00376     uint32_t insnCount = 0;
00377     Instruction* insnBuffer = new Instruction[byteCountForSharedLibFuncWrappers() / sizeof(uint32_t)];
00378 
00379     uint32_t scratchReg = 6;
00380     uint32_t fpScratchReg = 3;
00381     uint32_t savedReg = 31;
00382     uint32_t tocHoldReg = 30;
00383     uint32_t firstArgReg = 3;
00384     uint32_t secondArgReg = 4;
00385     uint32_t thirdArgReg = 5;
00386 
00387     ASSERT(scratchReg == 6);
00388     ASSERT(fpScratchReg == 3);
00389     ASSERT(savedReg == 31);
00390     ASSERT(tocHoldReg == 30);
00391     ASSERT(firstArgReg == 3);
00392     ASSERT(secondArgReg == 4);
00393     ASSERT(thirdArgReg == 5);
00394 
00395     int32_t saveOffset = 0x0;
00396 
00397     updateTOCRegister(insnBuffer,&insnCount);
00398 
00399     for(uint32_t i=0;i<=LAST_VOLATILE_REG;i++){
00400         saveOffset = getGPRSaveOffset(i);
00401         insnBuffer[insnCount++] = Instruction::generateStoreDouble(i,REG_TOC,saveOffset);
00402     }
00403     for(uint32_t i=0;i<=LAST_VOLATILE_REG;i++){
00404         saveOffset = getFPRSaveOffset(i);
00405         insnBuffer[insnCount++] = Instruction::generateStoreDoubleFloat(i,REG_TOC,saveOffset);
00406     }
00407 
00408     saveCTRRegister(insnBuffer,&insnCount,scratchReg);
00409     saveEXRRegister(insnBuffer,&insnCount,scratchReg);
00410     saveFPSCRRegister(insnBuffer,&insnCount,fpScratchReg);
00411 
00412     uint32_t bufferOffset = getDataOffsetForInst(0);
00413     insnBuffer[insnCount++] = Instruction::generateMoveReg(REG_TOC,firstArgReg);
00414     insnBuffer[insnCount++] = Instruction::generateIncrement(firstArgReg,bufferOffset);
00415 
00416     uint32_t bufferCount = getDataBufferEntryCount();
00417     insnBuffer[insnCount++] = Instruction::generateLoad32BitHigh(secondArgReg,bufferCount);
00418     insnBuffer[insnCount++] = Instruction::generateLoad32BitLow(secondArgReg,bufferCount);
00419 
00420     uint32_t commentOffset = getCommentAddressOffset();
00421     insnBuffer[insnCount++] = Instruction::generateMoveReg(REG_TOC,thirdArgReg);
00422     insnBuffer[insnCount++] = Instruction::generateIncrement(thirdArgReg,commentOffset);
00423 
00424     insnBuffer[insnCount++] = Instruction::generateMoveFromSPR(savedReg,REG_LNK);
00425     insnBuffer[insnCount++] = Instruction::generateMoveReg(REG_TOC,tocHoldReg);
00426 
00427 
00428     int32_t callOffset = funcCallAddr - execTOCAddress - tocDistUpdateVal;
00429     if(xcoffFile->is64Bit()){
00430         insnBuffer[insnCount++] = Instruction::generateSPIncrementDouble(-SAFE_FRAME_LOC*sizeof(uint64_t));
00431         insnBuffer[insnCount++] = Instruction::generateLoadDouble(scratchReg,REG_TOC,callOffset);
00432         insnBuffer[insnCount++] = Instruction::generateLoadDouble(REG_TOC,scratchReg,sizeof(uint64_t));
00433         insnBuffer[insnCount++] = Instruction::generateLoadDouble(scratchReg,scratchReg,0);
00434     } else {
00435         insnBuffer[insnCount++] = Instruction::generateSPIncrementWord(-SAFE_FRAME_LOC*sizeof(uint64_t));
00436         insnBuffer[insnCount++] = Instruction::generateLoadWord(scratchReg,REG_TOC,callOffset);
00437         insnBuffer[insnCount++] = Instruction::generateLoadWord(REG_TOC,scratchReg,sizeof(uint32_t));
00438         insnBuffer[insnCount++] = Instruction::generateLoadWord(scratchReg,scratchReg,0);
00439     }
00440     insnBuffer[insnCount++] = Instruction::generateMoveToSPR(scratchReg,REG_CTR);
00441     insnBuffer[insnCount++] = Instruction::generateCallToCTR();
00442 
00443     insnBuffer[insnCount++] = Instruction::generateMoveReg(tocHoldReg,REG_TOC);
00444     insnBuffer[insnCount++] = Instruction::generateMoveToSPR(savedReg,REG_LNK);
00445 
00446     restFPSCRRegister(insnBuffer,&insnCount,fpScratchReg);
00447     restEXRRegister(insnBuffer,&insnCount,scratchReg);
00448     restCTRRegister(insnBuffer,&insnCount,scratchReg);
00449 
00450     for(uint32_t i=0;i<=LAST_VOLATILE_REG;i++){
00451         saveOffset = getFPRSaveOffset(i);
00452         insnBuffer[insnCount++] = Instruction::generateLoadDoubleFloat(i,REG_TOC,saveOffset);
00453     }
00454     for(uint32_t i=0;i<=LAST_VOLATILE_REG;i++){
00455         saveOffset = getGPRSaveOffset(i);
00456         insnBuffer[insnCount++] = Instruction::generateLoadDouble(i,REG_TOC,saveOffset);
00457     }
00458     updateTOCRegister(insnBuffer,&insnCount);
00459 
00460     insnBuffer[insnCount++] = Instruction::generateReturnToLnk();
00461 
00462     gen->writeInstructions(genBufferOffset,insnCount,insnBuffer);
00463 
00464     delete[] insnBuffer;
00465 
00466     return (insnCount*sizeof(uint32_t));
00467 }

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