Alien-LibJIT

 view release on metacpan or  search on metacpan

libjit/doc/libjit.texi  view on Meta::CPAN

@end example

@c -----------------------------------------------------------------------

@node Tutorial 2, Tutorial 3, Tutorial 1, Tutorials
@section Tutorial 2 - gcd
@cindex gcd tutorial

In this second tutorial, we implement the subtracting Euclidean
Greatest Common Divisor (GCD) algorithm over positive integers.
This tutorial demonstrates how to handle conditional branching
and function calls.  In C, the code for the @code{gcd} function
is as follows:

@example
unsigned int gcd(unsigned int x, unsigned int y)
@{
    if(x == y)
    @{
        return x;
    @}
    else if(x < y)
    @{
        return gcd(x, y - x);
    @}
    else
    @{
        return gcd(x - y, y);
    @}
@}
@end example

The source code for this tutorial can be found in @code{tutorial/t2.c}.
Many of the details are similar to the previous tutorial.  We omit
those details here and concentrate on how to build the function body.
@xref{Tutorial 1}, for more information.

@noindent
We start by checking the condition @code{x == y}:

@example
jit_value_t x, y, temp1;
...
x = jit_value_get_param(function, 0);
y = jit_value_get_param(function, 1);
temp1 = jit_insn_eq(function, x, y);
@end example

This is very similar to our previous tutorial, except that we are using
the @code{eq} operator this time.  If the condition is not true, we
want to skip the @code{return} statement.  We achieve this with the
@code{jit_insn_branch_if_not} instruction:

@example
jit_label_t label1 = jit_label_undefined;
...
jit_insn_branch_if_not(function, temp1, &label1);
@end example

The label must be initialized to @code{jit_label_undefined}.  It will be
updated by @code{jit_insn_branch_if_not} to refer to a future position in
the code that we haven't seen yet.

If the condition is true, then execution falls through to the next
instruction where we return @code{x} to the caller:

@example
jit_insn_return(function, x);
@end example

If the condition was not true, then we branched to @code{label1} above.
We fix the location of the label using @code{jit_insn_label}:

@example
jit_insn_label(function, &label1);
@end example

@noindent
We use similar code to check the condition @code{x < y}, and branch
to @code{label2} if it is not true:

@example
jit_value_t temp2;
jit_label_t label2 = jit_label_undefined;
...
temp2 = jit_insn_lt(function, x, y);
jit_insn_branch_if_not(function, temp2, &label2);
@end example

At this point, we need to call the @code{gcd} function with the
arguments @code{x} and @code{y - x}.  The code for this is
fairly straight-forward.  The @code{jit_insn_call} instruction calls
the function listed in its third argument.  In this case, we are calling
ourselves recursively:

@example
jit_value_t temp_args[2];
jit_value_t temp3;
...
temp_args[0] = x;
temp_args[1] = jit_insn_sub(function, y, x);
temp3 = jit_insn_call
    (function, "gcd", function, 0, temp_args, 2, 0);
jit_insn_return(function, temp3);
@end example

The string @code{"gcd"} in the second argument is for diagnostic purposes
only.  It can be helpful when debugging, but the @code{libjit} library
otherwise makes no use of it.  You can set it to NULL if you wish.

In general, @code{libjit} does not maintain mappings from names to
@code{jit_function_t} objects.  It is assumed that the front end will
take care of that, using whatever naming scheme is appropriate to
its needs.

@noindent
The final part of the @code{gcd} function is similar to the previous one:

@example
jit_value_t temp4;
...



( run in 1.315 second using v1.01-cache-2.11-cpan-f5b5a18a01a )