Port-dreamcast archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
floating-point loads vs dreamcast
I'm seeing weird behaviour out of my dreamcast. When I write
fmov @r1,dr0
(with PR set in the FPSCR, to be sure), it appears to be losing the low
32 bits of the manitssa. I've verified (by computing 72/17 instead of
loading with fmov) that the way I'm printing the number is not at
fault.
Specifically, if the code says
8c03000e: ?? ?? 49 SETS.L #FPSCR_PR,r1
8c030010: 6a 41 50 lds r1,fpscr
51 .pr 1
8c030012: 48 e1 52 SETS.L #72,r1
8c030014: 5a 41 53 lds r1,fpul
8c030016: 2d f0 54 float fpul,dr0
8c030018: 11 e1 55 SETS.L #17,r1
8c03001a: 5a 41 56 lds r1,fpul
8c03001c: 2d f2 57 float fpul,dr2
8c03001e: 23 f0 58 fdiv dr2,dr0
59 ; SETS.L #twopi,r1
60 ; fmov @r1,dr0
8c030020: 0a e1 61 mov #10,r1
8c030022: 5a 41 62 lds r1,fpul
8c030024: 2d f4 63 float fpul,dr4
8c030026: 3c e2 64 mov #60,r2
8c030028: 3d f0 65 1: ftrc dr0,fpul
8c03002a: 5a 01 66 sts fpul,r1
8c03002c: ?? ?? 67 bsr putchar
8c03002e: 30 71 68 add #'0,r1
8c030030: 2d f2 69 float fpul,dr2
8c030032: 21 f0 70 fsub dr2,dr0
8c030034: 42 f0 71 fmul dr4,dr0
8c030036: 10 42 72 dt r2
8c030038: f6 8f 73 bf/s 1b
8c03003a: 09 00 74 nop
...
(8c03000e: 12 d1)
...
8c030058: 00 00 08 00 .long 0x00080000 ; 8c03000e
then the printed number is
423529411764705887577520115883089601993560791015625000000000
which (after inserting the decimal point, which I didn't bother
printing) is hex 4.3c3c3c3c3c3c4, which is correct. But if I do,
instead,
8c022000: 17 twopi:
8c022000: fb 21 19 40 18 .long 0x401921fb ; s=0, exp=1025,
mant=(1.)921fbxxxxxxxx
8c022004: 18 2d 44 54 19 .long 0x54442d18 ;
mant=(1.)xxxxx54442d18(469898cc...)
...
8c03000e: ?? ?? 49 SETS.L #FPSCR_PR,r1
8c030010: 6a 41 50 lds r1,fpscr
51 .pr 1
52 ; SETS.L #72,r1
53 ; lds r1,fpul
54 ; float fpul,dr0
55 ; SETS.L #17,r1
56 ; lds r1,fpul
57 ; float fpul,dr2
58 ; fdiv dr2,dr0
8c030012: ?? ?? 59 SETS.L #twopi,r1
8c030014: 18 f0 60 fmov @r1,dr0
8c030016: 0a e1 61 mov #10,r1
8c030018: 5a 41 62 lds r1,fpul
8c03001a: 2d f4 63 float fpul,dr4
8c03001c: 3c e2 64 mov #60,r2
8c03001e: 3d f0 65 1: ftrc dr0,fpul
8c030020: 5a 01 66 sts fpul,r1
8c030022: ?? ?? 67 bsr putchar
8c030024: 30 71 68 add #'0,r1
8c030026: 2d f2 69 float fpul,dr2
8c030028: 21 f0 70 fsub dr2,dr0
8c03002a: 42 f0 71 fmul dr4,dr0
8c03002c: 10 42 72 dt r2
8c03002e: f6 8f 73 bf/s 1b
8c030030: 09 00 74 nop
...
(8c030012: 10 d1)
...
8c030054: 00 20 02 8c .long 0x8c022000 ; 8c030012
then the printed number is
628318405151367187500000000000000000000000000000000000000000
which is hex 6.487ec, or 4 * 1.921fb - it lost the second 32 bits of
the mantissa. It's clearly doing a double load, not a single load and
convert to double, because it got the size of the exponent field right.
(Hex 401921fb as a single would be decimal 2.02454368etc.) Similarly,
it clearly isn't getting the bytes reversed or any such. But it's
somehow lost the low 32 bits of the mantissa. I checked, and the 8
bytes at 8c022000 do contain what they should (not that it's likely the
code would load OK but the data not, but I'm paranoid when weird things
like this happen).
Any idea what's going on here? As I read the hardware docs,
fmov @rN,drM certainly ought to do a 64-bit double-precision load.
/~\ The ASCII Mouse
\ / Ribbon Campaign
X Against HTML mouse%rodents-montreal.org@localhost
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B
Home |
Main Index |
Thread Index |
Old Index