Hello,
thanks for the patch! LGTM with a minor comment
Sergey
s/arm/ARM/From: Mike Pall <mike> Reported by Peter Cawley. (cherry picked from commit 32a683d226a3b57adbfeabff17d1ae0f7676545d) On the arm architecture, the `tobit()` function incorrectly truncates
instead of rounding to the nearest integer. This leads to inconsistency between various VMs (comparing to x86/x64, for example) and between the arm VM and JIT. This patch uses an addition of 2^52 + 2^51 constant to the given argument to convert it to the nearest integer value. After reading the lowest 32 bits of the register, we get the expected result. The test is the same as for the previous commit. Sergey Kaplun: * added the description for the problem Part of tarantool/tarantool#12880 --- src/vm_arm.dasc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc index 7ed555f8..139f7fed 100644 --- a/src/vm_arm.dasc +++ b/src/vm_arm.dasc @@ -1829,9 +1829,19 @@ static void build_subroutines(BuildCtx *ctx) | |//-- Bit library -------------------------------------------------------- | - |// FP number to bit conversion for soft-float. Clobbers r0-r3. |->vm_tobit_fb: | bhi ->fff_fallback + |.if FPU + |// FP number to bit conversion for hard-float. Clobbers r0, d0-d1. + | vldr d1, >9 + | vmov d0, CARG1, CARG2 + | vadd.f64 d0, d0, d1 + | vmov CARG1, s0 + | bx lr + |9: + | .long 0, 0x43380000 // (double)(2^52 + 2^51). + |.else + |// FP number to bit conversion for soft-float. Clobbers r0-r3. |->vm_tobit: | lsl RB, CARG2, #1 | adds RB, RB, #0x00200000 @@ -1856,6 +1866,7 @@ static void build_subroutines(BuildCtx *ctx) | orr CARG1, CARG4, CARG1, lsl RB | rsblt CARG1, CARG1, #0 | bx lr + |.endif | |.macro .ffunc_bit, name | .ffunc_1 bit_..name