Mercurial > repos > blastem
comparison gen_arm.c @ 553:1af6c1052993
Added untested code for generating ARM machine code
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Sun, 23 Feb 2014 21:37:19 -0800 |
parents | |
children | 474270dbff15 |
comparison
equal
deleted
inserted
replaced
552:0687b05061dd | 553:1af6c1052993 |
---|---|
1 /* | |
2 Copyright 2014 Michael Pavone | |
3 This file is part of BlastEm. | |
4 BlastEm is free software distributed under the terms of the GNU General Public License version 3 or greater. See COPYING for full license text. | |
5 */ | |
6 #include "gen_arm.h" | |
7 #include "mem.h" | |
8 #include <stdio.h> | |
9 #include <stdlib.h> | |
10 | |
11 #define OP_FIELD_SHIFT 21u | |
12 | |
13 //Data processing format instructions | |
14 #define OP_AND 0x0u | |
15 #define OP_EOR (0x1u << OP_FIELD_SHIFT) | |
16 #define OP_SUB (0x2u << OP_FIELD_SHIFT) | |
17 #define OP_RSB (0x3u << OP_FIELD_SHIFT) | |
18 #define OP_ADD (0x4u << OP_FIELD_SHIFT) | |
19 #define OP_ADC (0x5u << OP_FIELD_SHIFT) | |
20 #define OP_SBC (0x6u << OP_FIELD_SHIFT) | |
21 #define OP_RSC (0x7u << OP_FIELD_SHIFT) | |
22 #define OP_TST (0x8u << OP_FIELD_SHIFT) | |
23 #define OP_TEQ (0x9u << OP_FIELD_SHIFT) | |
24 #define OP_CMP (0xAu << OP_FIELD_SHIFT) | |
25 #define OP_CMN (0xBu << OP_FIELD_SHIFT) | |
26 #define OP_ORR (0xCu << OP_FIELD_SHIFT) | |
27 #define OP_MOV (0xDu << OP_FIELD_SHIFT) | |
28 #define OP_BIC (0xEu << OP_FIELD_SHIFT) | |
29 #define OP_MVN (0xFu << OP_FIELD_SHIFT) | |
30 | |
31 //branch instructions | |
32 #define OP_B 0xA000000u | |
33 #define OP_BL 0xB000000u | |
34 #define OP_BX 0x12FFF10u | |
35 | |
36 //load/store | |
37 #define OP_STR 0x4000000u | |
38 #define OP_LDR 0x4100000u | |
39 #define OP_STM 0x8000000u | |
40 #define OP_LDM 0x8100000u | |
41 #define POST_IND 0u | |
42 #define PRE_IND 0x1000000u | |
43 #define DIR_DOWN 0u | |
44 #define DIR_UP 0x0800000u | |
45 #define SZ_W 0u | |
46 #define SZ_B 0x0400000u | |
47 #define WRITE_B 0x0200000u | |
48 #define OFF_IMM 0u | |
49 #define OFF_REG 0x2000000u | |
50 | |
51 #define PUSH (OP_STR | PRE_IND | OFF_IMM | SZ_W | WRITE_B | DIR_DOWN | sizeof(uint32_t) | (sp << 16)) | |
52 #define POP (OP_LDR | POST_IND | OFF_IMM | SZ_W | DIR_UP | sizeof(uint32_t) | (sp << 16)) | |
53 #define PUSHM (OP_STM | PRE_IND | SZ_W | WRITE_B | DIR_DOWN | (sp << 16)) | |
54 #define POPM (OP_LDM | POST_IND | SZ_W | DIR_UP | (sp << 16)) | |
55 | |
56 #define IMMED 0x2000000u | |
57 #define REG 0u | |
58 | |
59 | |
60 | |
61 #define RESERVE_INSTRUCTIONS 4 //1 ldr + 1bx + 1 constant | |
62 #define CODE_ALLOC_SIZE (1024*1024) | |
63 | |
64 uint32_t make_immed(uint32_t val) | |
65 { | |
66 uint32_t rot_amount = 0; | |
67 for (; rot_amount < 0x20; rot_amount += 2) | |
68 { | |
69 uint32_t test_mask = ~(0xFF << rot_amount | 0xFF >> (32-rot_amount)); | |
70 if (!(test_mask & val)) { | |
71 return val << rot_amount | val >> (32-rot_amount) | rot_amount << 7; | |
72 } | |
73 } | |
74 return INVALID_IMMED; | |
75 } | |
76 | |
77 void init_code_info(code_info *code) | |
78 { | |
79 size_t size = CODE_ALLOC_SIZE; | |
80 code->cur = alloc_code(&size); | |
81 if (!code->cur) { | |
82 fputs("Failed to allocate memory for generated code\n", stderr); | |
83 exit(1); | |
84 } | |
85 code->last = code->cur + size/sizeof(uint32_t) - RESERVE_INSTRUCTIONS; | |
86 } | |
87 | |
88 void check_alloc_code(code_info *code) | |
89 { | |
90 if (code->cur = code->last) { | |
91 size_t size = CODE_ALLOC_SIZE; | |
92 uint32_t *next_code = alloc_code(&size); | |
93 if (!next_code) { | |
94 fputs("Failed to allocate memory for generated code\n", stderr); | |
95 exit(1); | |
96 } | |
97 if (next_code = code->last + RESERVE_INSTRUCTIONS) { | |
98 //new chunk is contiguous with the current one | |
99 code->last = next_code + size/sizeof(uint32_t) - RESERVE_INSTRUCTIONS; | |
100 } else { | |
101 uint32_t * from = code->cur + 2; | |
102 if (next_code - from < 0x400000 || from - next_code <= 0x400000) { | |
103 *from = CC_AL | OP_B | ((next_code - from) & 0xFFFFFF); | |
104 } else { | |
105 //push r0 onto the stack | |
106 *(from++) = CC_AL | PUSH; | |
107 uint32_t immed = make_immed((uint32_t)next_code); | |
108 if (immed == INVALID_IMMED) { | |
109 //Load target into r0 from word after next instruction into register 0 | |
110 *(from++) = CC_AL | OP_LDR | OFF_IMM | DIR_DOWN | PRE_IND | SZ_W | (pc << 16) | 4; | |
111 from[1] = (uint32_t)next_code; | |
112 } else { | |
113 //Load target into r0 | |
114 *(from++) = CC_AL | OP_MOV | IMMED | NO_COND | immed; | |
115 } | |
116 //branch to address in r0 | |
117 *from = CC_AL | OP_BX; | |
118 code->last = next_code + size/sizeof(uint32_t) - RESERVE_INSTRUCTIONS; | |
119 //pop r0 | |
120 *(next_code++) = CC_AL | POP; | |
121 code->cur = next_code; | |
122 } | |
123 } | |
124 } | |
125 } | |
126 | |
127 uint32_t data_proc(code_info *code, uint32_t cond, uint32_t op, uint32_t set_cond, uint32_t dst, uint32_t src1, uint32_t src2) | |
128 { | |
129 check_alloc_code(code); | |
130 *(code->cur++) = cond | op | set_cond | (dst << 16) | (src1 << 12) | src2; | |
131 | |
132 return CODE_OK; | |
133 } | |
134 | |
135 uint32_t data_proci(code_info *code, uint32_t cond, uint32_t op, uint32_t set_cond, uint32_t dst, uint32_t src1, uint32_t immed) | |
136 { | |
137 immed = make_immed(immed); | |
138 if (immed = INVALID_IMMED) { | |
139 return immed; | |
140 } | |
141 return data_proc(code, cond, op, set_cond, dst, src1, immed); | |
142 } | |
143 | |
144 //TODO: support shifted register for op2 | |
145 | |
146 uint32_t and(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t set_cond) | |
147 { | |
148 return data_proc(code, CC_AL, OP_AND, set_cond, dst, src1, src2); | |
149 } | |
150 | |
151 uint32_t andi(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t set_cond) | |
152 { | |
153 return data_proci(code, CC_AL, OP_AND, set_cond, dst, src1, immed); | |
154 } | |
155 | |
156 uint32_t and_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t cc, uint32_t set_cond) | |
157 { | |
158 return data_proc(code, cc, OP_AND, set_cond, dst, src1, src2); | |
159 } | |
160 | |
161 uint32_t andi_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t cc, uint32_t set_cond) | |
162 { | |
163 return data_proci(code, cc, OP_AND, set_cond, dst, src1, immed); | |
164 } | |
165 | |
166 uint32_t eor(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t set_cond) | |
167 { | |
168 return data_proc(code, CC_AL, OP_EOR, set_cond, dst, src1, src2); | |
169 } | |
170 | |
171 uint32_t eori(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t set_cond) | |
172 { | |
173 return data_proci(code, CC_AL, OP_EOR, set_cond, dst, src1, immed); | |
174 } | |
175 | |
176 uint32_t eor_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t cc, uint32_t set_cond) | |
177 { | |
178 return data_proc(code, cc, OP_EOR, set_cond, dst, src1, src2); | |
179 } | |
180 | |
181 uint32_t eori_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t cc, uint32_t set_cond) | |
182 { | |
183 return data_proci(code, cc, OP_EOR, set_cond, dst, src1, immed); | |
184 } | |
185 | |
186 uint32_t sub(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t set_cond) | |
187 { | |
188 return data_proc(code, CC_AL, OP_SUB, set_cond, dst, src1, src2); | |
189 } | |
190 | |
191 uint32_t subi(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t set_cond) | |
192 { | |
193 return data_proci(code, CC_AL, OP_SUB, set_cond, dst, src1, immed); | |
194 } | |
195 | |
196 uint32_t sub_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t cc, uint32_t set_cond) | |
197 { | |
198 return data_proc(code, cc, OP_SUB, set_cond, dst, src1, src2); | |
199 } | |
200 | |
201 uint32_t subi_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t cc, uint32_t set_cond) | |
202 { | |
203 return data_proci(code, cc, OP_SUB, set_cond, dst, src1, immed); | |
204 } | |
205 | |
206 uint32_t rsb(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t set_cond) | |
207 { | |
208 return data_proc(code, CC_AL, OP_RSB, set_cond, dst, src1, src2); | |
209 } | |
210 | |
211 uint32_t rsbi(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t set_cond) | |
212 { | |
213 return data_proci(code, CC_AL, OP_RSB, set_cond, dst, src1, immed); | |
214 } | |
215 | |
216 uint32_t rsb_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t cc, uint32_t set_cond) | |
217 { | |
218 return data_proc(code, cc, OP_RSB, set_cond, dst, src1, src2); | |
219 } | |
220 | |
221 uint32_t rsbi_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t cc, uint32_t set_cond) | |
222 { | |
223 return data_proci(code, cc, OP_RSB, set_cond, dst, src1, immed); | |
224 } | |
225 | |
226 uint32_t add(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t set_cond) | |
227 { | |
228 return data_proc(code, CC_AL, OP_ADD, set_cond, dst, src1, src2); | |
229 } | |
230 | |
231 uint32_t addi(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t set_cond) | |
232 { | |
233 return data_proci(code, CC_AL, OP_ADD, set_cond, dst, src1, immed); | |
234 } | |
235 | |
236 uint32_t add_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t cc, uint32_t set_cond) | |
237 { | |
238 return data_proc(code, cc, OP_ADD, set_cond, dst, src1, src2); | |
239 } | |
240 | |
241 uint32_t addi_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t cc, uint32_t set_cond) | |
242 { | |
243 return data_proci(code, cc, OP_ADD, set_cond, dst, src1, immed); | |
244 } | |
245 | |
246 uint32_t adc(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t set_cond) | |
247 { | |
248 return data_proc(code, CC_AL, OP_ADC, set_cond, dst, src1, src2); | |
249 } | |
250 | |
251 uint32_t adci(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t set_cond) | |
252 { | |
253 return data_proci(code, CC_AL, OP_ADC, set_cond, dst, src1, immed); | |
254 } | |
255 | |
256 uint32_t adc_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t cc, uint32_t set_cond) | |
257 { | |
258 return data_proc(code, cc, OP_ADC, set_cond, dst, src1, src2); | |
259 } | |
260 | |
261 uint32_t adci_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t cc, uint32_t set_cond) | |
262 { | |
263 return data_proci(code, cc, OP_ADC, set_cond, dst, src1, immed); | |
264 } | |
265 | |
266 uint32_t sbc(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t set_cond) | |
267 { | |
268 return data_proc(code, CC_AL, OP_SBC, set_cond, dst, src1, src2); | |
269 } | |
270 | |
271 uint32_t sbci(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t set_cond) | |
272 { | |
273 return data_proci(code, CC_AL, OP_SBC, set_cond, dst, src1, immed); | |
274 } | |
275 | |
276 uint32_t sbc_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t cc, uint32_t set_cond) | |
277 { | |
278 return data_proc(code, cc, OP_SBC, set_cond, dst, src1, src2); | |
279 } | |
280 | |
281 uint32_t sbci_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t cc, uint32_t set_cond) | |
282 { | |
283 return data_proci(code, cc, OP_SBC, set_cond, dst, src1, immed); | |
284 } | |
285 | |
286 uint32_t rsc(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t set_cond) | |
287 { | |
288 return data_proc(code, CC_AL, OP_RSC, set_cond, dst, src1, src2); | |
289 } | |
290 | |
291 uint32_t rsci(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t set_cond) | |
292 { | |
293 return data_proci(code, CC_AL, OP_RSC, set_cond, dst, src1, immed); | |
294 } | |
295 | |
296 uint32_t rsc_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t cc, uint32_t set_cond) | |
297 { | |
298 return data_proc(code, cc, OP_RSC, set_cond, dst, src1, src2); | |
299 } | |
300 | |
301 uint32_t rsci_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t cc, uint32_t set_cond) | |
302 { | |
303 return data_proci(code, cc, OP_RSC, set_cond, dst, src1, immed); | |
304 } | |
305 | |
306 uint32_t tst(code_info *code, uint32_t src1, uint32_t src2) | |
307 { | |
308 return data_proc(code, CC_AL, OP_TST, SET_COND, r0, src1, src2); | |
309 } | |
310 | |
311 uint32_t tsti(code_info *code, uint32_t src1, uint32_t immed) | |
312 { | |
313 return data_proci(code, CC_AL, OP_TST, SET_COND, r0, src1, immed); | |
314 } | |
315 | |
316 uint32_t tst_cc(code_info *code, uint32_t src1, uint32_t src2, uint32_t cc) | |
317 { | |
318 return data_proc(code, cc, OP_TST, SET_COND, r0, src1, src2); | |
319 } | |
320 | |
321 uint32_t tsti_cc(code_info *code, uint32_t src1, uint32_t immed, uint32_t cc) | |
322 { | |
323 return data_proci(code, cc, OP_TST, SET_COND, r0, src1, immed); | |
324 } | |
325 | |
326 uint32_t teq(code_info *code, uint32_t src1, uint32_t src2) | |
327 { | |
328 return data_proc(code, CC_AL, OP_TEQ, SET_COND, r0, src1, src2); | |
329 } | |
330 | |
331 uint32_t teqi(code_info *code, uint32_t src1, uint32_t immed) | |
332 { | |
333 return data_proci(code, CC_AL, OP_TEQ, SET_COND, r0, src1, immed); | |
334 } | |
335 | |
336 uint32_t teq_cc(code_info *code, uint32_t src1, uint32_t src2, uint32_t cc) | |
337 { | |
338 return data_proc(code, cc, OP_TEQ, SET_COND, r0, src1, src2); | |
339 } | |
340 | |
341 uint32_t teqi_cc(code_info *code, uint32_t src1, uint32_t immed, uint32_t cc) | |
342 { | |
343 return data_proci(code, cc, OP_TEQ, SET_COND, r0, src1, immed); | |
344 } | |
345 | |
346 uint32_t cmp(code_info *code, uint32_t src1, uint32_t src2) | |
347 { | |
348 return data_proc(code, CC_AL, OP_CMP, SET_COND, r0, src1, src2); | |
349 } | |
350 | |
351 uint32_t cmpi(code_info *code, uint32_t src1, uint32_t immed) | |
352 { | |
353 return data_proci(code, CC_AL, OP_CMP, SET_COND, r0, src1, immed); | |
354 } | |
355 | |
356 uint32_t cmp_cc(code_info *code, uint32_t src1, uint32_t src2, uint32_t cc) | |
357 { | |
358 return data_proc(code, cc, OP_CMP, SET_COND, r0, src1, src2); | |
359 } | |
360 | |
361 uint32_t cmpi_cc(code_info *code, uint32_t src1, uint32_t immed, uint32_t cc) | |
362 { | |
363 return data_proci(code, cc, OP_CMP, SET_COND, r0, src1, immed); | |
364 } | |
365 | |
366 uint32_t cmn(code_info *code, uint32_t src1, uint32_t src2) | |
367 { | |
368 return data_proc(code, CC_AL, OP_CMN, SET_COND, r0, src1, src2); | |
369 } | |
370 | |
371 uint32_t cmni(code_info *code, uint32_t src1, uint32_t immed) | |
372 { | |
373 return data_proci(code, CC_AL, OP_CMN, SET_COND, r0, src1, immed); | |
374 } | |
375 | |
376 uint32_t cmn_cc(code_info *code, uint32_t src1, uint32_t src2, uint32_t cc) | |
377 { | |
378 return data_proc(code, cc, OP_CMN, SET_COND, r0, src1, src2); | |
379 } | |
380 | |
381 uint32_t cmni_cc(code_info *code, uint32_t src1, uint32_t immed, uint32_t cc) | |
382 { | |
383 return data_proci(code, cc, OP_CMN, SET_COND, r0, src1, immed); | |
384 } | |
385 | |
386 uint32_t orr(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t set_cond) | |
387 { | |
388 return data_proc(code, CC_AL, OP_ORR, set_cond, dst, src1, src2); | |
389 } | |
390 | |
391 uint32_t orri(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t set_cond) | |
392 { | |
393 return data_proci(code, CC_AL, OP_ORR, set_cond, dst, src1, immed); | |
394 } | |
395 | |
396 uint32_t orr_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t cc, uint32_t set_cond) | |
397 { | |
398 return data_proc(code, cc, OP_ORR, set_cond, dst, src1, src2); | |
399 } | |
400 | |
401 uint32_t orri_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t cc, uint32_t set_cond) | |
402 { | |
403 return data_proci(code, cc, OP_ORR, set_cond, dst, src1, immed); | |
404 } | |
405 | |
406 uint32_t mov(code_info *code, uint32_t dst, uint32_t src2, uint32_t set_cond) | |
407 { | |
408 return data_proc(code, CC_AL, OP_MOV, set_cond, dst, 0, src2); | |
409 } | |
410 | |
411 uint32_t movi(code_info *code, uint32_t dst, uint32_t immed, uint32_t set_cond) | |
412 { | |
413 return data_proci(code, CC_AL, OP_MOV, set_cond, dst, 0, immed); | |
414 } | |
415 | |
416 uint32_t mov_cc(code_info *code, uint32_t dst, uint32_t src2, uint32_t cc, uint32_t set_cond) | |
417 { | |
418 return data_proc(code, cc, OP_MOV, set_cond, dst, 0, src2); | |
419 } | |
420 | |
421 uint32_t movi_cc(code_info *code, uint32_t dst, uint32_t immed, uint32_t cc, uint32_t set_cond) | |
422 { | |
423 return data_proci(code, cc, OP_MOV, set_cond, dst, 0, immed); | |
424 } | |
425 | |
426 uint32_t bic(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t set_cond) | |
427 { | |
428 return data_proc(code, CC_AL, OP_BIC, set_cond, dst, src1, src2); | |
429 } | |
430 | |
431 uint32_t bici(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t set_cond) | |
432 { | |
433 return data_proci(code, CC_AL, OP_BIC, set_cond, dst, src1, immed); | |
434 } | |
435 | |
436 uint32_t bic_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t src2, uint32_t cc, uint32_t set_cond) | |
437 { | |
438 return data_proc(code, cc, OP_BIC, set_cond, dst, src1, src2); | |
439 } | |
440 | |
441 uint32_t bici_cc(code_info *code, uint32_t dst, uint32_t src1, uint32_t immed, uint32_t cc, uint32_t set_cond) | |
442 { | |
443 return data_proci(code, cc, OP_BIC, set_cond, dst, src1, immed); | |
444 } | |
445 | |
446 uint32_t mvn(code_info *code, uint32_t dst, uint32_t src2, uint32_t set_cond) | |
447 { | |
448 return data_proc(code, CC_AL, OP_MVN, set_cond, dst, 0, src2); | |
449 } | |
450 | |
451 uint32_t mvni(code_info *code, uint32_t dst, uint32_t immed, uint32_t set_cond) | |
452 { | |
453 return data_proci(code, CC_AL, OP_MVN, set_cond, dst, 0, immed); | |
454 } | |
455 | |
456 uint32_t mvn_cc(code_info *code, uint32_t dst, uint32_t src2, uint32_t cc, uint32_t set_cond) | |
457 { | |
458 return data_proc(code, cc, OP_MVN, set_cond, dst, 0, src2); | |
459 } | |
460 | |
461 uint32_t mvni_cc(code_info *code, uint32_t dst, uint32_t immed, uint32_t cc, uint32_t set_cond) | |
462 { | |
463 return data_proci(code, cc, OP_MVN, set_cond, dst, 0, immed); | |
464 } | |
465 | |
466 uint32_t branchi(code_info *code, uint32_t cc, uint32_t op, uint32_t *dst) | |
467 { | |
468 uint32_t * from = code->cur + 2; | |
469 if (dst - from >= 0x400000 && from - dst > 0x400000) { | |
470 return INVALID_IMMED; | |
471 } | |
472 check_alloc_code(code); | |
473 *(code->cur++) = cc | op | ((dst - from) & 0xFFFFFF); | |
474 return CODE_OK; | |
475 } | |
476 | |
477 uint32_t b(code_info *code, uint32_t *dst) | |
478 { | |
479 return branchi(code, CC_AL, OP_B, dst); | |
480 } | |
481 | |
482 uint32_t b_cc(code_info *code, uint32_t *dst, uint32_t cc) | |
483 { | |
484 return branchi(code, cc, OP_B, dst); | |
485 } | |
486 | |
487 uint32_t bl(code_info *code, uint32_t *dst) | |
488 { | |
489 return branchi(code, CC_AL, OP_BL, dst); | |
490 } | |
491 | |
492 uint32_t bl_cc(code_info *code, uint32_t *dst, uint32_t cc) | |
493 { | |
494 return branchi(code, cc, OP_BL, dst); | |
495 } | |
496 | |
497 uint32_t bx(code_info *code, uint32_t dst) | |
498 { | |
499 check_alloc_code(code); | |
500 *(code->cur++) = CC_AL | OP_BX | dst; | |
501 return CODE_OK; | |
502 } | |
503 | |
504 uint32_t bx_cc(code_info *code, uint32_t dst, uint32_t cc) | |
505 { | |
506 check_alloc_code(code); | |
507 *(code->cur++) = cc | OP_BX | dst; | |
508 return CODE_OK; | |
509 } | |
510 | |
511 uint32_t push(code_info *code, uint32_t reg) | |
512 { | |
513 check_alloc_code(code); | |
514 *(code->cur++) = CC_AL | PUSH | reg << 12; | |
515 return CODE_OK; | |
516 } | |
517 | |
518 uint32_t push_cc(code_info *code, uint32_t reg, uint32_t cc) | |
519 { | |
520 check_alloc_code(code); | |
521 *(code->cur++) = cc | PUSH | reg << 12; | |
522 return CODE_OK; | |
523 } | |
524 | |
525 uint32_t pushm(code_info *code, uint32_t reglist) | |
526 { | |
527 check_alloc_code(code); | |
528 *(code->cur++) = CC_AL | PUSHM | reglist; | |
529 return CODE_OK; | |
530 } | |
531 | |
532 uint32_t pushm_cc(code_info *code, uint32_t reglist, uint32_t cc) | |
533 { | |
534 check_alloc_code(code); | |
535 *(code->cur++) = cc | PUSHM | reglist; | |
536 return CODE_OK; | |
537 } | |
538 | |
539 uint32_t pop(code_info *code, uint32_t reg) | |
540 { | |
541 check_alloc_code(code); | |
542 *(code->cur++) = CC_AL | POP | reg << 12; | |
543 return CODE_OK; | |
544 } | |
545 | |
546 uint32_t pop_cc(code_info *code, uint32_t reg, uint32_t cc) | |
547 { | |
548 check_alloc_code(code); | |
549 *(code->cur++) = cc | POP | reg << 12; | |
550 return CODE_OK; | |
551 } | |
552 | |
553 uint32_t popm(code_info *code, uint32_t reglist) | |
554 { | |
555 check_alloc_code(code); | |
556 *(code->cur++) = CC_AL | POPM | reglist; | |
557 return CODE_OK; | |
558 } | |
559 | |
560 uint32_t popm_cc(code_info *code, uint32_t reglist, uint32_t cc) | |
561 { | |
562 check_alloc_code(code); | |
563 *(code->cur++) = cc | POPM | reglist; | |
564 return CODE_OK; | |
565 } |