Float compare bug?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

I'm having a problem with the greater or equal operator (>=) with float arguments. I'm using

GCC 3.3.2
newlib 1.12.0
ARM7TDMI-S processor
little endian mode

It seems that:

float test = 7.2;
if(test >= 7.2)

the condition will return false. I have this snippet of code to try to figure out what's going on:

void
App::Initialize()
{
float test = 7.2;
if(test >= 7.2) "mov r1, #0");
else "mov r1, #1");
}

this is the code dump ...

0000034c <_ZN3App10InitializeEv>:
34c: e1a0c00d mov ip, sp
350: e92dd800 stmdb sp!, {fp, ip, lr, pc}
354: e28f002c add r0, pc, #44 ; 0x2c
358: e8900003 ldmia r0, {r0, r1}
35c: e24cb004 sub fp, ip, #4 ; 0x4
360: e28f2028 add r2, pc, #40 ; 0x28
364: e892000c ldmia r2, {r2, r3}
368: eb003457 bl d4cc <__gedf2>
36c: e3500000 cmp r0, #0 ; 0x0
370: ba000002 blt 380 <_ZN3App10InitializeEv+0x34>
374: e3a01000 mov r1, #0 ; 0x0
378: e91b6800 ldmdb fp, {fp, sp, lr}
37c: e12fff1e bx lr
380: e3a01001 mov r1, #1 ; 0x1
384: eafffffb b 378 <_ZN3App10InitializeEv+0x2c>
388: 401ccccc andmis ip, ip, ip, asr #25
38c: c0000000 andgt r0, r0, r0
390: 401ccccc andmis ip, ip, ip, asr #25
394: cccccccd stcgtl 12, cr12, [ip], #820

I set a breakpoint on address 368 then dump the registers.

User FIQ Superv Abort IRQ Undef
GPR00: 401ccccc 401ccccc 401ccccc 401ccccc 401ccccc 401ccccc
GPR01: c0000000 c0000000 c0000000 c0000000 c0000000 c0000000
GPR02: 401ccccc 401ccccc 401ccccc 401ccccc 401ccccc 401ccccc
GPR03: cccccccd cccccccd cccccccd cccccccd cccccccd cccccccd
GPR04: e002c000 e002c000 e002c000 e002c000 e002c000 e002c000
GPR05: 7ffffd24 7ffffd24 7ffffd24 7ffffd24 7ffffd24 7ffffd24
GPR06: 40000128 40000128 40000128 40000128 40000128 40000128
GPR07: 00000000 00000000 00000000 00000000 00000000 00000000
GPR08: 08000800 cbeb48f7 08000800 08000800 08000800 08000800
GPR09: 08000800 6f68fdad 08000800 08000800 08000800 08000800
GPR10: 08000800 a0700340 08000800 08000800 08000800 08000800
GPR11: 4000ee30 4000fec8 4000ee30 4000ee30 4000ee30 4000ee30
GPR12: 4000ee34 4000fecc 4000ee34 4000ee34 4000ee34 4000ee34
GPR13: eb20475f 4000ff00 4000ee24 f0aef6f0 4000f700 40001800
GPR14: 7700403b 00004bb8 0000700c 0000007c 00000090 7fffe258
PC : 00000368
CPSR : 20000013
SPSR : 00000010 00000010 00000010 80000013 00000010

Looking at the code dump r0 and r2 has the arguments for the compare function (am I correct?),
which are both 0x401CCCCC. I then set the breakpoint again on 36C and here's the register dump

User FIQ Superv Abort IRQ Undef
GPR00: ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff
GPR01: 00000000 00000000 00000000 00000000 00000000 00000000
GPR02: 1ccccccc 1ccccccc 1ccccccc 1ccccccc 1ccccccc 1ccccccc
GPR03: 1cccccc0 1cccccc0 1cccccc0 1cccccc0 1cccccc0 1cccccc0
GPR04: e002c000 e002c000 e002c000 e002c000 e002c000 e002c000
GPR05: 7ffffd24 7ffffd24 7ffffd24 7ffffd24 7ffffd24 7ffffd24
GPR06: 40000128 40000128 40000128 40000128 40000128 40000128
GPR07: 00000000 00000000 00000000 00000000 00000000 00000000
GPR08: 08000800 cbeb48f7 08000800 08000800 08000800 08000800
GPR09: 08000800 6f68fdad 08000800 08000800 08000800 08000800
GPR10: 08000800 a0700340 08000800 08000800 08000800 08000800
GPR11: 4000ee30 4000fec8 4000ee30 4000ee30 4000ee30 4000ee30
GPR12: 4000edf8 4000fecc 4000edf8 4000edf8 4000edf8 4000edf8
GPR13: eb20475f 4000ff00 4000ee24 f0aef6f0 4000f700 40001800
GPR14: 7700403b 00004bb8 0000e2b0 0000007c 00000090 7fffe258
PC : 0000036c
CPSR : 60000013
SPSR : 00000010 00000010 00000010 20000013 00000010

r0 contains 0xFFFFFFFF indicating false. To make this work properly,
I just changed the code to (cast on the constant):

void App::Initialize()
{
float test = 7.2;
if(test >= (float)7.2) "mov r1, #0");
else "mov r1, #1");
}

Now do I have to cast all my constant floats? Is this a bug? Thanks.

-John G-








[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux