Commit | Line | Data |
---|---|---|
4a71579b PC |
1 | #include <lightning.h> |
2 | #include <stdio.h> | |
3 | ||
4 | jit_state_t *_jit; | |
5 | long top; | |
6 | long stk[1024]; | |
7 | ||
8 | int | |
9 | main(int argc, char *argv[]) | |
10 | { | |
11 | void *address; | |
12 | void (*call)(void*); | |
13 | jit_state_t *frame_jit, *tramp_jit; | |
14 | jit_node_t *arg, *done, *xfibs, *out, *ret1, *ret2; | |
15 | ||
16 | init_jit(argv[0]); | |
17 | _jit = frame_jit = jit_new_state(); | |
18 | jit_name("main"); | |
19 | jit_prolog(); | |
20 | jit_frame(64); | |
21 | ||
22 | arg = jit_arg(); | |
23 | jit_getarg(JIT_R1, arg); | |
24 | ||
25 | /* Initialize language stack */ | |
26 | jit_movi(JIT_R0, (jit_word_t)stk); | |
27 | jit_sti(&top, JIT_R0); | |
28 | ||
29 | /* return address */ | |
30 | done = jit_movi(JIT_R0, 0); | |
31 | /* argument */ | |
32 | jit_movi(JIT_V0, 32); | |
33 | /* jump to code */ | |
34 | jit_jmpr(JIT_R1); | |
35 | jit_patch(done); | |
36 | ||
37 | jit_prepare(); | |
38 | jit_pushargi((jit_word_t)"xfibs(%d) = %d\n"); | |
39 | jit_ellipsis(); | |
40 | jit_pushargi(32); | |
41 | jit_pushargr(JIT_V0); | |
42 | jit_finishi(printf); | |
43 | jit_ret(); | |
44 | jit_epilog(); | |
45 | call = jit_emit(); | |
46 | jit_clear_state(); | |
47 | ||
48 | #define SIZE sizeof(jit_word_t) | |
49 | _jit = tramp_jit = jit_new_state(); | |
50 | jit_name("xfibs"); | |
51 | xfibs = jit_label(); | |
52 | jit_prolog(); | |
53 | jit_tramp(64); | |
54 | out = jit_blti(JIT_V0, 2); | |
55 | jit_subi(JIT_V1, JIT_V0, 1); /* V1 = N-1 */ | |
56 | jit_subi(JIT_V2, JIT_V0, 2); /* V1 = N-2 */ | |
57 | ||
58 | /* save return address */ | |
59 | jit_ldi(JIT_R1, &top); | |
60 | jit_stxi(SIZE * 0, JIT_R1, JIT_R0); | |
61 | /* save operands */ | |
62 | jit_stxi(SIZE * 1, JIT_R1, JIT_V0); | |
63 | jit_stxi(SIZE * 2, JIT_R1, JIT_V1); | |
64 | jit_stxi(SIZE * 3, JIT_R1, JIT_V2); | |
65 | /* adjust "language" stack */ | |
66 | jit_addi(JIT_R1, JIT_R1, SIZE * 4); | |
67 | jit_sti(&top, JIT_R1); | |
68 | ||
69 | /* return address */ | |
70 | ret1 = jit_movi(JIT_R0, 0); | |
71 | /* argument */ | |
72 | jit_movr(JIT_V0, JIT_V1); | |
73 | /* indirect goto */ | |
74 | jit_patch_at(jit_jmpi(), xfibs); | |
75 | jit_patch(ret1); | |
76 | jit_movr(JIT_V1, JIT_V0); /* V1 = rfibs(N-1) */ | |
77 | /* save V1 */ | |
78 | jit_ldi(JIT_R1, &top); | |
79 | jit_stxi(-SIZE * 2, JIT_R1, JIT_V1); | |
80 | ||
81 | /* reload V2 */ | |
82 | jit_ldxi(JIT_V2, JIT_R1, -SIZE * 1); | |
83 | ||
84 | /* return address */ | |
85 | ret2 = jit_movi(JIT_R0, 0); | |
86 | /* argument */ | |
87 | jit_movr(JIT_V0, JIT_V2); | |
88 | /* indirect goto */ | |
89 | jit_patch_at(jit_jmpi(), xfibs); | |
90 | jit_patch(ret2); | |
91 | jit_movr(JIT_V2, JIT_V0); /* V2 = rfibs(N-2) */ | |
92 | ||
93 | /* reload return address */ | |
94 | jit_ldi(JIT_R1, &top); | |
95 | jit_subi(JIT_R1, JIT_R1, SIZE * 4); | |
96 | jit_ldxi(JIT_R0, JIT_R1, SIZE * 0); | |
97 | /* reload operands */ | |
98 | jit_ldxi(JIT_V0, JIT_R1, SIZE * 1); | |
99 | jit_ldxi(JIT_V1, JIT_R1, SIZE * 2); | |
100 | /* V2 already loaded */ | |
101 | /* update "language" stack */ | |
102 | jit_sti(&top, JIT_R1); | |
103 | ||
104 | jit_addi(JIT_V1, JIT_V1, 1); | |
105 | jit_addr(JIT_V0, JIT_V1, JIT_V2); | |
106 | jit_jmpr(JIT_R0); | |
107 | ||
108 | jit_patch(out); | |
109 | jit_movi(JIT_V0, 1); | |
110 | jit_jmpr(JIT_R0); | |
111 | jit_epilog(); | |
112 | ||
113 | address = jit_emit(); | |
114 | jit_clear_state(); | |
115 | ||
116 | (*call)(address); | |
117 | ||
118 | jit_destroy_state(); | |
119 | ||
120 | _jit = frame_jit; | |
121 | jit_destroy_state(); | |
122 | return 0; | |
123 | } |