Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// e32\common\arm\cheap.cia
//
//
#include <e32cia.h>
#include "../common.h"
#if defined(__HEAP_MACHINE_CODED__) && !defined(_DEBUG)
GLREF_C void RHeap_PanicBadAllocatedCellSize();
GLREF_C void RHeap_PanicBadNextCell();
GLREF_C void RHeap_PanicBadPrevCell();
GLREF_C void RHeap_PanicBadCellAddress();
IMPORT_D extern const TInt KHeapShrinkHysRatio;
__NAKED__ RHeap::SCell* RHeap::DoAlloc(TInt /*aSize*/, SCell*& /*aLastFree*/)
//
// Allocate a cell.
//
{
asm("stmfd sp!, {r4,r5,lr} ");
asm("mov r4, r0 "); // r4=this
asm("add r3, r0, #%a0" : : "i" _FOFF(RHeap,iFree)); // r3=pP=&iFree
asm("ldr r0, [r3, #4] "); // r0=pC=pP->next
asm("cmp r0, #0 ");
asm("beq 0f "); // if no free cells, alloc failed
// optimised unfolded scanning loop
asm("2: ");
asm("ldmia r0, {r12,r14} "); // r12=pC->size, r14=pC->next
asm("cmp r1, r12 "); // compare aSize to size
asm("movhi r3, r0 "); // if aSize>size, pP=pC
asm("movhis r0, r14 "); // and pC=pC->next
#ifndef __CPU_ARMV6 // don't unroll on armv6
asm("ldmhiia r0, {r12,r14} "); // r12=pC->size, r14=pC->next
asm("cmphi r1, r12 "); // compare aSize to size
asm("movhi r3, r0 "); // if aSize>size, pP=pC
asm("movhis r0, r14 "); // and pC=pC->next
#endif
asm("bhi 2b "); // branch back if scan not finished
asm("1: ");
asm("subs r5, r12, r1 "); // r5 = pC->len - aSize
asm("ldrhs r2, [r4, #%a0]" : : "i" _FOFF(RHeap,iMinCell)); // if big enough, r2=iMinCell
asm("blo 0f "); // branch if no free cell was big enough
asm("cmp r5, r2 "); // leftover big enough?
asm("movlo r1, r12 "); // if not, aSize=pC->len ...
asm("strlo r14, [r3, #4] "); // ... and pP->next = pC->next
asm("addhs r2, r0, r1 "); // else r2 = pE = address of new free cell ...
asm("stmhsia r2, {r5, r14} "); // ... pE->len = pC->len - aSize, pE->next = pC->next ...
asm("strhs r2, [r3, #4] "); // ... and pP->next = pE
asm("str r1, [r0] "); // pC->len = aSize
__POPRET("r4,r5,"); // restore and exit, return pC
asm("0: ");
asm("str r3, [r2] "); // alloc failed - aLastFree=pP
asm("mov r0, #0 "); // return NULL
__POPRET("r4,r5,");
}
__NAKED__ void RHeap::DoFree(SCell* /*pC*/)
//
// Free a cell.
//
{
asm("add r2, r0, #%a0" : : "i" _FOFF(RHeap,iFree)); // r2=pP=&iFree
asm("ldr r3, [r2, #4] "); // r3=pE=pP->next
asm("stmfd sp!, {r4, r5} ");
asm("1: ");
asm("cmp r3, #0 "); // check if pE=NULL
asm("cmphi r1, r3 "); // if not, check if pC>pE
asm("movhi r2, r3 "); // if so, pP=pE
asm("ldrhi r3, [r3, #4] "); // and pE=pE->next
#ifndef __CPU_ARMV6 // don't unroll on armv6
asm("cmphi r3, #0 "); // check if pE=NULL
asm("cmphi r1, r3 "); // if not, check if pC>pE
asm("movhi r2, r3 "); // if so, pP=pE
asm("ldrhi r3, [r3, #4] "); // and pE=pE->next
#endif
asm("bhi 1b "); // loop if free cell position not found
asm("ldr r4, [r1, #0] "); // r4=pC->len
asm("cmp r3, #0 "); // is there a following free cell ?
asm("streq r3, [r1, #4] "); // if not, pC->next=NULL
asm("beq 2f "); // and skip next section
asm("add r5, r1, r4 "); // r5=pN=pC + pC->len (cell after pC)
asm("cmp r5, r3 "); // compare pN with pE
asm("ldmeqia r3, {r5, r12} "); // if pN==pE, r5=pE->len, r12=pE->next
asm("bhi " CSM_Z22RHeap_PanicBadNextCellv ); // if pN>pE, panic
asm("strne r3, [r1, #4] "); // if pN<pE, pC->next=pE
asm("addeq r4, r4, r5 "); // if pN==pE r4 = pC->len + pE->len
asm("stmeqia r1, {r4,r12} "); // if pN==pE pC->len+=pE->len, pC->next=pE->next
asm("2: ");
asm("ldr r3, [r2, #0] "); // r3=pP->len
asm("sub r5, r1, r2 "); // r5=pC-pP (gap between preceding free cell and this one)
asm("cmp r5, r3 "); // compare gap with predecessor length
asm("ldreq r12, [r1, #4] "); // if predecessor is adjacent, r12=pC->next
asm("blo RHeap_PanicBadPrevCell__Fv "); // if predecessor overlaps, panic
asm("addeq r4, r4, r3 "); // if predecessor is adjacent, r4=pC->len + pP->len
asm("stmeqia r2, {r4,r12} "); // if predecessor is adjacent, pP->len+=pC->len, pP->next=pC->next
asm("strne r1, [r2, #4] "); // else pP->next = pC
asm("moveq r1, r2 "); // if predecessor is adjacent, pC=pP (final amalgamated free cell)
asm("3: ");
asm("ldr r12, [r0, #%a0]" : : "i" _FOFF(RHeap,iTop)); // r12=iTop
asm("add r3, r1, r4 "); // end of amalgamated free cell
asm("cmp r3, r12 "); // end of amalgamated free cell = iTop ?
asm("ldmneia sp!, {r4,r5} "); // restore registers
__JUMP(ne,lr); // if not, finished
asm("ldr r12, [r0, #%a0]" : : "i" _FOFF(RHeap,iFlags)); // r12=iFlags
asm("tst r12, #%a0" : : "i" ((TInt)RAllocator::EFixedSize)); // check fixed size flag
asm("ldmneia sp!, {r4,r5} "); // restore registers
__JUMP(ne,lr); // if set, finished
asm("ldr r2, [r0, #%a0]" : : "i" _FOFF(RHeap,iGrowBy)); // r2=iGrowBy
asm("mov r3, r2, LSR #8"); // r3=iGrowBy>>8
asm("ldr r2, const_addr"); // r2=&KHeapShrinkHysRatio
asm("ldr r5, [r2]"); // r5=KHeapShrinkHysRatio
asm("mul r2, r5, r3"); // r2=KHeapShrinkHysRatio*(iGrowBy>>8) - low order bits
asm("cmp r4, r2"); // compare len(r4) to (iGrowBy>>8)*KHeapShrinkHysRatio(r2)
asm("ldmia sp!, {r4,r5} "); // restore registers
__JUMP(lo,lr); // if less, finished
asm("b Reduce__5RHeapPQ25RHeap5SCell "); // else reduce heap
asm("const_addr:");
asm(".word %a0" : : "i" ((TInt)&KHeapShrinkHysRatio));
}
#endif