MIPS 32bits cpu has the instruction "cvt.s.w fD, fS" (such like PSP used R4000 ASM) can convert integer value to float value. I found that PowerPC750 is also a 32bits CPU but the unique instruction "fcfid fD, fS" needs 64bits integer registers. Only "fctiw fD, fS" or "fctiwz fD, fS" need 32bits integer registers. Is there any other method to convert integer value to float value on Wii? ???
It's a pretty convoluted process to do an int->float cast. You basically have to build a 64-bit double-precision float; sign, exponent, and mantissa. And then you have to subtract it from a "magic double". Then you'll have the (single-precision!) float that you're looking for.
http://wall.riscom.net/books/proc/ppc/cwg/code3.html
Figure 3-52
32-Bit Implementation
# FR2 = 0x4330000080000000
addis R0,R0,0x4330 # R0 = 0x43300000
stw R0,disp(R1) # store upper half
xoris R3,R3,0x8000 # flip sign bit
stw R3,disp+4(R1) # store lower half
lfd FR1,disp(R1) # float load double of value
fsub FR1,FR1,FR2 # subtract 0x4330000080000000
In this case, they are assuming that FR2 contains the bit pattern 0x4330000080000000. Note this is a 64-bit value; the FRs in the PPC are 64-bit. Most games have this magic float stored in constants that are accessed with the Small Data Anchor, r2. If you can find that for your game, rock on! For instance, Resident Evil 4 stores the Magic Float at -27352(r2).
Otherwise, you'll need to create the Magic Float somewhere, probably on the stack, or maybe even in the C2 code itself.
The first line of the example is building the sign, exponent, and the first 20 bits of the mantissa. The second line stores this first half. The third line flips the bit (it matches up with the 8 in the middle of the Magic Float) The fourth line line stores this second half. The fifth line loads the double we just build. The sixth line then "normalizes" the float we built by subtracting the Magic Float from it.
Oh maybe you misunderstood my question. I meant how to convert integer value to float value (such as convert 0x00000064 to 0x42C80000).
No, I did not misunderstand you. You want the value 1 to turn into 0x3F800000. 2 into 0x40000000. You can't just use a constant (or you could code it in directly), because you need to convert a value in memory or in a register.
32-bit PowerPC processors don't have any easy way to do an integer -> float cast. The way I described above is how games do it. I can show you game logs of Super Mario Galaxy 2 and Resident Evil 4 if you don't believe me.
I still don't understand. :confused: Could you show me the sample of the asm instructions in RE4, please?
It's complicated. It helps to know what a float looks like in memory. Google sign exponent mantissa and you should get some good results.
Here's the example from RE4. I have removed interleaved instructions that are not relevant to the example. This example takes the integer value in r0 @ address 8009FF38, and puts it into the floating point register f2 @ address 8009FF4C.
---
8009FB18: 3C004330 lis r0,17200 r0 = 81280048
...
8009FB20: 90010008 stw r0,8(r1) r0 = 43300000 r1 = 806A7FA8 [806A7FB0] = 00000000
...
8009FF34: C8629528 lfd f3,-27352(r2) f3 = 4.2949673E+09 r2 = 80446B60 [80440088] = 4330000080000000
8009FF38: 6C008000 xoris r0,r0,32768 r0 = 00000005 r0 = 00000005
...
8009FF40: 9001000C stw r0,12(r1) r0 = 80000005 r1 = 806A7FA8 [806A7FB4] = 800002A3
...
8009FF48: C8410008 lfd f2,8(r1) f2 = NaN r1 = 806A7FA8 [806A7FB0] = 4330000080000005
8009FF4C: EC421828 fsubs f2,f2,f3 f2 = 4.5036E+15 f2 = 4.5036E+15 f3 = 4.5036E+15
8009FF50: EC4100BC fnmsubs f2,f1,f2,f0 f2 = 5 f1 = 0.03 f2 = 5 f0 = 1
---
line B18 builds the first half of the converted double and puts it on the stack at 8(r1). This contains the sign, exponent, and 20 bits of the mantissa. It is always the same.
line F34 reads the Magic Float 4330000080000000 by using the small read-only data anchor r2. This value will always be here for this game. It's a constant.
line F38 takes the value that we want, which is in r0 = 5, and flips the highest bit, so that it's 80000005 (as can be seen in the log at F40). This creates the second half of the converted double.
line F40 puts the second half of the converted double on the stack at 12(r1). In combination with F34, this creates the full 64-bit representation of our converted double on the stack.
line F48 reads our converted double off the stack. Notice the 64-bit operand.
line F4C normalizes our converted double by subtracting the Magic Float.
Just in case you don't believe that this process works, I included the next line from the Gecko.NET log. It shows that f2 contains a 5 in floating point (the integer value which was originally in r0). The Text View of Gecko.NET confirms that f2 contains the bit pattern 40A00000, which is a 32-bit single-precision 5.
4330000080000005=4503601774854149.00000000000000000000
4330000080000000=4503601774854144.00000000000000000000
4503601774854149.00000000000000000000-4503601774854144.00000000000000000000=5.00000000000000000000
I get it. Thank you very much. ^-^