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 
main(int argc,char * argv[])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 }
76