lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


KHMan wrote:
> On 4/19/2011 11:58 PM, Adam Strzelecki wrote:
> >>Could the JIT use such optimizations automatically, or maybe at
> >>least
> >>remove the intermediate __add and bit.* calls operating on the
> >>integers
> >>directly?
> >
> >It already there, quoting Mike's earlier response: "The ARM port
> >uses the dual-number mode of LuaJIT. All Lua numbers
> >are represented either as integers or doubles internally. This is
> >transparent to the user of the VM. Except for the performance
> >effects, of course: e.g. 'for i=1,1e7 do end' runs much faster
> >than 'for i=1.5,1e7 do end'."
> 
> IIRC, Michal was talking about inferring and accelerating fixed
> point arithmetic, which is a legit question that goes further than
> what you have quoted in the above.

No, the reply was spot on. The LuaJIT dual-number mode is a
property of the VM. It works even with the pure interpreter. The
JIT compiler does some extra narrowing to integers. But that's
rarely needed in dual-number mode (OTOH it's crucial for
performance in single-number mode, e.g. on x86/x64).

The main trick used is a special arrangement of the type codes in
the hi-word of a 64 bit NaN-tagged value:

   -1 nil
   -2 false
   -3 true
  ...
  -13 userdata
  -14 int (only used in dual-number mode)
  all others: FP numbers

A single comparison of the hi-word of a value with -14 can
disambiguate integers (equal), numbers (unsigned lower) or other
types (unsigned higher). This combines nicely with the predicated
ARM instructions.

I suggest to follow the disassembly for lj_ff_bit_band to get a
feeling how that works in the interpreter. The call to lj_vm_tobit
is only used for FP numbers (warning: heavy soft-float magic). The
check for non-numbers can be merged in, too (see lj_vm_tobit_fb).

--Mike