RPA Toolkit
work on the RJS function definitions.
[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         return cg;
19 }
20
21
22 void rvm_codegen_destroy(rvm_codegen_t *cg)
23 {
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);
28         r_free(cg);
29 }
30
31
32 void rvm_codegen_clear(rvm_codegen_t *cg)
33 {
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);
38 }
39
40
41 rvm_asmins_t *rvm_codegen_getcode(rvm_codegen_t *cg, ruint index)
42 {
43         return (rvm_asmins_t *)r_array_slot(cg->code, index);
44 }
45
46
47 rulong rvm_codegen_getcodesize(rvm_codegen_t *cg)
48 {
49         return r_array_length(cg->code);
50 }
51
52 void rvm_codegen_setcodesize(rvm_codegen_t *cg, ruint size)
53 {
54         r_array_setlength(cg->code, size);
55 }
56
57
58 ruint rvm_codegen_addins(rvm_codegen_t *cg, rvm_asmins_t ins)
59 {
60         return r_array_add(cg->code, &ins);
61 }
62
63
64 rlong rvm_codegen_redefinelabel(rvm_codegen_t *cg, rlong index)
65 {
66         rvm_codelabel_t *label = rvm_codemap_label(cg->codemap, index);
67
68         if (!label)
69                 return -1;
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)));
71 }
72
73
74 rlong rvm_codegen_redefinepointer(rvm_codegen_t *cg, rlong index, rpointer data)
75 {
76         rvm_codelabel_t *label = rvm_codemap_label(cg->codemap, index);
77
78         if (!label)
79                 return -1;
80         return rvm_codemap_addpointer(cg->codemap, label->name->str, label->name->size, data);
81 }
82
83
84 rlong rvm_codegen_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize)
85 {
86         return rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), RVM_CODE2BYTE_OFFSET(rvm_codegen_getcodesize(cg)));
87 }
88
89
90 rlong rvm_codegen_addlabel_s(rvm_codegen_t *cg, const rchar* name)
91 {
92         return rvm_codegen_addlabel(cg, name, r_strlen(name));
93 }
94
95
96 rlong rvm_codegen_invalid_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize)
97 {
98         return rvm_codemap_invalid_add(cg->codemap, name, namesize);
99 }
100
101
102 rlong rvm_codegen_invalid_addlabel_s(rvm_codegen_t *cg, const rchar* name)
103 {
104         return rvm_codegen_invalid_addlabel(cg, name, r_strlen(name));
105 }
106
107
108 ruint rvm_codegen_addlabelins(rvm_codegen_t *cg, const rchar* name, ruint namesize, rvm_asmins_t ins)
109 {
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);
112 }
113
114
115 ruint rvm_codegen_addlabelins_s(rvm_codegen_t *cg, const rchar* name, rvm_asmins_t ins)
116 {
117         return rvm_codegen_addlabelins(cg, name, r_strlen(name), ins);
118 }
119
120
121 ruint rvm_codegen_index_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, rulong index, rvm_asmins_t ins)
122 {
123         rvm_relocmap_add(cg->relocmap, type, rvm_codegen_getcodesize(cg), index);
124         return rvm_codegen_addins(cg, ins);
125 }
126
127
128 ruint rvm_codegen_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, ruint namesize, rvm_asmins_t ins)
129 {
130         return rvm_codegen_index_addrelocins(cg, type, rvm_codemap_lookup(cg->codemap, name, namesize), ins);
131 }
132
133
134 ruint rvm_codegen_addrelocins_s(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, rvm_asmins_t ins)
135 {
136         return rvm_codegen_addrelocins(cg, type, name, r_strlen(name), ins);
137 }
138
139
140 rint rvm_codegen_relocate(rvm_codegen_t *cg, rvm_codelabel_t **err)
141 {
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);
145 }
146
147
148 ruint rvm_codegen_insertins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins)
149 {
150         return r_array_insert(cg->code, index, &ins);
151 }
152
153
154 ruint rvm_codegen_replaceins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins)
155 {
156         return r_array_replace(cg->code, index, &ins);
157
158 }
159
160
161 ruint rvm_codegen_funcstart(rvm_codegen_t *cg, const rchar* name, ruint namesize, ruint args)
162 {
163         ruint start;
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);
169         return start;
170 }
171
172
173 ruint rvm_codegen_funcstart_s(rvm_codegen_t *cg, const rchar* name, ruint args)
174 {
175         return rvm_codegen_funcstart(cg, name, r_strlen(name), args);
176 }
177
178
179 ruint rvm_codegen_vargs_funcstart(rvm_codegen_t *cg, const rchar* name, ruint namesize)
180 {
181         ruint start;
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);
187         return start;
188 }
189
190
191 ruint rvm_codegen_vargs_funcstart_s(rvm_codegen_t *cg, const rchar* name)
192 {
193         return rvm_codegen_vargs_funcstart(cg, name, r_strlen(name));
194 }
195
196
197 void rvm_codegen_funcend(rvm_codegen_t *cg)
198 {
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));
202 }
203
204 rlong rvm_codegen_adddata(rvm_codegen_t *cg, const rchar *name, ruint namesize, rconstpointer data, rsize_t size)
205 {
206         rpointer buffer;
207         rulong cursize = R_SIZE_ALIGN(r_array_length(cg->data), sizeof(rword));
208
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);
214 }
215
216
217 rlong rvm_codegen_adddata_s(rvm_codegen_t *cg, const rchar *name, rconstpointer data, rsize_t size)
218 {
219         return rvm_codegen_adddata(cg, name, r_strlen(name), data, size);
220 }
221
222
223 rlong rvm_codegen_addstring(rvm_codegen_t *cg, const rchar *name, ruint namesize, const rchar* data)
224 {
225         return rvm_codegen_adddata(cg, name, namesize, data, r_strlen(data) + 1);
226 }
227
228
229 rlong rvm_codegen_addstring_s(rvm_codegen_t *cg, const rchar *name, const rchar* data)
230 {
231         return rvm_codegen_addstring(cg, name, r_strlen(name), data);
232 }
233
234
235 rlong rvm_codegen_add_numlabel_s(rvm_codegen_t *cg, const rchar *alphaname, rlong numname)
236 {
237         rchar label[128];
238
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);
242 }
243
244
245 rlong rvm_codegen_invalid_add_numlabel_s(rvm_codegen_t *cg, const rchar *alphaname, rlong numname)
246 {
247         rchar label[128];
248
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);
252 }
253