void PrologEpilogGenerator::saveRestorePreservedBr() { RegBitSet regMask = usedBrMask & opndManager->preservBrMask; if(regMask.any() == false) return; IPF_LOG << " Preserved brs:"; for(uint16 i=1; i<6; i++) { if(regMask[i] == false) continue; Opnd *storage = newStorage(DATA_B, SITE_STACK); Opnd *offset = opndManager->newImm(storage->getValue()); Opnd *scratch = opndManager->newRegOpnd(OPND_G_REG, DATA_B, SPILL_REG2); Opnd *preserv = opndManager->newRegOpnd(OPND_B_REG, DATA_B, i); saveBrsInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, scratch, preserv)); saveBrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); saveBrsInsts.push_back(new(mm) Inst(mm, INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); restBrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); restBrsInsts.push_back(new(mm) Inst(mm, INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); restBrsInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, preserv, scratch)); IPF_LOG << " " << IrPrinter::toString(preserv); } IPF_LOG << endl; opndManager->savedBrMask = regMask.to_ulong(); }
void PrologEpilogGenerator::saveRestorePreservedGr() { opndManager->initSavedBase(); // after this point mem local stack must contain preserved regs only IPF_LOG << " Preserved register saved in memory stack with offset: " << opndManager->savedBase << endl; RegBitSet preservGrMask(string("11110000")); // work with r4-r7 only (not with automatic regs r32-r127) RegBitSet regMask = usedGrMask & preservGrMask; if(regMask.any() == false) return; IPF_LOG << " Preserved grs:"; for(uint16 i=4; i<8; i++) { if(regMask[i] == false) continue; Opnd *storage = newStorage(DATA_U64, SITE_STACK); Opnd *offset = opndManager->newImm(storage->getValue()); Opnd *preserv = opndManager->newRegOpnd(OPND_G_REG, DATA_U64, i); saveGrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); saveGrsInsts.push_back(new(mm) Inst(mm, INST_ST8_SPILL, p0, stackAddr, preserv)); restGrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); restGrsInsts.push_back(new(mm) Inst(mm, INST_LD8_FILL, p0, preserv, stackAddr)); IPF_LOG << " " << IrPrinter::toString(preserv); } IPF_LOG << endl; opndManager->savedGrMask = regMask.to_ulong(); }
Opnd* PrologEpilogGenerator::saveRestorePfs() { if (containCall == false) { // method does not contain "call" - do not save AR.PFS return opndManager->newRegOpnd(OPND_G_REG, DATA_U64, SPILL_REG2); } RegBitSet regMask = usedGrMask; for(uint16 i=4; i<8; i++) regMask[i] = 1; // do not use preserved gr for saving AR.PFS Opnd *pfs = opndManager->newRegOpnd(OPND_A_REG, DATA_U64, AR_PFS_NUM); RegOpnd *pfsBak = newStorage(DATA_U64, SITE_REG); opndManager->pfsBak = pfsBak->getLocation(); // set the location as storage of AR.PFS if (pfsBak->isMem()) { Opnd *offset = opndManager->newImm(pfsBak->getValue()); Opnd *scratch = opndManager->newRegOpnd(OPND_G_REG, DATA_B, SPILL_REG2); savePfsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); savePfsInsts.push_back(new(mm) Inst(mm, INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); restPfsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); restPfsInsts.push_back(new(mm) Inst(mm, INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); restPfsInsts.push_back(new(mm) Inst(mm, INST_MOV_I, p0, pfs, scratch)); return scratch; } else { restPfsInsts.push_back(new(mm) Inst(mm, INST_MOV_I, p0, pfs, pfsBak)); return pfsBak; } }
void PrologEpilogGenerator::saveRestoreUnat() { RegBitSet preservGrMask(string("11110000")); // work with r4-r7 only (not with automatic regs r32-r127) RegBitSet regMask = usedGrMask & preservGrMask; if(regMask.any() == false) return; RegOpnd *storage = newStorage(DATA_U64, SITE_STACK); Opnd *offset = opndManager->newImm(storage->getValue()); Opnd *unat = opndManager->newRegOpnd(OPND_A_REG, DATA_U64, AR_UNAT_NUM); Opnd *scratch = opndManager->newRegOpnd(OPND_G_REG, DATA_U64, SPILL_REG2); opndManager->unatBak = storage->getLocation(); saveUnatInsts.push_back(new(mm) Inst(mm, INST_MOV_M, p0, scratch, unat)); saveUnatInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); saveUnatInsts.push_back(new(mm) Inst(mm, INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); restUnatInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); restUnatInsts.push_back(new(mm) Inst(mm, INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); restUnatInsts.push_back(new(mm) Inst(mm, INST_MOV_M, p0, unat, scratch)); }
// Acquires a stream to write to. This method is thread-safe. LEAN_ALWAYS_LINK log_details::output_stream& log_details::acquireStream() { scoped_sl_lock lock(m_streamLock); if (m_freeStreams.empty()) { std::auto_ptr<string_storage> newStorage(new string_storage()); // Make sure m_freeStreams.capacity() >= m_streams.size() // + Never add invalid element to m_streams m_freeStreams.reserve(m_streams.size() + 1); m_streams.push_back(newStorage.get()); return newStorage.release()->stream; } else { output_stream *stream = m_freeStreams.back(); m_freeStreams.pop_back(); return *stream; } }
void PrologEpilogGenerator::saveRestorePreservedFr() { RegBitSet regMask = usedFrMask & opndManager->preservFrMask; if(regMask.any() == false) return; IPF_LOG << " Preserved frs:"; for(uint16 i=2; i<32; i++) { if(regMask[i] == false) continue; Opnd *storage = newStorage(DATA_F, SITE_STACK); Opnd *offset = opndManager->newImm(storage->getValue()); Opnd *preserv = opndManager->newRegOpnd(OPND_F_REG, DATA_F, i); saveFrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); saveFrsInsts.push_back(new(mm) Inst(mm, INST_STF_SPILL, p0, stackAddr, preserv)); restFrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); restFrsInsts.push_back(new(mm) Inst(mm, INST_LDF_FILL, p0, preserv, stackAddr)); IPF_LOG << " " << IrPrinter::toString(preserv); } IPF_LOG << endl; opndManager->savedFrMask = regMask.to_ulong(); }
void PrologEpilogGenerator::saveRestorePr() { RegBitSet regMask = usedPrMask & opndManager->preservPrMask; if(regMask.any() == false) return; // method does not use preserved pr RegOpnd *prBak = newStorage(DATA_U64, SITE_REG); // opnd to store prs opndManager->prBak = prBak->getLocation(); // set prBak as storage of prs if (prBak->isMem()) { Opnd *offset = opndManager->newImm(prBak->getValue()); Opnd *scratch = opndManager->newRegOpnd(OPND_G_REG, DATA_B, SPILL_REG2); savePrsInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, scratch, p0)); savePrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); savePrsInsts.push_back(new(mm) Inst(mm, INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); restPrsInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); restPrsInsts.push_back(new(mm) Inst(mm, INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); restPrsInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, p0, scratch)); } else { savePrsInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, prBak, p0)); restPrsInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, p0, prBak)); } }
void PrologEpilogGenerator::saveRestoreRp() { if(containCall == false) return; // method does not contain "call" - nothing to do RegOpnd *b0 = opndManager->getB0(); // return pointer to be saved RegOpnd *rpBak = newStorage(DATA_B, SITE_REG); // opnd to store return pointer opndManager->rpBak = rpBak->getLocation(); // set rpBak as storage of return pointer if (rpBak->isMem()) { Opnd *offset = opndManager->newImm(rpBak->getValue()); Opnd *scratch = opndManager->newRegOpnd(OPND_G_REG, DATA_B, SPILL_REG2); saveRpInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, scratch, b0)); saveRpInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); saveRpInsts.push_back(new(mm) Inst(mm, INST_ST, CMPLT_SZ_8, p0, stackAddr, scratch)); restRpInsts.push_back(new(mm) Inst(mm, INST_ADDS, p0, stackAddr, offset, sp)); restRpInsts.push_back(new(mm) Inst(mm, INST_LD, CMPLT_SZ_8, p0, scratch, stackAddr)); restRpInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, b0, scratch)); } else { saveRpInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, rpBak, b0)); restRpInsts.push_back(new(mm) Inst(mm, INST_MOV, p0, b0, rpBak)); } }