1 #include <lightning.h>
2 #include <stdio.h>
3 
4 jit_state_t		*_jit;
5 long			 top;
6 long			 stk[1024];
7 
8 int
main(int argc,char * argv[])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 }
124