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) 1997-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\euser\epoc\win32\uc_i64.cpp
//
//
#include "u32std.h"
#include <e32math.h>
#pragma warning ( disable : 4100 ) // unreferenced formal parameter
#pragma warning ( disable : 4414 ) // short jump to function converted to near
extern "C" void UDiv64();
EXPORT_C __NAKED__ void Math::Mul64(Int64 /*aX*/, Int64 /*aY*/, Int64& /*aOutH*/, Uint64& /*aOutL*/)
/**
Multiply aX by aY to generate a 128 bit result.
The high order 64 bits of this calculation are stored in aOutH,
and the low order 64 bits are stored in aOutL.
@param aX The first 64-bit operand.
@param aY The second 64-bit operand.
@param aOutH The high order 64 bits of the result.
@param aOutL The low order 64 bits of the result.
*/
{
_asm mov eax, [esp+4]
_asm mul dword ptr [esp+12] // edx:eax = x0*y0
_asm push edi
_asm push esi
_asm push ebx // [esp+16]=&aX, [esp+24]=&aY, [esp+32]=&aOutH, [esp+36]=&aOutL
_asm mov ecx, eax
_asm mov ebx, edx // ebx:ecx = x0*y0
_asm mov eax, [esp+16]
_asm mul dword ptr [esp+28] // edx:eax = x0*y1
_asm xor esi, esi
_asm add ebx, eax
_asm adc esi, edx // esi:ebx:ecx = x0*y
_asm mov eax, [esp+20] // eax=x1
_asm imul dword ptr [esp+28] // edx:eax = x1*y1
_asm mov edi, edx
_asm add esi, eax
_asm adc edi, 0 // partial result in edi:esi:ebx:ecx
_asm cmp dword ptr [esp+28], 0 // y<0 ?
_asm jns mul64_ypos
_asm sub esi, [esp+16] // if so, subtract x0<<64
_asm sbb edi, 0
mul64_ypos:
_asm mov eax, [esp+20] // eax=x1
_asm cmp eax, 0 // x<0 ?
_asm jns mul64_xpos
_asm sub esi, [esp+24] // if so, subtract y0<<64
_asm sbb edi, 0
mul64_xpos:
_asm mul dword ptr [esp+24] // edx:eax = x1*y0
_asm add ebx, eax
_asm mov eax, [esp+32] // eax=&aOutH
_asm adc esi, edx
_asm mov edx, [esp+36] // edx=&aOutL
_asm adc edi, 0 // full result now in edi:esi:ebx:ecx
_asm mov [eax], esi
_asm mov [eax+4], edi // store high 64
_asm mov [edx], ecx
_asm mov [edx+4], ebx // store low 64
_asm pop ebx
_asm pop esi
_asm pop edi
_asm ret
}
EXPORT_C __NAKED__ void Math::UMul64(Uint64 /*aX*/, Uint64 /*aY*/, Uint64& /*aOutH*/, Uint64& /*aOutL*/)
/**
Multiply aX by aY to generate a 128 bit result.
The high order 64 bits of this calculation are stored in aOutH,
and the low order 64 bits are stored in aOutL.
@param aX The first 64-bit operand.
@param aY The second 64-bit operand.
@param aOutH The high order 64 bits of the result.
@param aOutL The low order 64 bits of the result.
*/
{
_asm mov eax, [esp+4]
_asm mul dword ptr [esp+12] // edx:eax = x0*y0
_asm push edi
_asm push esi
_asm push ebx // [esp+16]=&aX, [esp+24]=&aY, [esp+32]=&aOutH, [esp+36]=&aOutL
_asm mov ecx, eax
_asm mov ebx, edx // ebx:ecx = x0*y0
_asm mov eax, [esp+16]
_asm mul dword ptr [esp+28] // edx:eax = x0*y1
_asm xor esi, esi
_asm add ebx, eax
_asm adc esi, edx // esi:ebx:ecx = x0*y
_asm mov eax, [esp+20] // eax=x1
_asm mul dword ptr [esp+28] // edx:eax = x1*y1
_asm mov edi, edx
_asm add esi, eax
_asm adc edi, 0 // partial result in edi:esi:ebx:ecx
_asm mov eax, [esp+20]
_asm mul dword ptr [esp+24] // edx:eax = x1*y0
_asm add ebx, eax
_asm mov eax, [esp+32] // eax=&aOutH
_asm adc esi, edx
_asm mov edx, [esp+36] // edx=&aOutL
_asm adc edi, 0 // full result now in edi:esi:ebx:ecx
_asm mov [eax], esi
_asm mov [eax+4], edi // store high 64
_asm mov [edx], ecx
_asm mov [edx+4], ebx // store low 64
_asm pop ebx
_asm pop esi
_asm pop edi
_asm ret
}
EXPORT_C __NAKED__ Int64 Math::DivMod64(Int64 /*aDividend*/, Int64 /*aDivisor*/, Int64& /*aRemainder*/)
/**
Divides aDividend by aDivisor.
The quotient is returned, and the remainder is stored in aRemainder.
The remainder has same sign as the dividend.
@param aDividend The 64-bit dividend.
@param aDivisor The 64-bit divisor.
@param aRemainder The 64-bit remainder.
@return The 64-bit quotient.
*/
{
_asm mov eax, [esp+4]
_asm mov edx, [esp+8] // edx:eax = dividend
_asm cmp edx, 0
_asm jns divmod64_0
_asm neg edx
_asm neg eax
_asm sbb edx, 0
divmod64_0: // edx:eax = ABS(dividend)
_asm push edi
_asm push esi
_asm push ebx
_asm push ebp
_asm mov esi, [esp+28]
_asm mov edi, [esp+32] // edi:esi = dividend
_asm cmp edi, 0
_asm jns divmod64_1
_asm neg edi
_asm neg esi
_asm sbb edi, 0 // edi:esi = ABS(dividend)
divmod64_1:
_asm call UDiv64 // do division, quotient in ebx:eax remainder in edi:edx
_asm xchg ebx, edx // quotient in edx:eax, remainder in edi:ebx
_asm mov ecx, [esp+24] // ecx=dividend high
_asm xor ecx, [esp+32] // ecx=dividend high ^ divisor high
_asm jns divmod64_2
_asm neg edx
_asm neg eax
_asm sbb edx, 0
divmod64_2: // edx:eax = quotient with correct sign
_asm cmp dword ptr [esp+24], 0
_asm jns divmod64_3
_asm neg edi
_asm neg ebx
_asm sbb edi, 0
divmod64_3: // edi:ebx = remainder with correct sign
_asm mov ecx, [esp+36] // ecx=&aRemainder
_asm mov [ecx], ebx
_asm mov [ecx+4], edi
_asm pop ebp
_asm pop ebx
_asm pop esi
_asm pop edi
_asm ret
}
EXPORT_C __NAKED__ Uint64 Math::UDivMod64(Uint64 /*aDividend*/, Uint64 /*aDivisor*/, Uint64& /*aRemainder*/)
/**
Divides aDividend by aDivisor.
The quotient is returned, and the remainder is stored in aRemainder.
@param aDividend The 64-bit dividend.
@param aDivisor The 64-bit divisor.
@param aRemainder The 64-bit remainder.
@return The 64-bit quotient.
*/
{
_asm mov eax, [esp+4]
_asm mov edx, [esp+8] // edx:eax = dividend
_asm push edi
_asm push esi
_asm push ebx
_asm push ebp
_asm mov esi, [esp+28]
_asm mov edi, [esp+32] // edi:esi = dividend
_asm call UDiv64 // do division, quotient in ebx:eax remainder in edi:edx
_asm xchg ebx, edx // quotient in edx:eax, remainder in edi:ebx
_asm mov ecx, [esp+36] // ecx=&aRemainder
_asm mov [ecx], ebx
_asm mov [ecx+4], edi
_asm pop ebp
_asm pop ebx
_asm pop esi
_asm pop edi
_asm ret
}
#pragma warning ( default : 4100 )
#pragma warning ( default : 4414 )