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();
22 void rvm_codegen_destroy(rvm_codegen_t *cg)
24 rvm_codemap_destroy(cg->codemap);
25 rvm_relocmap_destroy(cg->relocmap);
26 r_object_destroy((robject_t*)cg->data);
27 r_object_destroy((robject_t*)cg->code);
32 void rvm_codegen_clear(rvm_codegen_t *cg)
34 r_array_setlength(cg->code, 0);
35 r_array_setlength(cg->data, 0);
36 rvm_codemap_clear(cg->codemap);
37 rvm_relocmap_clear(cg->relocmap);
41 rvm_asmins_t *rvm_codegen_getcode(rvm_codegen_t *cg, ruint index)
43 return (rvm_asmins_t *)r_array_slot(cg->code, index);
47 rulong rvm_codegen_getcodesize(rvm_codegen_t *cg)
49 return r_array_length(cg->code);
52 void rvm_codegen_setcodesize(rvm_codegen_t *cg, ruint size)
54 r_array_setlength(cg->code, size);
58 ruint rvm_codegen_addins(rvm_codegen_t *cg, rvm_asmins_t ins)
60 return r_array_add(cg->code, &ins);
64 rlong rvm_codegen_redefinelabel(rvm_codegen_t *cg, rlong index)
66 rvm_codelabel_t *label = rvm_codemap_label(cg->codemap, index);
70 return rvm_codemap_addoffset(cg->codemap, label->name->str, label->name->size, rvm_codemap_lookup_s(cg->codemap, ".code"), RVM_CODE2BYTE_OFFSET(rvm_codegen_getcodesize(cg)));
74 rlong rvm_codegen_redefinepointer(rvm_codegen_t *cg, rlong index, rpointer data)
76 rvm_codelabel_t *label = rvm_codemap_label(cg->codemap, index);
80 return rvm_codemap_addpointer(cg->codemap, label->name->str, label->name->size, data);
84 rlong rvm_codegen_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize)
86 return rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), RVM_CODE2BYTE_OFFSET(rvm_codegen_getcodesize(cg)));
90 rlong rvm_codegen_addlabel_s(rvm_codegen_t *cg, const rchar* name)
92 return rvm_codegen_addlabel(cg, name, r_strlen(name));
96 rlong rvm_codegen_invalid_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize)
98 return rvm_codemap_invalid_add(cg->codemap, name, namesize);
102 rlong rvm_codegen_invalid_addlabel_s(rvm_codegen_t *cg, const rchar* name)
104 return rvm_codegen_invalid_addlabel(cg, name, r_strlen(name));
108 ruint rvm_codegen_addlabelins(rvm_codegen_t *cg, const rchar* name, ruint namesize, rvm_asmins_t ins)
110 rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), RVM_CODE2BYTE_OFFSET(rvm_codegen_getcodesize(cg)));
111 return rvm_codegen_addins(cg, ins);
115 ruint rvm_codegen_addlabelins_s(rvm_codegen_t *cg, const rchar* name, rvm_asmins_t ins)
117 return rvm_codegen_addlabelins(cg, name, r_strlen(name), ins);
121 ruint rvm_codegen_index_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, rulong index, rvm_asmins_t ins)
123 rvm_relocmap_add(cg->relocmap, type, rvm_codegen_getcodesize(cg), index);
124 return rvm_codegen_addins(cg, ins);
128 ruint rvm_codegen_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, ruint namesize, rvm_asmins_t ins)
130 return rvm_codegen_index_addrelocins(cg, type, rvm_codemap_lookup(cg->codemap, name, namesize), ins);
134 ruint rvm_codegen_addrelocins_s(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, rvm_asmins_t ins)
136 return rvm_codegen_addrelocins(cg, type, name, r_strlen(name), ins);
140 rint rvm_codegen_relocate(rvm_codegen_t *cg, rvm_codelabel_t **err)
142 rvm_codemap_addpointer_s(cg->codemap, ".code", r_array_slot(cg->code, 0));
143 rvm_codemap_addpointer_s(cg->codemap, ".data", r_array_slot(cg->data, 0));
144 return rvm_relocmap_relocate(cg->relocmap, cg->codemap, (rvm_asmins_t *)r_array_slot(cg->code, 0), err);
148 ruint rvm_codegen_insertins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins)
150 return r_array_insert(cg->code, index, &ins);
154 ruint rvm_codegen_replaceins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins)
156 return r_array_replace(cg->code, index, &ins);
161 ruint rvm_codegen_funcstart(rvm_codegen_t *cg, const rchar* name, ruint namesize, ruint args)
164 rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
165 start = rvm_codegen_addlabelins(cg, name, namesize, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
166 rvm_codegen_addins(cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
167 rvm_codegen_addins(cg, rvm_asm(RVM_ADD, SP, SP, DA, args));
168 // rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), start);
173 ruint rvm_codegen_funcstart_s(rvm_codegen_t *cg, const rchar* name, ruint args)
175 return rvm_codegen_funcstart(cg, name, r_strlen(name), args);
179 ruint rvm_codegen_vargs_funcstart(rvm_codegen_t *cg, const rchar* name, ruint namesize)
182 rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
183 start = rvm_codegen_addlabelins(cg, name, namesize, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
184 rvm_codegen_addins(cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
185 rvm_codegen_addins(cg, rvm_asm(RVM_ADD, SP, SP, R0, 0));
186 // rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), start);
191 ruint rvm_codegen_vargs_funcstart_s(rvm_codegen_t *cg, const rchar* name)
193 return rvm_codegen_vargs_funcstart(cg, name, r_strlen(name));
197 void rvm_codegen_funcend(rvm_codegen_t *cg)
199 rvm_codegen_addins(cg, rvm_asm(RVM_MOV, SP, FP, XX, 0));
200 rvm_codegen_addins(cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
201 rvm_codegen_addins(cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
204 rlong rvm_codegen_adddata(rvm_codegen_t *cg, const rchar *name, ruint namesize, rconstpointer data, rsize_t size)
207 rulong cursize = R_SIZE_ALIGN(r_array_length(cg->data), sizeof(rword));
209 r_array_setlength(cg->data, cursize + size + sizeof(rword));
210 buffer = r_array_slot(cg->data, cursize);
211 r_memset(buffer, 0, size + sizeof(rword));
212 r_memmove(buffer, data, size);
213 return rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".data"), cursize);
217 rlong rvm_codegen_adddata_s(rvm_codegen_t *cg, const rchar *name, rconstpointer data, rsize_t size)
219 return rvm_codegen_adddata(cg, name, r_strlen(name), data, size);
223 rlong rvm_codegen_addstring(rvm_codegen_t *cg, const rchar *name, ruint namesize, const rchar* data)
225 return rvm_codegen_adddata(cg, name, namesize, data, r_strlen(data) + 1);
229 rlong rvm_codegen_addstring_s(rvm_codegen_t *cg, const rchar *name, const rchar* data)
231 return rvm_codegen_addstring(cg, name, r_strlen(name), data);
235 rlong rvm_codegen_add_numlabel_s(rvm_codegen_t *cg, const rchar *alphaname, rlong numname)
239 r_memset(label, 0, sizeof(label));
240 r_snprintf(label, sizeof(label) - 1, "L%07ld__%s:", numname, alphaname);
241 return rvm_codegen_addlabel_s(cg, label);
245 rlong rvm_codegen_invalid_add_numlabel_s(rvm_codegen_t *cg, const rchar *alphaname, rlong numname)
249 r_memset(label, 0, sizeof(label));
250 r_snprintf(label, sizeof(label) - 1, "L%07ld__%s:", numname, alphaname);
251 return rvm_codegen_invalid_addlabel_s(cg, label);