os/kernelhwsrv/kernel/eka/euser/epoc/arm/uc_gcc.cia
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/euser/epoc/arm/uc_gcc.cia	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,146 @@
     1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// e32\euser\epoc\arm\uc_gcc.cia
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include <u32std.h>
    1.22 +#include <e32math.h>
    1.23 +#include "uc_std.h"
    1.24 +
    1.25 +extern "C" {
    1.26 +EXPORT_C __NAKED__ long long __fixdfdi(double /*aVal*/)
    1.27 +	{
    1.28 +	// r0:r1 contains argument, return result in r1:r0
    1.29 +#ifdef __DOUBLE_WORDS_SWAPPED__
    1.30 +	asm("mov r2, r0 ");					// save sign
    1.31 +#else
    1.32 +	asm("mov r2, r1 ");					// save sign
    1.33 +	asm("mov r1, r0 ");
    1.34 +	asm("mov r0, r2 ");
    1.35 +#endif
    1.36 +	asm("bic r0, r0, #0x80000000 ");	// remove sign bit from r0
    1.37 +	asm("mov r3, #0x400 ");				// r3=0x43E = exponent of 2^63
    1.38 +	asm("orr r3, r3, #0x3E ");
    1.39 +	asm("subs r3, r3, r0, lsr #20 ");	// r3=0x43E-exponent = number of right shifts needed
    1.40 +	asm("ble 1f ");						// branch to saturate result if exp>=0x43E
    1.41 +	asm("cmp r3, #63 ");
    1.42 +	asm("bgt 2f ");						// branch to produce zero result if exp<0x3FF
    1.43 +	asm("mov r12, r0, lsl #11 ");		// left justify mantissa in r1:r0
    1.44 +	asm("orr r12, r12, r1, lsr #21 ");
    1.45 +	asm("mov r0, r1, lsl #11 ");
    1.46 +	asm("orr r1, r12, #0x80000000 ");	// put in implied integer bit
    1.47 +	asm("cmp r3, #32 ");				// check if >=32 shifts needed
    1.48 +	asm("subge r3, r3, #32 ");			// if so reduce count by 32
    1.49 +	asm("movge r0, r1, lsr r3 ");		// and shift right by (32+r3)
    1.50 +	asm("movge r1, #0 ");
    1.51 +	asm("rsblt r12, r3, #32 ");			// else shift right by r3
    1.52 +	asm("movlt r0, r0, lsr r3 ");
    1.53 +	asm("orrlt r0, r0, r1, lsl r12 ");
    1.54 +	asm("movlt r1, r1, lsr r3 ");
    1.55 +	asm("movs r2, r2 ");				// test sign bit
    1.56 +	__JUMP(pl,lr);						// if +ve, finished
    1.57 +	asm("rsbs r0, r0, #0 ");			// if -ve, negate
    1.58 +	asm("rsc r1, r1, #0 ");
    1.59 +	__JUMP(,lr);
    1.60 +	asm("2: ");
    1.61 +	asm("mov r0, #0 ");
    1.62 +	asm("mov r1, #0 ");
    1.63 +	__JUMP(,lr);						// return 0
    1.64 +	asm("1: ");							// produce saturated result
    1.65 +	asm("mvn r1, r2, asr #32 ");		// if +ve, r1=FFFFFFFF else r1=0
    1.66 +	asm("mov r0, r1 ");					//
    1.67 +	asm("eor r1, r1, #0x80000000 ");	// if +ve, r1:r0=7FFFFFFF FFFFFFFF else r1:r0=80000000 00000000
    1.68 +	__JUMP(,lr);
    1.69 +	}
    1.70 +
    1.71 +EXPORT_C __NAKED__ double __floatdidf(long long /*a*/)
    1.72 +//
    1.73 +// Convert 64-bit signed integer to double
    1.74 +//
    1.75 +	{
    1.76 +	// r1:r0 = input, return output in r0,r1
    1.77 +	asm("mov r2, #0x40000000 ");		// r2 will hold result exponent
    1.78 +	asm("and r12, r1, #0x80000000 ");	// save sign in r12
    1.79 +	asm("cmp r1, #0 ");					// test for MS word negative or zero
    1.80 +	asm("orr r2, r2, #0x01E00000 ");	// r2=0x41E=exponent of 2^31
    1.81 +	asm("bpl 1f ");						// skip if +
    1.82 +	asm("rsbs r0, r0, #0 ");			// else negate
    1.83 +	asm("rscs r1, r1, #0 ");
    1.84 +	asm("1: ");
    1.85 +	asm("bne 2f ");						// branch if ms word nonzero
    1.86 +	asm("cmp r0, #0 ");					// check if ls word also zero
    1.87 +	__JUMP(eq,lr);
    1.88 +	asm("cmp r0, #0x10000 ");			// normalise r1 and adjust exponent
    1.89 +	asm("movcc r0, r0, lsl #16 ");
    1.90 +	asm("subcc r2, r2, #0x01000000 ");
    1.91 +	asm("cmp r0, #0x1000000 ");
    1.92 +	asm("movcc r0, r0, lsl #8 ");
    1.93 +	asm("subcc r2, r2, #0x00800000 ");
    1.94 +	asm("cmp r0, #0x10000000 ");
    1.95 +	asm("movcc r0, r0, lsl #4 ");
    1.96 +	asm("subcc r2, r2, #0x00400000 ");
    1.97 +	asm("cmp r0, #0x40000000 ");
    1.98 +	asm("movcc r0, r0, lsl #2 ");
    1.99 +	asm("subcc r2, r2, #0x00200000 ");
   1.100 +	asm("cmp r0, #0x80000000 ");
   1.101 +	asm("movcc r0, r0, lsl #1 ");
   1.102 +	asm("subcc r2, r2, #0x00100000 ");
   1.103 +	asm("bic r1, r0, #0x80000000 ");	// remove implied integer bit
   1.104 +	asm("orr r0, r2, r12 ");			// sign+exponent into r0
   1.105 +	asm("orr r0, r0, r1, lsr #11 ");	// top 21 mantissa bits into r0
   1.106 +	asm("mov r1, r1, lsl #21 ");		// remaining 11 mantissa bits in r1
   1.107 +	asm("b 0f ");
   1.108 +	asm("2: ");							// come here if ms word non zero
   1.109 +	asm("mov r3, #32 ");				// r3=32-shift count
   1.110 +	asm("cmp r1, #0x00010000 ");
   1.111 +	asm("movcc r1, r1, lsl #16 ");
   1.112 +	asm("subcc r3, r3, #16 ");
   1.113 +	asm("cmp r1, #0x01000000 ");
   1.114 +	asm("movcc r1, r1, lsl #8 ");
   1.115 +	asm("subcc r3, r3, #8 ");
   1.116 +	asm("cmp r1, #0x10000000 ");
   1.117 +	asm("movcc r1, r1, lsl #4 ");
   1.118 +	asm("subcc r3, r3, #4 ");
   1.119 +	asm("cmp r1, #0x40000000 ");
   1.120 +	asm("movcc r1, r1, lsl #2 ");
   1.121 +	asm("subcc r3, r3, #2 ");
   1.122 +	asm("cmp r1, #0x80000000 ");
   1.123 +	asm("movcc r1, r1, lsl #1 ");
   1.124 +	asm("subcc r3, r3, #1 ");
   1.125 +	asm("add r2, r2, r3, lsl #20 ");	// r2 now holds result exponent
   1.126 +	asm("orr r1, r1, r0, lsr r3 ");		// normalise r1:r0
   1.127 +	asm("rsb r3, r3, #32 ");
   1.128 +	asm("mov r0, r0, lsl r3 ");
   1.129 +	asm("mov r3, r0, lsl #21 ");		// rounding bits into r3
   1.130 +	asm("cmp r3, #0x80000000 ");		// C=1 to round up or halfway, C=0 to round down
   1.131 +	asm("moveqs r3, r0, lsr #12 ");		// if exactly half-way, carry=LSB of mantissa
   1.132 +	asm("addcss r0, r0, #0x800 ");		// if C=1, round up
   1.133 +	asm("adcs r1, r1, #0 ");
   1.134 +	asm("addcs r2, r2, #0x00100000 ");	// if carry, increment exponent
   1.135 +	asm("bic r3, r1, #0x80000000 ");	// remove implied integer bit
   1.136 +	asm("mov r1, r0, lsr #11 ");		// shift mantissa down to correct position
   1.137 +	asm("orr r1, r1, r3, lsl #21 ");
   1.138 +	asm("orr r0, r2, r3, lsr #11 ");	// and put in exponent
   1.139 +	asm("orr r0, r0, r12 ");			// put in sign bit
   1.140 +	asm("0: ");
   1.141 +#ifndef __DOUBLE_WORDS_SWAPPED__
   1.142 +	asm("mov r2, r1 ");					// save sign
   1.143 +	asm("mov r1, r0 ");
   1.144 +	asm("mov r0, r2 ");
   1.145 +#endif
   1.146 +	__JUMP(,lr);
   1.147 +	}
   1.148 +}
   1.149 +