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) 2007-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\x86\uc_i64.cia
//
//
#include "u32std.h"
#include <e32math.h>
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");
asm("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");
asm("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");
asm("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}
asm("divmod64_1:");
asm("call %a0": : "i"(&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");
asm("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");
asm("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 %a0": : "i"(&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");
}