From: David Given Date: Wed, 5 Sep 2018 21:53:38 +0000 (+0200) Subject: MIPS appears to hate converting unsigneds to floats and vice versa. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=b7a1c969864d5eeadf02410a1e24c0f94008ac0e;p=ack.git MIPS appears to hate converting unsigneds to floats and vice versa. --- diff --git a/mach/mips/libem/fromud.s b/mach/mips/libem/fromud.s new file mode 100644 index 000000000..3b2c459ca --- /dev/null +++ b/mach/mips/libem/fromud.s @@ -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 diff --git a/mach/mips/libem/fromuf.s b/mach/mips/libem/fromuf.s new file mode 100644 index 000000000..0b9517134 --- /dev/null +++ b/mach/mips/libem/fromuf.s @@ -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 diff --git a/mach/mips/mcg/table b/mach/mips/mcg/table index d9ec7a6ac..c2b7e3eb3 100644 --- a/mach/mips/mcg/table +++ b/mach/mips/mcg/table @@ -617,7 +617,7 @@ PATTERNS ALUC(LSR.I, "srl") out:(int)reg = NEG.I(left:(int)reg) - emit "neg %out, %left" + emit "subu %out, zero, %left" cost 4; out:(int)reg = NOT.I(in:(int)reg) @@ -625,7 +625,7 @@ PATTERNS cost 4; ALUR(AND.I, "and") - ALUCC(AND.I, "andi.") + ALUCC(AND.I, "andi") ALUR(OR.I, "or") ALUCC(OR.I, "ori") @@ -667,7 +667,7 @@ PATTERNS emit "div.d %out, %left, %right" cost 4; - out:(float)reg = NEGF.D(left:(float)reg) + out:(double)reg = NEGF.D(left:(double)reg) emit "neg.d %out, %left" cost 4; @@ -681,6 +681,12 @@ PATTERNS emit "mfc1 %out, f31" 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) emit "mtc1 %in.0, %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" 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 "mfc1 %out, f31" 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 */ cost 8; - out:(long)reg = COPYF.I(in:(double)reg) + out:(int)reg = COPYF.I(in:(float)reg) emit "mfc1 %out, %in" cost 8;