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));
}
Esempio n. 5
0
// 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));
    }
}