Bug 983448 - Fix masm.convertUInt32ToFloat32 on x86. r=bbouvier, a=sledru
authorLuke Wagner <luke@mozilla.com>
Thu, 13 Mar 2014 18:05:08 -0500
changeset 183614 87251be46cc752da41eeeb61affa49bb48521d7e
parent 183613 31f35431afd34da8a545261254fde36688911fd6
child 183615 d0da2733724d3a6360ddd58130749e254d046296
push id3422
push userryanvm@gmail.com
push dateThu, 03 Apr 2014 18:35:46 +0000
treeherdermozilla-beta@cc734bdf4e41 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbbouvier, sledru
bugs983448
milestone29.0
Bug 983448 - Fix masm.convertUInt32ToFloat32 on x86. r=bbouvier, a=sledru
js/src/jit-test/tests/asm.js/testFloat32.js
js/src/jit/x86/MacroAssembler-x86.h
--- a/js/src/jit-test/tests/asm.js/testFloat32.js
+++ b/js/src/jit-test/tests/asm.js/testFloat32.js
@@ -81,16 +81,19 @@ assertEq(asmLink(asmCompile('glob', 'ffi
 
 // -> to Float32
 assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = x|0; return toF(~~x); } return f"), this)(23), 23);
 assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = x|0; return toF(x >> 0); } return f"), this)(23), 23);
 assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = +x; return toF(x); } return f"), this)(13.37), Math.fround(13.37));
 
 UINT32_MAX = Math.pow(2, 32)-1;
 assertEq(asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = x|0; return toF(x >>> 0); } return f"), this)(-1), Math.fround(UINT32_MAX));
+var tof = asmLink(asmCompile('glob', USE_ASM + TO_FLOAT32 + "function f(x) { x = x|0; return toF(x>>>0) } return f"), this);
+for (x of [0, 1, 10, 64, 1025, 65000, Math.pow(2,30), Math.pow(2,31), Math.pow(2,32)-2, Math.pow(2,32)-1])
+    assertEq(tof(x), Math.fround(x));
 
 // Global variables imports
 assertAsmTypeFail('glob', USE_ASM + "var x = toF(); function f() {} return f");
 assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var x = some(3); function f() {} return f");
 assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var x = toF(); function f() {} return f");
 assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var x = toF(3, 4); function f() {} return f");
 assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var x = toF({x: 3}); function f() {} return f");
 assertAsmTypeFail('glob', USE_ASM + TO_FLOAT32 + "var x = toF(true); function f() {} return f");
--- a/js/src/jit/x86/MacroAssembler-x86.h
+++ b/js/src/jit/x86/MacroAssembler-x86.h
@@ -977,25 +977,18 @@ class MacroAssemblerX86 : public MacroAs
 
         // dest is now a double with the int range.
         // correct the double value by adding 0x80000000.
         addConstantDouble(2147483648.0, dest);
     }
 
     // Note: this function clobbers the source register.
     void convertUInt32ToFloat32(const Register &src, const FloatRegister &dest) {
-        // src is [0, 2^32-1]
-        subl(Imm32(0x80000000), src);
-
-        // Do it the GCC way
-        convertInt32ToFloat32(src, dest);
-
-        // dest is now a double with the int range.
-        // correct the double value by adding 0x80000000.
-        addConstantFloat32(2147483648.f, dest);
+        convertUInt32ToDouble(src, dest);
+        convertDoubleToFloat32(dest, dest);
     }
 
     void inc64(AbsoluteAddress dest) {
         addl(Imm32(1), Operand(dest));
         Label noOverflow;
         j(NonZero, &noOverflow);
         addl(Imm32(1), Operand(dest.offset(4)));
         bind(&noOverflow);