Index: working_vm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp =================================================================== --- working_vm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (revision 542490) +++ working_vm/vm/jitrino/src/codegenerator/ia32/Ia32InstCodeSelector.cpp (working copy) @@ -26,6 +26,7 @@ #include "VMInterface.h" #include "Opcode.h" #include "Ia32Tls.h" +#include "Algorithms.h" #include #include @@ -127,7 +128,7 @@ // FP remainder internal helpers (temp solution to be optimized) float __stdcall remF4 (float v0, float v1)stdcall__; float __stdcall remF4 (float v0, float v1) { - return fmodf(v0,v1); + return fmod((double)v0,(double)v1); } double __stdcall remF8 (double v0, double v1)stdcall__; @@ -132,7 +133,7 @@ double __stdcall remF8 (double v0, double v1)stdcall__; double __stdcall remF8 (double v0, double v1) { - return fmod(v0,v1); + return jitrino_ieee754_fmod_double(v0,v1); } void __stdcall initialize_array(uint8* array, uint32 elems_offset, uint8* data, uint32 num_elems) stdcall__; Index: working_vm/vm/jitrino/src/jet/arith_rt.cpp =================================================================== --- working_vm/vm/jitrino/src/jet/arith_rt.cpp (revision 542490) +++ working_vm/vm/jitrino/src/jet/arith_rt.cpp (working copy) @@ -24,6 +24,7 @@ */ #include "arith_rt.h" +#include "Algorithms.h" #include #include @@ -138,7 +139,7 @@ if (finite(v1) && !finite(v2)) { return v1; } - return fmod(v1,v2); + return jitrino_ieee754_fmod_double(v1,v2); } float __stdcall rt_h_flt_a(float v1, float v2, JavaByteCodes op) @@ -170,7 +171,7 @@ if (finite(v1) && !finite(v2)) { return v1; } - return fmod(v1,v2); + return fmod((double)v1,(double)v2); } jlong __stdcall rt_h_i64_shift(jlong v1, int v2, JavaByteCodes op) Index: working_vm/vm/jitrino/src/shared/Algorithms.cpp =================================================================== --- working_vm/vm/jitrino/src/shared/Algorithms.cpp (revision 0) +++ working_vm/vm/jitrino/src/shared/Algorithms.cpp (revision 0) @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @author Igor V Chebykin + * @version $Revision: 1.3.12.4.4.4 $ + */ +/** + * @file + * @brief Implementation of special algorithms declared in Algorithms.h. + */ + +#include +#include +#include +#include +#include "Algorithms.h" + + +namespace Jitrino { + +/* + * ieee754_fmod(x,y) + * Return x mod y in exact arithmetic + * Method: shift and subtract + */ +#define __HI(x) *(1+(int*)&x) +#define __LO(x) *(int*)&x +#define __HIp(x) *(1+(int*)x) +#define __LOp(x) *(int*)x + +double jitrino_ieee754_fmod_double(double x, double y) { + const double one = 1.0, Zero[] = {0.0, -0.0,}; + int n,hx,hy,hz,ix,iy,sx,i; + unsigned lx,ly,lz; + + hx = __HI(x); /* high word of x */ + lx = __LO(x); /* low word of x */ + hy = __HI(y); /* high word of y */ + ly = __LO(y); /* low word of y */ + sx = hx&0x80000000; /* sign of x */ + hx ^=sx; /* |x| */ + hy &= 0x7fffffff; /* |y| */ + + /* purge off exception values */ + if ((hy|ly)==0 || + (hx>=0x7ff00000) || /* y=0,or x not finite */ + ((hy|((ly|(-((int)ly)))>>31))>0x7ff00000) ) /* or y is NaN */ + return (x*y)/(x*y); + if(hx<=hy) { + if((hx>31]; /* |x|=|y| return x*0*/ + } + + /* determine ix = ilogb(x) */ + if(hx<0x00100000) { /* subnormal x */ + if(hx==0) { + for (ix = -1043, i=lx; i>0; i<<=1) ix -=1; + } else { + for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1; + } + } else ix = (hx>>20)-1023; + + /* determine iy = ilogb(y) */ + if(hy<0x00100000) { /* subnormal y */ + if(hy==0) { + for (iy = -1043, i=ly; i>0; i<<=1) iy -=1; + } else { + for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1; + } + } else iy = (hy>>20)-1023; + + /* set up {hx,lx}, {hy,ly} and align y to x */ + if(ix >= -1022) + hx = 0x00100000|(0x000fffff&hx); + else { /* subnormal x, shift x to normal */ + n = -1022-ix; + if(n<=31) { + hx = (hx<>(32-n)); + lx <<= n; + } else { + hx = lx<<(n-32); + lx = 0; + } + } + if(iy >= -1022) + hy = 0x00100000|(0x000fffff&hy); + else { /* subnormal y, shift y to normal */ + n = -1022-iy; + if(n<=31) { + hy = (hy<>(32-n)); + ly <<= n; + } else { + hy = ly<<(n-32); + ly = 0; + } + } + + /* fix point fmod */ + n = ix - iy; + while(n--) { + hz=hx-hy;lz=lx-ly; if(lx>31); lx = lx+lx;} + else { + if((hz|lz)==0) /* return sign(x)*0 */ + return Zero[(unsigned)sx>>31]; + hx = hz+hz+(lz>>31); lx = lz+lz; + } + } + hz=hx-hy;lz=lx-ly; if(lx=0) {hx=hz;lx=lz;} + + /* convert back to floating value and restore the sign */ + if((hx|lx)==0) /* return sign(x)*0 */ + return Zero[(unsigned)sx>>31]; + while(hx<0x00100000) { /* normalize x */ + hx = hx+hx+(lx>>31); lx = lx+lx; + iy -= 1; + } + if(iy>= -1022) { /* normalize output */ + hx = ((hx-0x00100000)|((iy+1023)<<20)); + __HI(x) = hx|sx; + __LO(x) = lx; + } else { /* subnormal output */ + n = -1022 - iy; + if(n<=20) { + lx = (lx>>n)|((unsigned)hx<<(32-n)); + hx >>= n; + } else if (n<=31) { + lx = (hx<<(32-n))|(lx>>n); hx = sx; + } else { + lx = hx>>(n-32); hx = sx; + } + __HI(x) = hx|sx; + __LO(x) = lx; + x *= one; /* create necessary signal */ + } + return x; /* exact output */ +} + + +} //namespace Jitrino \ No newline at end of file Index: working_vm/vm/jitrino/src/shared/Algorithms.h =================================================================== --- working_vm/vm/jitrino/src/shared/Algorithms.h (revision 0) +++ working_vm/vm/jitrino/src/shared/Algorithms.h (revision 0) @@ -0,0 +1,10 @@ +#ifndef ALGORITHMS_H_ +#define ALGORITHMS_H_ + +namespace Jitrino { + +double jitrino_ieee754_fmod_double(double x, double y); + +} //namespace Jitrino + +#endif /*ALGORITHMS_H_*/