2 #include "rpacompiler.h"
6 void rpacompiler_mnode_nan(rpa_compiler_t *co)
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));
13 void rpacompiler_mnode_opt(rpa_compiler_t *co)
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));
27 void rpacompiler_mnode_mul(rpa_compiler_t *co)
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));
47 void rpacompiler_mnode_mop(rpa_compiler_t *co)
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));
69 rpa_compiler_t *rpa_compiler_create()
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);
86 void rpa_compiler_destroy(rpa_compiler_t *co)
89 rvm_codegen_destroy(co->cg);
90 rvm_scope_destroy(co->scope);
91 r_object_destroy((robject_t*)co->expressions);
97 rint rpa_compiler_rule_begin(rpa_compiler_t *co, const rchar *name, ruint namesize)
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);
114 rint rpa_compiler_rule_begin_s(rpa_compiler_t *co, const rchar *name)
116 return rpa_compiler_rule_begin(co, name, r_strlen(name));
120 rint rpa_compiler_rule_end(rpa_compiler_t *co)
122 rpa_ruledef_t exp = r_array_pop(co->expressions, rpa_ruledef_t);
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));
136 rint rpa_compiler_exp_begin(rpa_compiler_t *co)
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);
152 rint rpa_compiler_exp_end(rpa_compiler_t *co, ruint qflag)
154 rpa_ruledef_t exp = r_array_pop(co->expressions, rpa_ruledef_t);
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(RVM_MOV, R_WHT, DA, XX, 0));
165 if (qflag == RPA_MATCH_OPTIONAL) {
166 rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_opt", rvm_asm(RVM_BL, DA, XX, XX, 0));
167 } else if (qflag == RPA_MATCH_MULTIPLE) {
168 rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_mul", rvm_asm(RVM_BL, DA, XX, XX, 0));
169 } else if (qflag == RPA_MATCH_MULTIOPT) {
170 rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_mop", rvm_asm(RVM_BL, DA, XX, XX, 0));
172 rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_nan", rvm_asm(RVM_BL, DA, XX, XX, 0));
178 rint rpa_compiler_altexp_begin(rpa_compiler_t *co)
183 exp.branch = rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 0));
184 r_snprintf(endlabel, sizeof(endlabel) - 1, "__begin:%ld", rvm_codegen_getcodesize(co->cg));
185 exp.labelidx = rvm_codegen_addlabel_s(co->cg, endlabel);
186 exp.start = rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R_TOP)|BIT(R_WHT)|BIT(LR)));
187 r_snprintf(endlabel, sizeof(endlabel) - 1, "__end:%ld", exp.start);
188 exp.endidx = rvm_codemap_invalid_add_s(co->cg->codemap, endlabel);
189 r_array_add(co->expressions, &exp);
194 rint rpa_compiler_altexp_end(rpa_compiler_t *co, ruint qflag)
196 rpa_ruledef_t exp = r_array_pop(co->expressions, rpa_ruledef_t);
198 rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R_TOP)|BIT(R_WHT)|BIT(LR)));
199 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, -1));
200 rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
201 rvm_codegen_redefinelabel(co->cg, exp.endidx);
202 rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R1)|BIT(R_WHT)|BIT(LR)));
203 rvm_codegen_addins(co->cg, rvm_asm(RVM_SUBS, R0, R_TOP, R1, 0));
204 rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
206 rvm_codegen_replaceins(co->cg, exp.branch, rvm_asm(RVM_B, DA, XX, XX, rvm_codegen_getcodesize(co->cg) - exp.branch));
207 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_JUMP, exp.labelidx, rvm_asm(RVM_MOV, R_WHT, DA, XX, 0));
208 if (qflag == RPA_MATCH_OPTIONAL) {
209 rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_opt", rvm_asm(RVM_BL, DA, XX, XX, 0));
210 } else if (qflag == RPA_MATCH_MULTIPLE) {
211 rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_mul", rvm_asm(RVM_BL, DA, XX, XX, 0));
212 } else if (qflag == RPA_MATCH_MULTIOPT) {
213 rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_mop", rvm_asm(RVM_BL, DA, XX, XX, 0));
215 rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_nan", rvm_asm(RVM_BL, DA, XX, XX, 0));
221 rint rpa_compiler_altbranch_begin(rpa_compiler_t *co)
226 exp.branch = rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 0));
227 r_snprintf(endlabel, sizeof(endlabel) - 1, "__begin:%ld", rvm_codegen_getcodesize(co->cg));
228 exp.labelidx = rvm_codegen_addlabel_s(co->cg, endlabel);
229 exp.start = rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R_TOP)|BIT(R_WHT)|BIT(LR)));
230 r_snprintf(endlabel, sizeof(endlabel) - 1, "__end:%ld", exp.start);
231 exp.endidx = rvm_codemap_invalid_add_s(co->cg->codemap, endlabel);
232 r_array_add(co->expressions, &exp);
237 rint rpa_compiler_altbranch_end(rpa_compiler_t *co, ruint qflag)
239 rpa_ruledef_t exp = r_array_pop(co->expressions, rpa_ruledef_t);
241 rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R1)|BIT(R_WHT)|BIT(LR)));
242 rvm_codegen_addins(co->cg, rvm_asm(RVM_SUBS, R0, R_TOP, R1, 0));
243 rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
244 rvm_codegen_redefinelabel(co->cg, exp.endidx);
245 rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(R_TOP)|BIT(R_WHT)|BIT(LR)));
246 rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, -1));
247 rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
248 rvm_codegen_replaceins(co->cg, exp.branch, rvm_asm(RVM_B, DA, XX, XX, rvm_codegen_getcodesize(co->cg) - exp.branch));
249 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_JUMP, exp.labelidx, rvm_asm(RVM_MOV, R_WHT, DA, XX, 0));
250 if (qflag == RPA_MATCH_OPTIONAL) {
251 rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_opt", rvm_asm(RVM_BL, DA, XX, XX, 0));
252 } else if (qflag == RPA_MATCH_MULTIPLE) {
253 rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_mul", rvm_asm(RVM_BL, DA, XX, XX, 0));
254 } else if (qflag == RPA_MATCH_MULTIOPT) {
255 rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_mop", rvm_asm(RVM_BL, DA, XX, XX, 0));
257 rvm_codegen_addrelocins_s(co->cg, RVM_RELOC_BRANCH, "rpacompiler_mnode_nan", rvm_asm(RVM_BL, DA, XX, XX, 0));
259 rvm_codegen_index_addrelocins(co->cg, RVM_RELOC_BRANCH, RPA_COMPILER_CURRENTEXP(co)->endidx, rvm_asm(RVM_BGRE, DA, XX, XX, 0));