Commit | Line | Data |
---|---|---|
4a71579b PC |
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 | } |