MIPS appears to hate converting unsigneds to floats and vice versa.

This commit is contained in:
David Given 2018-09-05 23:53:38 +02:00
parent fc0b0ae178
commit b7a1c96986
3 changed files with 92 additions and 6 deletions

37
mach/mips/libem/fromud.s Normal file
View file

@ -0,0 +1,37 @@
#
.sect .text
.sect .rom
.sect .data
.sect .bss
.data
.define .fromud
.fromud:
/* Input: f0
* Output: r2
* Only at and f31 may be used.
*/
li at, hi(.fd_80000000)
ldc1 f31, lo(.fd_800000000)(at)
c.le.d 0, f31, f0
bc1t toobig
nop
trunc.w.d f0, f0
mfc1 r2, f0
jr ra
nop
toobig:
sub.d f0, f0, f31
trunc.w.d f0, f0
mfc1 r2, f0
addiu r2, r2, 0x8000
jr ra
nop
sect .rom
.fd_80000000:
!float 2.147483648e+9 sz 8
.data4 0x41e00000, 0

37
mach/mips/libem/fromuf.s Normal file
View file

@ -0,0 +1,37 @@
#
.sect .text
.sect .rom
.sect .data
.sect .bss
.data
.define .fromuf
.fromuf:
/* Input: f0
* Output: r2
* Only at and f31 may be used.
*/
li at, hi(.fd_80000000)
lwc1 f31, lo(.fd_800000000)(at)
c.le.f 0, f31, f0
bc1t toobig
nop
trunc.w.f f0, f0
mfc1 r2, f0
jr ra
nop
toobig:
sub.f f0, f0, f31
trunc.w.f f0, f0
mfc1 r2, f0
addiu r2, r2, 0x8000
jr ra
nop
sect .rom
.fd_80000000:
!float 2.147483648e+9 sz 4
.data4 0x4f000000, 0

View file

@ -617,7 +617,7 @@ PATTERNS
ALUC(LSR.I, "srl") ALUC(LSR.I, "srl")
out:(int)reg = NEG.I(left:(int)reg) out:(int)reg = NEG.I(left:(int)reg)
emit "neg %out, %left" emit "subu %out, zero, %left"
cost 4; cost 4;
out:(int)reg = NOT.I(in:(int)reg) out:(int)reg = NOT.I(in:(int)reg)
@ -625,7 +625,7 @@ PATTERNS
cost 4; cost 4;
ALUR(AND.I, "and") ALUR(AND.I, "and")
ALUCC(AND.I, "andi.") ALUCC(AND.I, "andi")
ALUR(OR.I, "or") ALUR(OR.I, "or")
ALUCC(OR.I, "ori") ALUCC(OR.I, "ori")
@ -667,7 +667,7 @@ PATTERNS
emit "div.d %out, %left, %right" emit "div.d %out, %left, %right"
cost 4; cost 4;
out:(float)reg = NEGF.D(left:(float)reg) out:(double)reg = NEGF.D(left:(double)reg)
emit "neg.d %out, %left" emit "neg.d %out, %left"
cost 4; cost 4;
@ -681,6 +681,12 @@ PATTERNS
emit "mfc1 %out, f31" emit "mfc1 %out, f31"
cost 8; cost 8;
out:(iret)reg = FROMUD.I(in:(dret)reg)
with corrupted(dret)
emit "jal .fromud"
emit "nop"
cost 30;
out:(double)reg = COPYL.D(in:(long)reg) out:(double)reg = COPYL.D(in:(long)reg)
emit "mtc1 %in.0, %out" /* mtc1 has reversed parameters */ emit "mtc1 %in.0, %out" /* mtc1 has reversed parameters */
emit "mthc1 %in.1, %out" /* mtc1 has reversed parameters */ emit "mthc1 %in.1, %out" /* mtc1 has reversed parameters */
@ -718,16 +724,22 @@ PATTERNS
emit "cvt.s.w %out, %out" emit "cvt.s.w %out, %out"
cost 4; cost 4;
out:(int)reg = FROMSF.I(in:(double)reg) out:(int)reg = FROMSF.I(in:(float)reg)
emit "trunc.w.s f31, %in" emit "trunc.w.s f31, %in"
emit "mfc1 %out, f31" emit "mfc1 %out, f31"
cost 8; cost 8;
out:(double)reg = COPYI.F(in:(long)reg) out:(iret)reg = FROMUD.I(in:(fret)reg)
with corrupted(fret)
emit "jal .fromuf"
emit "nop"
cost 30;
out:(float)reg = COPYI.F(in:(int)reg)
emit "mtc1 %in, %out" /* mtc1 has reversed parameters */ emit "mtc1 %in, %out" /* mtc1 has reversed parameters */
cost 8; cost 8;
out:(long)reg = COPYF.I(in:(double)reg) out:(int)reg = COPYF.I(in:(float)reg)
emit "mfc1 %out, %in" emit "mfc1 %out, %in"
cost 8; cost 8;