[Tarantool-patches] [PATCH luajit 2/2] ARM: Make hard-float tobit conversions match JIT backend behavior.

Sergey Kaplun skaplun at tarantool.org
Tue Jul 21 17:53:09 MSK 2026


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
-- 
2.55.0



More information about the Tarantool-patches mailing list