
(i'm working with the original poster, Joshua Lamorie)
On Tue, 16 Mar 2004, Wolfgang Denk wrote:
In message 004101c40b6d$69274aa0$cb01a8c0@xiphos.ca you wrote:
So if this is the problem, why is our compiler making code that does
this? I'm new to PPC assembler, so perhaps I'm interpreting this
Maybe your compiler / assembler is brogen?
Can you recommend a toolchain that would be better than the one we're
currently using? (listed below)
ELDK 3.0?
thank you for the suggestion!
i had missed the ELDK when i looked for a toolchain originally. I downloaded the latest version, installed from binary:
ELDK version 3.0 ppc_4xx: Build 2004-02-16
and compiled my little test program, which basically just loops and outputs values to a memory-mapped register that is plugged into LEDs.
to my amazement, the ELDK compiler made the same "mistake" (in quotes because it's entirely possible that it's my limited ppc405 knowledge that leads me to thinks it's a mistake):
00018304 <XIo_Out32>: 18304: 94 21 ff e0 stwu r1,-32(r1) 18308: 93 e1 00 1c stw r31,28(r1) 1830c: 7c 3f 0b 78 mr r31,r1 18310: 90 7f 00 08 stw r3,8(r31) 18314: 90 9f 00 0c stw r4,12(r31) 18318: 3d 20 00 03 lis r9,3 1831c: 80 1f 00 0c lwz r0,12(r31) 18320: 90 09 84 b0 stw r0,-31568(r9) 18324: 81 3f 00 0c lwz r9,12(r31) 18328: 80 1f 00 08 lwz r0,8(r31) 1832c: 91 20 00 00 stw r9,0(r0) 18330: 7c 00 06 ac eieio 18334: 81 61 00 00 lwz r11,0(r1) 18338: 83 eb ff fc lwz r31,-4(r11) 1833c: 7d 61 5b 78 mr r1,r11 18340: 4e 80 00 20 blr
(notice that this is the XIo_Out32() function generated by Xilinx XPS)
the problem is at 1832c. it correctly puts the absolute address in r0, and the data to output in r9. it then tries to store r9's contents at [r0+0].
Looking at the PP405's UM, i see this in the stw instruction page:
===================== An effective address (EA) is calculated by adding a displacement to a base address, which are formed as follows: * The displacement is formed by sign-extending the 16-bit d instruction field to 32 bits. * If the rA field is 0, the base address is 0. * If the rA field is not 0, the contents of register rA are used as the base address.
The contents of register rS are stored into the word referenced by EA. =====================
so using r0 as a pointer won't work: the cpu won't use the contents of r0, but will use 0. And we verified that: the value indeed gets output to 0 in memory.
Both ELDK's compiler and my other toolchain, a crosstool 0.26-generated toolchain (powerpc-405-linux-gnu-gcc version 3.3.3 20040112 (prerelease)) generate this "flawed" code.
Which would explain why our u-boot port isn't working, as presumably, "mistaken" code is generated elsewhere as well.
This looks like a gcc problem, but perhaps someone on this list could offer some guidance: - do all powerpc's, not just the 405, have this behavior (of using 0 instead of r0 when the rA field is 0)? - if so, why would these compilers generate code that seems flawed? - if not, are we supposed to invoke the compiler in a particular way?
The compiler that is part of Xilinx EDK, powerpc-eabi-gcc gcc version 2.95.3-4 Xilinx EDK 6.2 Build EDK_Gm.1, does not produce this flaw (it uses r9 as the address, r0 as the data), which correctly outputs to the correct address.
i realize that at this level, it's not a u-boot problem and that this mailing list is probably not the best avenue to ask for advice, but seeing as some people here have ppc / xilinx experience, perhaps someone would care to make a comment.
thank you!