2 #include "rvmcodegen.h"
6 rvm_codegen_t *rvm_codegen_create()
10 cg = (rvm_codegen_t *)r_malloc(sizeof(*cg));
13 r_memset(cg, 0, sizeof(*cg));
14 cg->code = r_array_create(sizeof(rvm_asmins_t));
15 cg->data = r_array_create(sizeof(rbyte));
16 cg->codemap = rvm_codemap_create();
17 cg->relocmap = rvm_relocmap_create();
18 cg->sourceidx = r_array_create(sizeof(rsize_t));
23 void rvm_codegen_destroy(rvm_codegen_t *cg)
25 rvm_codemap_destroy(cg->codemap);
26 rvm_relocmap_destroy(cg->relocmap);
27 r_array_destroy(cg->data);
28 r_array_destroy(cg->code);
29 r_array_destroy(cg->sourceidx);
34 void rvm_codegen_clear(rvm_codegen_t *cg)
36 r_array_setlength(cg->code, 0);
37 r_array_setlength(cg->data, 0);
38 rvm_codemap_clear(cg->codemap);
39 rvm_relocmap_clear(cg->relocmap);
43 void rvm_codegen_setsource(rvm_codegen_t *cg, rsize_t srcidx)
45 cg->cursrcidx = srcidx;
49 rlong rvm_codegen_getsource(rvm_codegen_t *cg, rsize_t codeidx)
51 if (codeidx >= r_array_length(cg->sourceidx))
53 return r_array_index(cg->sourceidx, codeidx, rlong);
57 rvm_asmins_t *rvm_codegen_getcode(rvm_codegen_t *cg, ruint index)
59 return (rvm_asmins_t *)r_array_slot(cg->code, index);
63 rsize_t rvm_codegen_getcodesize(rvm_codegen_t *cg)
65 return r_array_length(cg->code);
68 void rvm_codegen_setcodesize(rvm_codegen_t *cg, ruint size)
70 r_array_setlength(cg->code, size);
74 rsize_t rvm_codegen_addins(rvm_codegen_t *cg, rvm_asmins_t ins)
78 codeidx = r_array_add(cg->code, &ins);
79 r_array_replace(cg->sourceidx, codeidx, &cg->cursrcidx);
84 rlong rvm_codegen_redefinelabel(rvm_codegen_t *cg, rlong index, rulong offset)
86 rlong codeidx = rvm_codemap_lookupadd_s(cg->codemap, ".code");
87 rvm_codelabel_t *label = rvm_codemap_label(cg->codemap, index);
91 rvm_codelabel_setoffset(label, codeidx, RVM_CODE2BYTE_OFFSET(offset));
96 rlong rvm_codegen_redefinelabel_default(rvm_codegen_t *cg, rlong index)
98 return rvm_codegen_redefinelabel(cg, index, rvm_codegen_getcodesize(cg));
102 rlong rvm_codegen_validlabel(rvm_codegen_t *cg, rlong index)
104 return rvm_codemap_validindex(cg->codemap, index);
108 rlong rvm_codegen_redefinepointer(rvm_codegen_t *cg, rlong index, rpointer data)
110 rvm_codelabel_t *label = rvm_codemap_label(cg->codemap, index);
114 // return rvm_codemap_addpointer(cg->codemap, label->name->str, label->name->size, data);
115 rvm_codelabel_setpointer(label, data);
120 rlong rvm_codegen_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize, rulong offset)
122 return rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookupadd_s(cg->codemap, ".code"), RVM_CODE2BYTE_OFFSET(offset));
126 rlong rvm_codegen_addlabel_s(rvm_codegen_t *cg, const rchar* name, rulong offset)
128 return rvm_codegen_addlabel(cg, name, r_strlen(name), offset);
132 rlong rvm_codegen_addlabel_default(rvm_codegen_t *cg, const rchar* name, ruint namesize)
134 return rvm_codegen_addlabel(cg, name, namesize, rvm_codegen_getcodesize(cg));
138 rlong rvm_codegen_addlabel_default_s(rvm_codegen_t *cg, const rchar* name)
140 return rvm_codegen_addlabel_default(cg, name, r_strlen(name));
144 rlong rvm_codegen_invalid_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize)
146 return rvm_codemap_invalid_add(cg->codemap, name, namesize);
150 rlong rvm_codegen_invalid_addlabel_s(rvm_codegen_t *cg, const rchar* name)
152 return rvm_codegen_invalid_addlabel(cg, name, r_strlen(name));
156 rsize_t rvm_codegen_addlabelins(rvm_codegen_t *cg, const rchar* name, ruint namesize, rvm_asmins_t ins)
158 rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookupadd_s(cg->codemap, ".code"), RVM_CODE2BYTE_OFFSET(rvm_codegen_getcodesize(cg)));
159 return rvm_codegen_addins(cg, ins);
163 rsize_t rvm_codegen_addlabelins_s(rvm_codegen_t *cg, const rchar* name, rvm_asmins_t ins)
165 return rvm_codegen_addlabelins(cg, name, r_strlen(name), ins);
169 rsize_t rvm_codegen_index_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, rulong index, rvm_asmins_t ins)
171 rvm_relocmap_add(cg->relocmap, RVM_RELOC_CODE, type, rvm_codegen_getcodesize(cg), index);
172 return rvm_codegen_addins(cg, ins);
176 rsize_t rvm_codegen_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, ruint namesize, rvm_asmins_t ins)
178 return rvm_codegen_index_addrelocins(cg, type, rvm_codemap_lookupadd(cg->codemap, name, namesize), ins);
182 rsize_t rvm_codegen_addrelocins_s(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, rvm_asmins_t ins)
184 return rvm_codegen_addrelocins(cg, type, name, r_strlen(name), ins);
188 rint rvm_codegen_relocate(rvm_codegen_t *cg, rvm_codelabel_t **err)
190 rvm_codemap_addpointer_s(cg->codemap, ".code", r_array_slot(cg->code, 0));
191 rvm_codemap_addpointer_s(cg->codemap, ".data", r_array_slot(cg->data, 0));
192 return rvm_relocmap_relocate(cg->relocmap, cg->codemap, (rvm_asmins_t *)r_array_slot(cg->code, 0), err);
196 rsize_t rvm_codegen_insertins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins)
198 return r_array_insert(cg->code, index, &ins);
202 rsize_t rvm_codegen_replaceins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins)
204 return r_array_replace(cg->code, index, &ins);
209 ruint rvm_codegen_funcstart(rvm_codegen_t *cg, const rchar* name, ruint namesize, ruint args)
212 rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
213 start = rvm_codegen_addlabelins(cg, name, namesize, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
214 rvm_codegen_addins(cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
215 rvm_codegen_addins(cg, rvm_asm(RVM_ADD, SP, SP, DA, args));
216 // rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookupadd_s(cg->codemap, ".code"), start);
221 ruint rvm_codegen_funcstart_s(rvm_codegen_t *cg, const rchar* name, ruint args)
223 return rvm_codegen_funcstart(cg, name, r_strlen(name), args);
227 ruint rvm_codegen_vargs_funcstart(rvm_codegen_t *cg, const rchar* name, ruint namesize)
230 rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
231 start = rvm_codegen_addlabelins(cg, name, namesize, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
232 rvm_codegen_addins(cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
233 rvm_codegen_addins(cg, rvm_asm(RVM_ADD, SP, SP, R0, 0));
234 // rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookupadd_s(cg->codemap, ".code"), start);
239 ruint rvm_codegen_vargs_funcstart_s(rvm_codegen_t *cg, const rchar* name)
241 return rvm_codegen_vargs_funcstart(cg, name, r_strlen(name));
245 void rvm_codegen_funcend(rvm_codegen_t *cg)
247 rvm_codegen_addins(cg, rvm_asm(RVM_MOV, SP, FP, XX, 0));
248 rvm_codegen_addins(cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
249 rvm_codegen_addins(cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
252 rlong rvm_codegen_adddata(rvm_codegen_t *cg, const rchar *name, ruint namesize, rconstpointer data, rsize_t size)
255 rulong cursize = R_SIZE_ALIGN(r_array_length(cg->data), sizeof(rword));
257 r_array_setlength(cg->data, cursize + size + sizeof(rword) + 1);
258 buffer = r_array_slot(cg->data, cursize);
259 r_memset(buffer, 0, size + sizeof(rword));
260 r_memmove(buffer, data, size);
261 return rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookupadd_s(cg->codemap, ".data"), cursize);
265 rlong rvm_codegen_adddata_s(rvm_codegen_t *cg, const rchar *name, rconstpointer data, rsize_t size)
267 return rvm_codegen_adddata(cg, name, r_strlen(name), data, size);
271 rlong rvm_codegen_addstring(rvm_codegen_t *cg, const rchar *name, ruint namesize, const rchar* data)
273 return rvm_codegen_adddata(cg, name, namesize, data, r_strlen(data) + 1);
277 rlong rvm_codegen_addstring_s(rvm_codegen_t *cg, const rchar *name, const rchar* data)
279 return rvm_codegen_addstring(cg, name, r_strlen(name), data);
283 rlong rvm_codegen_add_numlabel_s(rvm_codegen_t *cg, const rchar *alphaname, rlong numname)
287 r_memset(label, 0, sizeof(label));
288 r_snprintf(label, sizeof(label) - 1, "L%07ld__%s:", numname, alphaname);
289 return rvm_codegen_addlabel_default_s(cg, label);
293 rlong rvm_codegen_invalid_add_numlabel_s(rvm_codegen_t *cg, const rchar *alphaname, rlong numname)
297 r_memset(label, 0, sizeof(label));
298 r_snprintf(label, sizeof(label) - 1, "L%07ld__%s:", numname, alphaname);
299 return rvm_codegen_invalid_addlabel_s(cg, label);