ARM JIT: fix soft-float `round'

Use our own implementation of round(), since the round()
function might be missing.
This commit is contained in:
Matthew Flatt 2013-08-24 06:10:41 -06:00
parent eb6e49e32e
commit 0b8e764e99
4 changed files with 43 additions and 35 deletions

View File

@ -45,8 +45,6 @@
#define __jit_constructor /* empty */
#define __jit_inline XFORM_NONGCING MZ_INLINE static
typedef unsigned int _ui;
typedef signed char _sc;
typedef unsigned char _uc, jit_insn;
typedef unsigned short _us;

View File

@ -377,10 +377,19 @@ swf_id(jit_state_t _jitp, double (*i0)(double), jit_gpr_t r0, jit_fpr_t r1)
swf_pop(l);
}
XFORM_NONGCING static float SCH_ROUNDF(float f)
{
/* JIT does not generate single-precision arithmetic */
return f;
}
/* SCH_ROUND: */
#include "../../schround.inc"
#define swf_rintr_f_i(_jitp, r0, r1) swf_if(_jitp, rintf, r0, r1)
#define swf_rintr_d_i(_jitp, r0, r1) swf_id(_jitp, rint, r0, r1)
#define swf_roundr_f_i(_jitp, r0, r1) swf_if(_jitp, roundf, r0, r1)
#define swf_roundr_d_i(_jitp, r0, r1) swf_id(_jitp, round, r0, r1)
#define swf_roundr_f_i(_jitp, r0, r1) swf_if(_jitp, SCH_ROUNDF, r0, r1)
#define swf_roundr_d_i(_jitp, r0, r1) swf_id(_jitp, SCH_ROUND, r0, r1)
#define swf_truncr_f_i(_jitp, r0, r1) swf_if(_jitp, (void *)0, r0, r1)
#define swf_truncr_d_i(_jitp, r0, r1) swf_id(_jitp, (void *)0, r0, r1)
#define swf_ceilr_f_i(_jitp, r0, r1) swf_if(_jitp, ceilf, r0, r1)

View File

@ -2428,37 +2428,7 @@ sch_truncate (int argc, Scheme_Object *argv[])
ESCAPED_BEFORE_HERE;
}
XFORM_NONGCING static double SCH_ROUND(double d)
{
double i, frac;
int invert;
#ifdef FMOD_CAN_RETURN_POS_ZERO
if ((d == 0.0) && minus_zero_p(d))
return d;
#endif
if (d < 0) {
d = -d;
invert = 1;
} else
invert = 0;
frac = modf(d, &i);
if (frac < 0.5)
d = i;
else if (frac > 0.5)
d = i + 1;
else if (fmod(i, 2.0) != 0.0)
d = i + 1;
else
d = i;
if (invert)
d = -d;
return d;
}
#include "schround.inc"
static Scheme_Object *
sch_round (int argc, Scheme_Object *argv[])

View File

@ -0,0 +1,31 @@
XFORM_NONGCING static double SCH_ROUND(double d)
{
double i, frac;
int invert;
#ifdef FMOD_CAN_RETURN_POS_ZERO
if ((d == 0.0) && minus_zero_p(d))
return d;
#endif
if (d < 0) {
d = -d;
invert = 1;
} else
invert = 0;
frac = modf(d, &i);
if (frac < 0.5)
d = i;
else if (frac > 0.5)
d = i + 1;
else if (fmod(i, 2.0) != 0.0)
d = i + 1;
else
d = i;
if (invert)
d = -d;
return d;
}