RPA Toolkit
b0dcb1fe8a6deef28d2dadcfad7e1a1c602a312d
[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_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize)
75 {
76         return rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), RVM_CODE2BYTE_OFFSET(rvm_codegen_getcodesize(cg)));
77 }
78
79
80 rlong rvm_codegen_addlabel_s(rvm_codegen_t *cg, const rchar* name)
81 {
82         return rvm_codegen_addlabel(cg, name, r_strlen(name));
83 }
84
85
86 rlong rvm_codegen_invalid_addlabel(rvm_codegen_t *cg, const rchar* name, ruint namesize)
87 {
88         return rvm_codemap_invalid_add(cg->codemap, name, namesize);
89 }
90
91
92 rlong rvm_codegen_invalid_addlabel_s(rvm_codegen_t *cg, const rchar* name)
93 {
94         return rvm_codegen_invalid_addlabel(cg, name, r_strlen(name));
95 }
96
97
98 ruint rvm_codegen_addlabelins(rvm_codegen_t *cg, const rchar* name, ruint namesize, rvm_asmins_t ins)
99 {
100         rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), RVM_CODE2BYTE_OFFSET(rvm_codegen_getcodesize(cg)));
101         return rvm_codegen_addins(cg, ins);
102 }
103
104
105 ruint rvm_codegen_addlabelins_s(rvm_codegen_t *cg, const rchar* name, rvm_asmins_t ins)
106 {
107         return rvm_codegen_addlabelins(cg, name, r_strlen(name), ins);
108 }
109
110
111 ruint rvm_codegen_index_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, rulong index, rvm_asmins_t ins)
112 {
113         rvm_relocmap_add(cg->relocmap, type, rvm_codegen_getcodesize(cg), index);
114         return rvm_codegen_addins(cg, ins);
115 }
116
117
118 ruint rvm_codegen_addrelocins(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, ruint namesize, rvm_asmins_t ins)
119 {
120         return rvm_codegen_index_addrelocins(cg, type, rvm_codemap_lookup(cg->codemap, name, namesize), ins);
121 }
122
123
124 ruint rvm_codegen_addrelocins_s(rvm_codegen_t *cg, rvm_reloctype_t type, const rchar* name, rvm_asmins_t ins)
125 {
126         return rvm_codegen_addrelocins(cg, type, name, r_strlen(name), ins);
127 }
128
129
130 rint rvm_codegen_relocate(rvm_codegen_t *cg, rvm_codelabel_t **err)
131 {
132         rvm_codemap_addpointer_s(cg->codemap, ".code", r_array_slot(cg->code, 0));
133         rvm_codemap_addpointer_s(cg->codemap, ".data", r_array_slot(cg->data, 0));
134         return rvm_relocmap_relocate(cg->relocmap, cg->codemap, (rvm_asmins_t *)r_array_slot(cg->code, 0), err);
135 }
136
137
138 ruint rvm_codegen_insertins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins)
139 {
140         return r_array_insert(cg->code, index, &ins);
141 }
142
143
144 ruint rvm_codegen_replaceins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins)
145 {
146         return r_array_replace(cg->code, index, &ins);
147
148 }
149
150
151 ruint rvm_codegen_funcstart(rvm_codegen_t *cg, const rchar* name, ruint namesize, ruint args)
152 {
153         ruint start;
154         rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
155         start = rvm_codegen_addlabelins(cg, name, namesize, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
156         rvm_codegen_addins(cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
157         rvm_codegen_addins(cg, rvm_asm(RVM_ADD, SP, SP, DA, args));
158 //      rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), start);
159         return start;
160 }
161
162
163 ruint rvm_codegen_funcstart_s(rvm_codegen_t *cg, const rchar* name, ruint args)
164 {
165         return rvm_codegen_funcstart(cg, name, r_strlen(name), args);
166 }
167
168
169 ruint rvm_codegen_vargs_funcstart(rvm_codegen_t *cg, const rchar* name, ruint namesize)
170 {
171         ruint start;
172         rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
173         start = rvm_codegen_addlabelins(cg, name, namesize, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
174         rvm_codegen_addins(cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
175         rvm_codegen_addins(cg, rvm_asm(RVM_ADD, SP, SP, R0, 0));
176 //      rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".code"), start);
177         return start;
178 }
179
180
181 ruint rvm_codegen_vargs_funcstart_s(rvm_codegen_t *cg, const rchar* name)
182 {
183         return rvm_codegen_vargs_funcstart(cg, name, r_strlen(name));
184 }
185
186
187 void rvm_codegen_funcend(rvm_codegen_t *cg)
188 {
189         rvm_codegen_addins(cg, rvm_asm(RVM_MOV, SP, FP, XX, 0));
190         rvm_codegen_addins(cg, rvm_asm(RVM_POPM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
191         rvm_codegen_addins(cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
192 }
193
194 rlong rvm_codegen_adddata(rvm_codegen_t *cg, const rchar *name, ruint namesize, rconstpointer data, rsize_t size)
195 {
196         rpointer buffer;
197         rulong cursize = R_SIZE_ALIGN(r_array_length(cg->data), sizeof(rword));
198
199         r_array_setlength(cg->data, cursize + size + sizeof(rword));
200         buffer = r_array_slot(cg->data, cursize);
201         r_memset(buffer, 0, size + sizeof(rword));
202         r_memmove(buffer, data, size);
203         return rvm_codemap_addoffset(cg->codemap, name, namesize, rvm_codemap_lookup_s(cg->codemap, ".data"), cursize);
204 }
205
206
207 rlong rvm_codegen_adddata_s(rvm_codegen_t *cg, const rchar *name, rconstpointer data, rsize_t size)
208 {
209         return rvm_codegen_adddata(cg, name, r_strlen(name), data, size);
210 }
211
212
213 rlong rvm_codegen_addstring(rvm_codegen_t *cg, const rchar *name, ruint namesize, const rchar* data)
214 {
215         return rvm_codegen_adddata(cg, name, namesize, data, r_strlen(data) + 1);
216 }
217
218
219 rlong rvm_codegen_addstring_s(rvm_codegen_t *cg, const rchar *name, const rchar* data)
220 {
221         return rvm_codegen_addstring(cg, name, r_strlen(name), data);
222 }