RPA Toolkit
9ead57be85994a1e382fb8fa00e4a85267a17d55
[rpatk.git] / rpa2 / rpacompiler.c
1 #include "rmem.h"
2 #include "rpacompiler.h"
3 #include "rstring.h"
4
5
6 void rpacompiler_mnode_nan(rpa_compiler_t *co)
7 {
8         rvm_codegen_addlabel_s(co->cg, "rpacompiler_mnode_nan");
9         rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, R_WHT, XX, XX, 0));
10 }
11
12
13 void rpacompiler_mnode_opt(rpa_compiler_t *co)
14 {
15         rvm_codegen_addlabel_s(co->cg, "rpacompiler_mnode_opt");
16         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, LR, XX, XX, 0));
17         rvm_codegen_addins(co->cg, rvm_asm(RVM_BXL, R_WHT, XX, XX, 0));
18         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, LR, XX, XX, 0));
19         rvm_codegen_addins(co->cg, rvm_asml(RVM_CMP, R0, DA, XX, 0));
20         rvm_codegen_addins(co->cg, rvm_asm(RVM_BXGRE, LR, XX, XX, 0));
21         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, 0));
22         rvm_codegen_addins(co->cg, rvm_asm(RVM_CMP, R0, R0, XX, 0));
23         rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
24 }
25
26
27 void rpacompiler_mnode_mul(rpa_compiler_t *co)
28 {
29         rvm_codegen_addlabel_s(co->cg, "rpacompiler_mnode_mul");
30         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, LR, XX, XX, 0));
31         rvm_codegen_addins(co->cg, rvm_asm(RVM_BXL, R_WHT, XX, XX, 0));
32         rvm_codegen_addins(co->cg, rvm_asml(RVM_CMP, R0, DA, XX, 0));
33         rvm_codegen_addins(co->cg, rvm_asm(RVM_BGRE, DA, XX, XX, 2));
34         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, PC, XX, XX, 0));
35         rvm_codegen_addins(co->cg, rvm_asm(RVM_CLR, R1, XX, XX, 0));
36         rvm_codegen_addins(co->cg, rvm_asm(RVM_ADD, R0, R0, R1, 0));
37         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
38         rvm_codegen_addins(co->cg, rvm_asm(RVM_BXL, R_WHT, XX, XX, 0));
39         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
40         rvm_codegen_addins(co->cg, rvm_asml(RVM_CMP, R0, DA, XX, 0));
41         rvm_codegen_addins(co->cg, rvm_asm(RVM_BGRE, DA, XX, XX, -5));
42         rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDS, R0, R1, DA, 0));
43         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, PC, XX, XX, 0));
44 }
45
46
47 void rpacompiler_mnode_mop(rpa_compiler_t *co)
48 {
49         rvm_codegen_addlabel_s(co->cg, "rpacompiler_mnode_mop");
50         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, LR, XX, XX, 0));
51         rvm_codegen_addins(co->cg, rvm_asm(RVM_BXL, R_WHT, XX, XX, 0));
52         rvm_codegen_addins(co->cg, rvm_asml(RVM_CMP, R0, DA, XX, 0));
53         rvm_codegen_addins(co->cg, rvm_asm(RVM_BGRE, DA, XX, XX, 4));
54         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, 0));
55         rvm_codegen_addins(co->cg, rvm_asml(RVM_CMP, R0, R0, XX, 0));
56         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, PC, XX, XX, 0));
57         rvm_codegen_addins(co->cg, rvm_asm(RVM_CLR, R1, XX, XX, 0));
58         rvm_codegen_addins(co->cg, rvm_asm(RVM_ADD, R0, R0, R1, 0));
59         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSH, R0, XX, XX, 0));
60         rvm_codegen_addins(co->cg, rvm_asm(RVM_BXL, R_WHT, XX, XX, 0));
61         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, R1, XX, XX, 0));
62         rvm_codegen_addins(co->cg, rvm_asml(RVM_CMP, R0, DA, XX, 0));
63         rvm_codegen_addins(co->cg, rvm_asm(RVM_BGRE, DA, XX, XX, -5));
64         rvm_codegen_addins(co->cg, rvm_asm(RVM_ADDS, R0, R1, DA, 0));
65         rvm_codegen_addins(co->cg, rvm_asm(RVM_POP, PC, XX, XX, 0));
66 }
67
68
69 rpa_compiler_t *rpa_compiler_create()
70 {
71         rpa_compiler_t *co;
72
73         co = r_malloc(sizeof(*co));
74         r_memset(co, 0, sizeof(*co));
75         co->cg = rvm_codegen_create();
76         co->scope = rvm_scope_create();
77         co->expressions = r_array_create(sizeof(rpa_ruledef_t));
78         rpacompiler_mnode_nan(co);
79         rpacompiler_mnode_opt(co);
80         rpacompiler_mnode_mul(co);
81         rpacompiler_mnode_mop(co);
82         return co;
83 }
84
85
86 void rpa_compiler_destroy(rpa_compiler_t *co)
87 {
88         if (co) {
89                 rvm_codegen_destroy(co->cg);
90                 rvm_scope_destroy(co->scope);
91                 r_object_destroy((robject_t*)co->expressions);
92         }
93         r_free(co);
94 }
95
96
97 rint rpa_compiler_rule_begin(rpa_compiler_t *co, const rchar *name, ruint namesize)
98 {
99         rpa_ruledef_t exp;
100         rchar endlabel[64];
101
102         r_memset(&exp, 0, sizeof(exp));
103         exp.emitidx = rvm_codegen_adddata_s(co->cg, NULL, name, namesize);
104         exp.labelidx = rvm_codegen_addlabel(co->cg, name, namesize);
105         exp.start = rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_STRING, exp.emitidx, rvm_asm(RPA_EMITSTART, DA, R_TOP, XX, 0));
106         rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R_TOP)|BIT(R_WHT)|BIT(LR)));
107         r_snprintf(endlabel, sizeof(endlabel) - 1, "__end:%ld", exp.start);
108         exp.endidx = rvm_codemap_invalid_add_s(co->cg->codemap, endlabel);
109         r_array_add(co->expressions, &exp);
110         return 0;
111 }
112
113
114 rint rpa_compiler_rule_begin_s(rpa_compiler_t *co, const rchar *name)
115 {
116         return rpa_compiler_rule_begin(co, name, r_strlen(name));
117 }
118
119
120 rint rpa_compiler_rule_end(rpa_compiler_t *co)
121 {
122         rpa_ruledef_t exp = r_array_pop(co->expressions, rpa_ruledef_t);
123
124         rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R1)|BIT(R_WHT)|BIT(LR)));
125         rvm_codegen_addins(co->cg, rvm_asm(RVM_SUBS, R0, R_TOP, R1, 0));
126         rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_STRING, exp.emitidx, rvm_asm(RPA_EMITEND, DA, R1, R0, 0));
127         rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
128         rvm_codegen_redefinelabel(co->cg, exp.endidx);
129         rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R_TOP)|BIT(R_WHT)|BIT(LR)));
130         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, -1));
131         rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
132         return 0;
133 }
134
135
136 rint rpa_compiler_exp_begin(rpa_compiler_t *co)
137 {
138         rpa_ruledef_t exp;
139         rchar endlabel[64];
140
141         exp.branch = rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 0));
142         r_snprintf(endlabel, sizeof(endlabel) - 1, "__begin:%ld", rvm_codegen_getcodesize(co->cg));
143         exp.labelidx = rvm_codegen_addlabel_s(co->cg, endlabel);
144         exp.start = rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R_TOP)|BIT(R_WHT)|BIT(LR)));
145         r_snprintf(endlabel, sizeof(endlabel) - 1, "__end:%ld", exp.start);
146         exp.endidx = rvm_codemap_invalid_add_s(co->cg->codemap, endlabel);
147         r_array_add(co->expressions, &exp);
148         return 0;
149 }
150
151
152 rint rpa_compiler_exp_end(rpa_compiler_t *co, ruint qflag)
153 {
154         rpa_ruledef_t exp = r_array_pop(co->expressions, rpa_ruledef_t);
155
156         rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R1)|BIT(R_WHT)|BIT(LR)));
157         rvm_codegen_addins(co->cg, rvm_asm(RVM_SUBS, R0, R_TOP, R1, 0));
158         rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
159         rvm_codegen_redefinelabel(co->cg, exp.endidx);
160         rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R_TOP)|BIT(R_WHT)|BIT(LR)));
161         rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, -1));
162         rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
163         rvm_codegen_replaceins(co->cg, exp.branch, rvm_asm(RVM_B, DA, XX, XX, rvm_codegen_getcodesize(co->cg) - exp.branch));
164         rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_JUMP, exp.labelidx, rvm_asm(RPA_BXLWHT, R_MNODE_NAN, DA, XX, 0));
165
166         return 0;
167 }
168