Merge pull request #377 from pcercuei/libretro
[pcsx_rearmed.git] / deps / lightning / doc / fact.c
1 #include <stdio.h>
2 #include <lightning.h>
3
4 static jit_state_t *_jit;
5
6 typedef long (*pwfw_t)(long);           /* Pointer to Long Function of Long */
7
8 int main(int argc, char *argv[])
9 {
10     pwfw_t       factorial;
11     long         arg;
12     jit_node_t  *ac;                    /* Accumulator */
13     jit_node_t  *in;                    /* Argument */
14     jit_node_t  *call;
15     jit_node_t  *fact;
16     jit_node_t  *jump;
17     jit_node_t  *fact_entry;
18     jit_node_t  *fact_out;
19
20     init_jit(argv[0]);
21     _jit = jit_new_state();
22
23     /* declare a forward label */
24     fact = jit_forward();
25
26     jit_prolog();                       /* Entry point of the factorial function */
27     in = jit_arg();                     /* Receive an integer argument */
28     jit_getarg(JIT_R0, in);             /* Move argument to RO */
29     jit_prepare();
30     jit_pushargi(1);                    /* This is the accumulator */
31     jit_pushargr(JIT_R0);               /* This is the argument */
32     call = jit_finishi(NULL);           /* Call the tail call optimized function */
33     jit_patch_at(call, fact);           /* Patch call to forward defined function */
34     /* the above could have been written as:
35      *          jit_patch_at(jit_finishi(NULL), fact);
36      */
37     jit_retval(JIT_R0);                 /* Fetch the result */
38     jit_retr(JIT_R0);                   /* Return it */
39     jit_epilog();                       /* Epilog *before* label before prolog */
40
41     /* define the forward label */
42     jit_link(fact);                     /* Entry point of the helper function */
43     jit_prolog();
44     jit_frame(16);                      /* Reserve 16 bytes in the stack */
45     fact_entry = jit_label();           /* This is the tail call entry point */
46     ac = jit_arg();                     /* The accumulator is the first argument */
47     in = jit_arg();                     /* The factorial argument */
48     jit_getarg(JIT_R0, ac);             /* Move the accumulator to R0 */
49     jit_getarg(JIT_R1, in);             /* Move the argument to R1 */
50     fact_out = jit_blei(JIT_R1, 1);     /* Done if argument is one or less */
51     jit_mulr(JIT_R0, JIT_R0, JIT_R1);   /* accumulator *= argument */
52     jit_putargr(JIT_R0, ac);            /* Update the accumulator */
53     jit_subi(JIT_R1, JIT_R1, 1);        /* argument -= 1 */
54     jit_putargr(JIT_R1, in);            /* Update the argument */
55     jump = jit_jmpi();
56     jit_patch_at(jump, fact_entry);     /* Tail Call Optimize it! */
57     jit_patch(fact_out);
58     jit_retr(JIT_R0);                   /* Return the accumulator */
59
60     factorial = jit_emit();
61     /* no need to query information about resolved addresses */
62     jit_clear_state();
63
64     if (argc == 2)
65         arg = atoi(argv[1]);
66     else
67         arg = 5;
68
69     /* call the generated code */
70     printf("factorial(%ld) = %ld\n", arg, factorial(arg));
71     /* release all memory associated with the _jit identifier */
72     jit_destroy_state();
73     finish_jit();
74     return 0;
75 }