lightning
[Top][All Lists]
Advanced

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

Re: [Lightning] How to call varargs functions from lightning in x86_64?


From: Paulo César Pereira de Andrade
Subject: Re: [Lightning] How to call varargs functions from lightning in x86_64?
Date: Wed, 18 Aug 2010 22:01:42 -0300
User-agent: SquirrelMail/1.4.19

Paolo Bonzini wrote:
>>>> It's not insurmountable, but it needs a new form of prepare statement
>>>> or something like that.
>>>
>>>   Now, the test cases works for both, i386 and x86_64.
>>
>>  I think it can be implemented significantly better lightning support
>> for x86_64. It would require setting a flag in jit_prepare() if:
>>
>> o The user specified it is a varargs prepare, like adding a new
>>  jit_vararg(num) to be used instead of jit_prepare(num). This is the
>>  only real change to lightning, and should be better than blindly
>>  setting %rax when it is not required
>
> Yes, that's okay, though the cost of a single mov to %rax is not
> too bad.

  I am making an initial/experimental patch. What surelly needs to
be done is:

o Change JIT_REXTMP to _R11D as the current value of _R9D means
  there is only support for 5 integer arguments, as %r9 is the 5th
  argument, but also clobbered in the finish/calli macro.
  Since the abi specifies %r11 is a scratch register, JIT_V_NUM can
  also be extended to 5, to use %rbx, and the other calee saved
  %r11-%r15

o Change JIT_FPTMP to _XMM8, because the abi uses %xmm0 to   %xmm7
  for passing arguments, and the value of %al is 0-8 inclusive,
  telling the number of used registers.

>>  I believe this should be reasonable, of course only support for
>> basic data types is done, otherwise it would defeat the lightning
>> purpose as jit, but removing the 6 (+n float) arguments would be
>> cheap, and not too hard to implement. What do you think?
>
> I agree.

  I got it almost working. Still need to properly restore stack or
call printf only once :-) but it works for any number of integer
arguments. The quick and dirty macro is basically:

-#define jit_pusharg_i(rs)      (--_jitl.argssize, MOVQrr(rs,
jit_arg_reg_order[_jitl.argssize]))
-#define jit_finish(sub)         (MOVQir((long) (sub), JIT_REXTMP), \
-                                CALLsr(JIT_REXTMP))
+#define jit_pusharg_i(rs)      \
+    (--_jitl.argssize,         \
+     _jitl.argssize >= 6 ?     \
+     PUSHQr(rs) : MOVQrr(rs, jit_arg_reg_order[_jitl.argssize]))
+#define jit_finish(sub)                \
+    (MOVBir(_jitl.fprssize < 9 ? _jitl.fprssize : 8, _AL),     \
+     MOVQir((long) (sub), JIT_REXTMP), \
+     CALLsr(JIT_REXTMP))

  But, besides correcting stack (and jit_arg_*/jit_getarg_* later),
it will be required code for SSEUP, if I understand it correctly,
that is, if more then 8 float arguments, they go in the upper 64 bits
of xmm0-xmm7, and only then are pushed on stack (if more then 16 float
arguments).

>>  BTW, please pardon my ignorance :-), but could it be made cheaper
>> to "callq routine_address", instead of "movabs routine_address,%r9;
>> callq *%r9"? I think there should be a reason (not sitting in front
>> of a x86_64, so cannot test it myself right now...)
>
> Yes, though I don't have a manual at hand to double check.

  I am still somewhat in the dark (as I already told, I am not that
good with assembly), I made some experiments, but need to better
understand rex/modr/sib, as from what I read so far, apparently
it really needs do dereference a register, if not using %rip, what
could be hard to compute with just macros, but I think usually
function pointers will be mapped more then "32 bit" distant from
the malloc area of the jit code...

> Paolo

Paulo




reply via email to

[Prev in Thread] Current Thread [Next in Thread]