Skip to main content

StrictMath.exp() failed

6 replies [Last post]
ssc123
Offline
Joined: 2006-12-08

Hi all:
I've built phoneme advanced mr1 with JIT enabled on TI DaVinci 6446 board.
The return value of StrictMath.exp() is not correct.

long result = Double.doubleToLongBits(StrictMath.exp(Double.longBitsToDouble(0xc086280624dd2feaL)));

On x86, I will get "2455414353530514", but on DaVinci, I will get "2455414353530515".

Here is DaVinci environment info.
CPU: ARM926EJ-S
GCC:
arm_v5t_le-gcc (GCC) 3.4.3 (MontaVista 3.4.3-25.0.30.0501131 2005-07-23)
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Thank you.

aries

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
cjplummer
Offline
Joined: 2006-10-16

Hi Aries,

Try adding the following to your GNUmakefile:

CVM_DEFINES += -DAAPCS

It is needed on platforms that use AAPCS calling conventions rather than APCS. Unfortunately we have not been able to find a way to detect the need for it in the source (like you can for things like VFP and endianness), so it must be manually added when needed.

Chris Plummer

cjplummer
Offline
Joined: 2006-10-16

After thinking about this some more, I don't think AAPCS is the problem. Not setting AAPCS results in completly wrong answers, not rounding errors. I think this is a bug in the gcc arm soft float support (and there have been many over the years). You'll need to rebuild gcc to fix these problems. There are two choices: (1) revert to using the C version of the arm softfloat support, or (2) apply patches to the assembler version.

Here are the modifications need to force gcc 3.3.2 to use the C version of the soft float point library. I'm not sure if this needs to be done differently for gcc 3.4.3:

Step 1. Change the LIB1ASMFUNCS in gcc/config/arm/t-linux to disable the ASM soft float library functions.

-LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx \
- _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi
_fixunsdfsi \
- _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
- _fixsfsi _fixunssfsi
+LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx

Step 2. Add the following lines in gcc/config/arm/t-linux to enable C soft float library functions.

+FPBIT = fp-bit.c
+DPBIT = dp-bit.c
+
+fp-bit.c:$(srcdir)/config/fp-bit.c
+ echo '#define FLOAT' > fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+dp-bit.c:$(srcdir)/config/fp-bit.c
+ cat $(srcdir)/config/fp-bit.c >> dp-bit.c
+TARGET_LIBGCC2_CFLAGS = -Dinhibit_libc -fno-inline

Here is the diff to apply to gcc 3.4.2 ieee754-df.S to fix some bugs in the ASM version of the soft float library. I'm not 100% certain this one fixes all problems. I've been using a different set of patches which were applied to gcc 3.3.4 (which had a lot more problems than 3.4.2). However, since you are using 3.4.3, I thought this patch might be a better first start.

3c3
< Copyright (C) 2003, 2004 Free Software Foundation, Inc.
---
> Copyright (C) 2003 Free Software Foundation, Inc.
574a575
> movle lr, lr, lsl #12
656c657,658
< 2: rsb r5, r4, #32
---
> 2: bic r2, xh, #0x80000000
> rsb r5, r4, #32
659,660c661,662
< orr r3, r3, xh, lsl r5
< mov xl, xh, lsr r4
---
> orr r3, r3, r2, lsl r5
> mov xl, r2, lsr r4
662,663c664,665
< bic xl, xl, xh, lsr r4
< add xl, xl, r3, lsr #31
---
> adds xl, xl, r3, lsr #31
> adc xh, xh, #0
942a945
> FUNC_START gedf2
944d946
< ARM_FUNC_ALIAS gedf2 gtdf2
947a950
> FUNC_START ledf2
949d951
< ARM_FUNC_ALIAS ledf2 ltdf2
952a955,956
> FUNC_START nedf2
> FUNC_START eqdf2
954,955d957
< ARM_FUNC_ALIAS nedf2 cmpdf2
< ARM_FUNC_ALIAS eqdf2 cmpdf2

Chris Plummer

ssc123
Offline
Joined: 2006-12-08

Hi, Chris:
I've already defined CVM_DEFINES += -DAAPCS because of DaVinci uses montavista. I will try your suggestion later. Thanks for your help.
Aries

ssc123
Offline
Joined: 2006-12-08

Hi
I think this forum was crashed because part of messages were lost. Anyway, after tracing, I found there is an inaccuracy in __ieee754_exp() in E_exp.c.
The last line of __ieee754_exp() is "return y*twom1000;".
In DaVinci platform, I will get "1.213135878384921e-308".
But in x86 platform, I will get "1.21313587838492e-308".
Any suggestion? Thank you.
Aries

cjplummer
Offline
Joined: 2006-10-16

Yes, the server crashed, and it appears about a days worth of stuff was lost.

I don't understand why you are back in __ieee754_exp() when you tracked the problem to a simple Java example that did not invovle StrictMath or exp(). I believe it was Long.toHexString() that was not working correctly.

If the problem is the compatution of y*twom1000, then we are back to the usual suspect of the gcc arm softfloat support. Have you applied the patches I mentioned yet?

Chris Plummer

ssc123
Offline
Joined: 2006-12-08

Hi, Chris:
I think the computation of y*twom1000 is wrong on TI DaVinci board. I think there is inaccuracy in double multiplication. I use two 32 bits long to simulate double multiplication. Now the TCK passed. Really appreciate for you great help. Thanks.
Aries