RPA Toolkit
Modified the public API of rvm_relocmap_t to add support for multiple relocation...
[rpatk.git] / rvm / rvmcodegen.c
1 #include "rmem.h"
2 #include "rvmcodegen.h"
3 #include "rvmcpu.h"
4
5
6 rvm_codegen_t *rvm_codegen_create()
7 {
8         rvm_codegen_t *cg;
9
10         cg = (rvm_codegen_t *)r_malloc(sizeof(*cg));
11         if (!cg)
12                 return (NULL);
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));
19         return cg;
20 }
21
22
23 void rvm_codegen_destroy(rvm_codegen_t *cg)
24 {
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);
30         r_free(cg);
31 }
32
33
34 void rvm_codegen_clear(rvm_codegen_t *cg)
35 {
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);
40 }
41
42
43 void rvm_codegen_setsource(rvm_codegen_t *cg, rsize_t srcidx)
44 {
45         cg->cursrcidx = srcidx;
46 }
47
48
49 rlong rvm_codegen_getsource(rvm_codegen_t *cg, rsize_t codeidx)
50 {
51         if (codeidx >= r_array_length(cg->sourceidx))
52                 return -1;
53         return r_array_index(cg->sourceidx, codeidx, rlong);
54 }
55
56
57 rvm_asmins_t *rvm_codegen_getcode(rvm_codegen_t *cg, ruint index)
58 {
59         return (rvm_asmins_t *)r_array_slot(cg->code, index);
60 }
61
62
63 rsize_t rvm_codegen_getcodesize(rvm_codegen_t *cg)
64 {
65         return r_array_length(cg->code);
66 }
67
68 void rvm_codegen_setcodesize(rvm_codegen_t *cg, ruint size)
69 {
70         r_array_setlength(cg->code, size);
71 }
72
73
74 rsize_t rvm_codegen_addins(rvm_codegen_t *cg, rvm_asmins_t ins)
75 {
76         rsize_t codeidx;
77
78         codeidx = r_array_add(cg->code, &ins);
79         r_array_replace(cg->sourceidx, codeidx, &cg->cursrcidx);
80         return codeidx;
81 }
82
83
84 rlong rvm_codegen_redefinelabel(rvm_codegen_t *cg, rlong index, rulong offset)
85 {
86         rlong codeidx = rvm_codemap_lookupadd_s(cg->codemap, ".code");
87         rvm_codelabel_t *label = rvm_codemap_label(cg->codemap, index);
88
89         if (!label)
90                 return -1;
91         rvm_codelabel_setoffset(label, codeidx, RVM_CODE2BYTE_OFFSET(offset));
92         return index;
93 }
94
95
96 rlong rvm_codegen_redefinelabel_default(rvm_codegen_t *cg, rlong index)
97 {
98         return rvm_codegen_redefinelabel(cg, index, rvm_codegen_getcodesize(cg));
99 }
100
101
102 rlong rvm_codegen_validlabel(rvm_codegen_t *cg, rlong index)
103 {
104         return rvm_codemap_validindex(cg->codemap, index);
105 }
106
107
108 rlong rvm_codegen_redefinepointer(rvm_codegen_t *cg, rlong index, rpointer data)
109 {
110         rvm_codelabel_t *label = rvm_codemap_label(cg->codemap, index);
111
112         if (!label)
113                 return -1;
114 //      return rvm_codemap_addpointer(cg->codemap, label->name->str, label->name->size, data);
115         rvm_codelabel_setpointer(label, data);
116         return index;
117 }
118
119
120 rlong rvm_codegen_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize, rulong offset)
121 {
122         return rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookupadd_s(cg->codemap, ".code"), RVM_CODE2BYTE_OFFSET(offset));
123 }
124
125
126 rlong rvm_codegen_addlabel_s(rvm_codegen_t *cg, const rchar* name, rulong offset)
127 {
128         return rvm_codegen_addlabel(cg, name, r_strlen(name), offset);
129 }
130
131
132 rlong rvm_codegen_addlabel_default(rvm_codegen_t *cg, const rchar* name, ruint namesize)
133 {
134         return rvm_codegen_addlabel(cg, name, namesize, rvm_codegen_getcodesize(cg));
135 }
136
137
138 rlong rvm_codegen_addlabel_default_s(rvm_codegen_t *cg, const rchar* name)
139 {
140         return rvm_codegen_addlabel_default(cg, name, r_strlen(name));
141 }
142
143
144 rlong rvm_codegen_invalid_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize)
145 {
146         return rvm_codemap_invalid_add(cg->codemap, name, namesize);
147 }
148
149
150 rlong rvm_codegen_invalid_addlabel_s(rvm_codegen_t *cg, const rchar* name)
151 {
152         return rvm_codegen_invalid_addlabel(cg, name, r_strlen(name));
153 }
154
155
156 rsize_t rvm_codegen_addlabelins(rvm_codegen_t *cg, const rchar* name, ruint namesize, rvm_asmins_t ins)
157 {
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);
160 }
161
162
163 rsize_t rvm_codegen_addlabelins_s(rvm_codegen_t *cg, const rchar* name, rvm_asmins_t ins)
164 {
165         return rvm_codegen_addlabelins(cg, name, r_strlen(name), ins);
166 }
167
168
169 rsize_t rvm_codegen_index_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, rulong index, rvm_asmins_t ins)
170 {
171         rvm_relocmap_add(cg->relocmap, RVM_RELOC_CODE, type, rvm_codegen_getcodesize(cg), index);
172         return rvm_codegen_addins(cg, ins);
173 }
174
175
176 rsize_t rvm_codegen_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, ruint namesize, rvm_asmins_t ins)
177 {
178         return rvm_codegen_index_addrelocins(cg, type, rvm_codemap_lookupadd(cg->codemap, name, namesize), ins);
179 }
180
181
182 rsize_t rvm_codegen_addrelocins_s(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, rvm_asmins_t ins)
183 {
184         return rvm_codegen_addrelocins(cg, type, name, r_strlen(name), ins);
185 }
186
187
188 rint rvm_codegen_relocate(rvm_codegen_t *cg, rvm_codelabel_t **err)
189 {
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);
193 }
194
195
196 rsize_t rvm_codegen_insertins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins)
197 {
198         return r_array_insert(cg->code, index, &ins);
199 }
200
201
202 rsize_t rvm_codegen_replaceins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins)
203 {
204         return r_array_replace(cg->code, index, &ins);
205
206 }
207
208
209 ruint rvm_codegen_funcstart(rvm_codegen_t *cg, const rchar* name, ruint namesize, ruint args)
210 {
211         ruint start;
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);
217         return start;
218 }
219
220
221 ruint rvm_codegen_funcstart_s(rvm_codegen_t *cg, const rchar* name, ruint args)
222 {
223         return rvm_codegen_funcstart(cg, name, r_strlen(name), args);
224 }
225
226
227 ruint rvm_codegen_vargs_funcstart(rvm_codegen_t *cg, const rchar* name, ruint namesize)
228 {
229         ruint start;
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);
235         return start;
236 }
237
238
239 ruint rvm_codegen_vargs_funcstart_s(rvm_codegen_t *cg, const rchar* name)
240 {
241         return rvm_codegen_vargs_funcstart(cg, name, r_strlen(name));
242 }
243
244
245 void rvm_codegen_funcend(rvm_codegen_t *cg)
246 {
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));
250 }
251
252 rlong rvm_codegen_adddata(rvm_codegen_t *cg, const rchar *name, ruint namesize, rconstpointer data, rsize_t size)
253 {
254         rpointer buffer;
255         rulong cursize = R_SIZE_ALIGN(r_array_length(cg->data), sizeof(rword));
256
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);
262 }
263
264
265 rlong rvm_codegen_adddata_s(rvm_codegen_t *cg, const rchar *name, rconstpointer data, rsize_t size)
266 {
267         return rvm_codegen_adddata(cg, name, r_strlen(name), data, size);
268 }
269
270
271 rlong rvm_codegen_addstring(rvm_codegen_t *cg, const rchar *name, ruint namesize, const rchar* data)
272 {
273         return rvm_codegen_adddata(cg, name, namesize, data, r_strlen(data) + 1);
274 }
275
276
277 rlong rvm_codegen_addstring_s(rvm_codegen_t *cg, const rchar *name, const rchar* data)
278 {
279         return rvm_codegen_addstring(cg, name, r_strlen(name), data);
280 }
281
282
283 rlong rvm_codegen_add_numlabel_s(rvm_codegen_t *cg, const rchar *alphaname, rlong numname)
284 {
285         rchar label[128];
286
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);
290 }
291
292
293 rlong rvm_codegen_invalid_add_numlabel_s(rvm_codegen_t *cg, const rchar *alphaname, rlong numname)
294 {
295         rchar label[128];
296
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);
300 }
301