This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/44364] Wrong code with e500 double floating point
- From: "Kyle dot D dot Moffett at boeing dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 3 Jun 2010 19:26:33 -0000
- Subject: [Bug target/44364] Wrong code with e500 double floating point
- References: <bug-44364-14399@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #3 from Kyle dot D dot Moffett at boeing dot com 2010-06-03 19:26 -------
(In reply to comment #0)
> So after looking at the code I saw now the following:
> 10000c24 <__floatdidf>:
> 10000c6c: 11 23 1a 2c evmergehi r9,r3,r3
>
> This function is touching the complete 64bit r9 register
> The code which calls it:
>
> 10000a40: 91 21 00 20 stw r9,32(r1)
> 10000a44: 4e 80 04 21 bctrl # tell function which in turn calls
> floatdidf
>
> 10000a7c: 81 21 00 20 lwz r9,32(r1)
> 10000a80: 38 60 00 00 li r3,0
> 10000a84: 7e 33 8b 78 mr r19,r17
> 10000a88: 12 49 92 e1 efdsub r18,r9,r18
> 10000a8c: 10 80 92 fa efdctsiz r4,r18
> 10000a90: 12 49 4a 17 evmr r18,r9
>
> So we just save the lower 32bit of r9 before calling the function and the upper
> 32bit are overwritten by efdsub.
Ok, here's the e500 ABI user guide:
http://www.freescale.com/files/32bit/doc/ref_manual/E500ABIUG.pdf
According to that guide, we have the following usage of GPRs:
Dedicated: r1 r2 r13
Nonvolatile: r14-r31
Volatile: r0 r3-r12
Then:
Before a function changes the value in the upper word of any nonvolatile
general register, rn, it shall save the 64-bit value in rn in the 64-bit
general register save area 8*(32-n) bytes below the CR save area (plus any
required padding). The 64-bit general save area shall have 8-byte alignment.
And:
Before a function changes the value in the lower word of any nonvolatile
general register, rn, that has not already been saved in the 64-bit general
register save area, it shall save the value in the lower word of rn in the word
in the 32-bit general register save area 4*(32-n) bytes before the back chain
word of the previous frame.
So clearly the caller's assembly is wrong; it should be saving all 64-bits of
r9 (volatile gpr) first.
Cheers,
Kyle Moffett
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44364