lightning
[Top][All Lists]
Advanced

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

Re: [Lightning] How to return a floating point value from a function ?


From: Paulo César Pereira de Andrade
Subject: Re: [Lightning] How to return a floating point value from a function ?
Date: Fri, 4 Apr 2014 19:04:07 -0300

2014-04-04 17:12 GMT-03:00 Domingo Alvarez Duarte <address@hidden>:
> Hello !

  Hi,

> I was looking on the docs and web but did not found an example explanation
> of how to return floating points from lightning generated functions, so I'm
> asking here to see if someone can help me, also this can be added to the
> documentation to make it easy for others.

  I think documentation is indeed not very clear about this, or there are
not enough, and well documented examples. I will comment below your
sample code the problems.

> Here is a example that I'm trying to create with lightning, the integer
> functions works as expected but the floating pointing ones doesn't.
>
> Thanks in advance for any help !
>
> -----
> #include <stdio.h>
> #include <lightning.h>
>
> //static jit_state_t *_jit;
>
> int inative_mult(int a, int b) {
>   return a * b;
> }
>
> int inative_div(int a, int b) {
>   return a / b;
> }
>
> typedef int (*pifii)(int, int);    /* Pointer to Int Function of Int Int */
>
> double dnative_mult(double a, double b) {
>   return a * b;
> }
>
> double dnative_div(double a, double b) {
>   return a / b;
> }
>
> typedef double (*pdfdd)(double, double);    /* Pointer to double Function of
> double double */
>
> int main(int argc, char *argv[])
> {
>   jit_state_t *_jit;
>   pifii          imyMult, imyDiv;             /* ptr to generated code */
>   jit_node_t    *startIMult, *startIDiv;           /* a couple of labels */
>
>   pdfdd          dmyMult, dmyDiv;             /* ptr to generated code */
>   jit_node_t    *startDMult, *startDDiv;           /* a couple of labels */
>
>   jit_node_t    *inA, *inB;                    /* to get the argument */
>
>   init_jit(argv[0]);
>   _jit = jit_new_state();
>
>   startIMult = jit_note(__FILE__, __LINE__);
>   jit_prolog();
>   inA = jit_arg();
>   inB = jit_arg();
>   jit_getarg(JIT_V0, inA);
>   jit_getarg(JIT_V1, inB);
>   jit_mulr(JIT_R0, JIT_V0, JIT_V1);
>   jit_ret();

  You should use "jit_retr(JIT_R0);" instead of "jit_ret();". Plain
jit_ret() should be used for void functions. It is working because
the return register maps to JIT_R0 on *most* lightning ports,
but not all.

>   jit_epilog();
>
>   startIDiv = jit_note(__FILE__, __LINE__);
>   jit_prolog();
>   inA = jit_arg();
>   inB = jit_arg();
>   jit_getarg(JIT_V0, inA);
>   jit_getarg(JIT_V1, inB);
>   jit_divr(JIT_R0, JIT_V0, JIT_V1);
>   jit_ret();

  Same problem with jit_ret(), where should use jit_retr(JIT_R0)

>   jit_epilog();
>
>   startDMult = jit_note(__FILE__, __LINE__);
>   jit_prolog();
>   inA = jit_arg_f();
>   inB = jit_arg_f();
>   jit_getarg_f(JIT_F0, inA);
>   jit_getarg_f(JIT_F1, inB);
>   jit_mulr_f(JIT_FA0, JIT_F0, JIT_F1);
>   jit_retr_f(JIT_FA0);

  Well, it was a mistake to export the JIT_FA0 symbol :-) Please
do not use it. It is only available on a few ports, where float/double
arguments are passed on registers, and is an alias for the
first argument register. I suggest writing:
    jit_mulr_f(JIT_F0, JIT_F0, JIT_F1);
    jit_retr_f(JIT_F0);
it is actually better this way for ix86, x86_64 and s390 that have
two operand instructions.

>   jit_epilog();
>
>   startDDiv = jit_note(__FILE__, __LINE__);
>   jit_prolog();
>   inA = jit_arg_f();
>   inB = jit_arg_f();
>   jit_getarg_f(JIT_F0, inA);
>   jit_getarg_f(JIT_F1, inB);
>   jit_divr_f(JIT_FA0, JIT_F0, JIT_F1);
>   jit_retr_f(JIT_FA0);

  Same comment about not using JIT_FA0.

>   jit_epilog();
>
>   jit_emit();
>
>   imyMult = (pifii)jit_address(startIMult);
>   imyDiv = (pifii)jit_address(startIDiv);
>
>   dmyMult = (pdfdd)jit_address(startDMult);
>   dmyDiv = (pdfdd)jit_address(startDDiv);

  This is bad, you are casting float (*)(float,float) to double
(*)(double, double)

>   jit_clear_state();
>
>   /* call the generated code, passing its size as argument */
>   printf("jit_native_imult(%d, %d) = %d\n", 12, 27, imyMult(12, 27));
>   printf("jit_native_idiv(%d, %d) = %d\n", 27, 12, imyDiv(27, 12));
>
>   printf("jit_native_dmult(%f, %f) = %f\n", 12.3, 27.5, dmyMult(12.3,
> 27.5));
>   printf("jit_native_ddiv(%f, %f) = %f\n", 27.5, 12.3, dmyDiv(27.5, 12.3));

  You should either change the functions to operate on doubles, or use
the proper cast so that the compiler would convert the float return to
a double, as printf only accepts doubles. So, either:

-typedef double (*pdfdd)(double, double);    /* Pointer to double
Function of double double */
+typedef float (*pdfdd)(float, float);    /* Pointer to double
Function of double double */

or a global "s/_f/_d/g" in the sample source.

>   jit_disassemble();
>
>   jit_destroy_state();
>   finish_jit();
>   return 0;
> }


Thanks,
Paulo



reply via email to

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