2 * Regular Pattern Analyzer (RPA)
3 * Copyright (c) 2009-2010 Martin Stoilov
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 * Martin Stoilov <martin@rpasearch.com>
23 #include "rvm/rvmcpu.h"
24 #include "rvm/rvmcodemap.h"
25 #include "rlib/rmem.h"
26 #include "rlib/rstring.h"
27 #include "rvm/rvmreg.h"
28 #include "rlib/rmap.h"
30 #define RVM_DEFAULT_STACKSIZE (4 * 1024)
33 static void rvm_op_b(rvmcpu_t *cpu, rvm_asmins_t *ins)
37 // if (ins->op1 != XX)
38 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
39 // if (ins->op2 != XX)
40 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
41 // if (ins->op3 != XX)
42 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
43 pc += RVM_CPUREG_GETU(cpu, ins->op1);
44 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
48 static void rvm_op_beq(rvmcpu_t *cpu, rvm_asmins_t *ins)
52 if ((cpu->status & RVM_STATUS_Z)) {
53 // if (ins->op1 != XX)
54 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
55 // if (ins->op2 != XX)
56 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
57 // if (ins->op3 != XX)
58 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
59 pc += RVM_CPUREG_GETU(cpu, ins->op1);
60 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
65 static void rvm_op_bneq(rvmcpu_t *cpu, rvm_asmins_t *ins)
69 if ((cpu->status & RVM_STATUS_Z) == 0) {
70 // if (ins->op1 != XX)
71 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
72 // if (ins->op2 != XX)
73 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
74 // if (ins->op3 != XX)
75 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
76 pc += RVM_CPUREG_GETU(cpu, ins->op1);
77 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
82 static void rvm_op_bleq(rvmcpu_t *cpu, rvm_asmins_t *ins)
86 if ((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z)) {
87 // if (ins->op1 != XX)
88 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
89 // if (ins->op2 != XX)
90 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
91 // if (ins->op3 != XX)
92 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
93 pc += RVM_CPUREG_GETU(cpu, ins->op1);
94 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
98 static void rvm_op_bgeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
102 if ((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1) {
103 // if (ins->op1 != XX)
104 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
105 // if (ins->op2 != XX)
106 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
107 // if (ins->op3 != XX)
108 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
109 pc += RVM_CPUREG_GETU(cpu, ins->op1);
110 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
115 static void rvm_op_bles(rvmcpu_t *cpu, rvm_asmins_t *ins)
120 if ((cpu->status & RVM_STATUS_N)) {
121 // if (ins->op1 != XX)
122 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
123 // if (ins->op2 != XX)
124 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
125 // if (ins->op3 != XX)
126 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
127 pc += RVM_CPUREG_GETU(cpu, ins->op1);
128 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
133 static void rvm_op_bgre(rvmcpu_t *cpu, rvm_asmins_t *ins)
137 if ((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0) {
138 // if (ins->op1 != XX)
139 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
140 // if (ins->op2 != XX)
141 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
142 // if (ins->op3 != XX)
143 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
144 pc += RVM_CPUREG_GETU(cpu, ins->op1);
145 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
150 static void rvm_op_bx(rvmcpu_t *cpu, rvm_asmins_t *ins)
152 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
156 static void rvm_op_bxleq(rvmcpu_t *cpu, rvm_asmins_t *ins)
158 if ((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z)) {
159 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
164 static void rvm_op_bxgeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
166 if ((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1){
167 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
172 static void rvm_op_bxles(rvmcpu_t *cpu, rvm_asmins_t *ins)
174 if ((cpu->status & RVM_STATUS_N)) {
175 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
180 static void rvm_op_bxgre(rvmcpu_t *cpu, rvm_asmins_t *ins)
182 if ((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0) {
183 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
188 static void rvm_op_bxeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
190 if ((cpu->status & RVM_STATUS_Z)) {
191 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
196 static void rvm_op_bxneq(rvmcpu_t *cpu, rvm_asmins_t *ins)
198 if (!(cpu->status & RVM_STATUS_Z)) {
199 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
204 static void rvm_op_bxl(rvmcpu_t *cpu, rvm_asmins_t *ins)
206 RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
207 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
211 static void rvm_op_bl(rvmcpu_t *cpu, rvm_asmins_t *ins)
215 // if (ins->op1 != XX)
216 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
217 // if (ins->op2 != XX)
218 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
219 // if (ins->op3 != XX)
220 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
221 pc += RVM_CPUREG_GETU(cpu, ins->op1);
222 RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
223 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
227 static void rvm_op_exit(rvmcpu_t *cpu, rvm_asmins_t *ins)
233 static void rvm_op_mov(rvmcpu_t *cpu, rvm_asmins_t *ins)
235 RVM_CPUREG_SET(cpu, ins->op1, RVM_CPUREG_GET(cpu, ins->op2));
239 static void rvm_op_movs(rvmcpu_t *cpu, rvm_asmins_t *ins)
241 ruword op2 = RVM_CPUREG_GETU(cpu, ins->op2);;
243 RVM_CPUREG_SETU(cpu, ins->op1, op2);
244 RVM_STATUS_CLRALL(cpu);
245 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !op2);
246 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, op2 & RVM_SIGN_BIT);
250 static void rvm_op_swp(rvmcpu_t *cpu, rvm_asmins_t *ins)
252 rvmreg_t tmp = RVM_CPUREG_GET(cpu, ins->op1);
253 RVM_CPUREG_SET(cpu, ins->op1, RVM_CPUREG_GET(cpu, ins->op2));
254 RVM_CPUREG_SET(cpu, ins->op2, tmp);
258 static void rvm_op_ldr(rvmcpu_t *cpu, rvm_asmins_t *ins)
260 RVM_CPUREG_SETU(cpu, ins->op1, *((ruword*)RVM_CPUREG_GETU(cpu, ins->op2)));
265 static void rvm_op_ldrp(rvmcpu_t *cpu, rvm_asmins_t *ins)
267 RVM_CPUREG_SETU(cpu, ins->op1, *((rpointer*)RVM_CPUREG_GETU(cpu, ins->op2)));
271 static void rvm_op_ldrb(rvmcpu_t *cpu, rvm_asmins_t *ins)
273 RVM_CPUREG_SETU(cpu, ins->op1, *((ruint8*)RVM_CPUREG_GETU(cpu, ins->op2)));
277 static void rvm_op_ldrh(rvmcpu_t *cpu, rvm_asmins_t *ins)
279 RVM_CPUREG_SETU(cpu, ins->op1, *((ruint16*)RVM_CPUREG_GETU(cpu, ins->op2)));
283 static void rvm_op_ldrw(rvmcpu_t *cpu, rvm_asmins_t *ins)
285 RVM_CPUREG_SETU(cpu, ins->op1, *((ruint32*)RVM_CPUREG_GETU(cpu, ins->op2)));
289 static void rvm_op_ldrr(rvmcpu_t *cpu, rvm_asmins_t *ins)
291 RVM_CPUREG_SET(cpu, ins->op1, *((rvmreg_t*)RVM_CPUREG_GETU(cpu, ins->op2)));
295 static void rvm_op_clr(rvmcpu_t *cpu, rvm_asmins_t *ins)
297 RVM_REG_CLEAR(((rvmreg_t*)RVM_CPUREG_PTR(cpu, ins->op1)));
298 RVM_REG_SETTYPE(((rvmreg_t*)RVM_CPUREG_PTR(cpu, ins->op1)), RVM_DTYPE_UNDEF);
302 static void rvm_op_cflag(rvmcpu_t *cpu, rvm_asmins_t *ins)
304 ruword op1 = RVM_CPUREG_GETU(cpu, ins->op1);
305 RVM_STATUS_CLRBIT(cpu, op1);
309 static void rvm_op_clrr(rvmcpu_t *cpu, rvm_asmins_t *ins)
311 RVM_REG_CLEAR(((rvmreg_t*)RVM_CPUREG_GETP(cpu, ins->op1)));
312 RVM_REG_SETTYPE(((rvmreg_t*)RVM_CPUREG_GETP(cpu, ins->op1)), RVM_DTYPE_UNDEF);
316 static void rvm_op_str(rvmcpu_t *cpu, rvm_asmins_t *ins)
318 *((ruword*)RVM_CPUREG_GETP(cpu, ins->op2)) = RVM_CPUREG_GETU(cpu, ins->op1);
322 static void rvm_op_strp(rvmcpu_t *cpu, rvm_asmins_t *ins)
324 *((rpointer*)RVM_CPUREG_GETP(cpu, ins->op2)) = (rpointer)RVM_CPUREG_GETP(cpu, ins->op1);
328 static void rvm_op_strb(rvmcpu_t *cpu, rvm_asmins_t *ins)
330 *((ruint8*)RVM_CPUREG_GETP(cpu, ins->op2)) = (ruint8)RVM_CPUREG_GETU(cpu, ins->op1);
334 static void rvm_op_strh(rvmcpu_t *cpu, rvm_asmins_t *ins)
336 *((ruint16*)RVM_CPUREG_GETP(cpu, ins->op2)) = (ruint16)RVM_CPUREG_GETU(cpu, ins->op1);
341 static void rvm_op_strw(rvmcpu_t *cpu, rvm_asmins_t *ins)
343 *((ruint32*)RVM_CPUREG_GETP(cpu, ins->op2)) = (ruint32)RVM_CPUREG_GETU(cpu, ins->op1);
348 static void rvm_op_strr(rvmcpu_t *cpu, rvm_asmins_t *ins)
350 rvmreg_t *dest = RVM_CPUREG_PTR(cpu, ins->op2);
351 if (RVM_REG_GETTYPE(dest) != RVM_DTYPE_POINTER)
352 RVM_ABORT(cpu, RVM_E_LVALUE);
354 *((rvmreg_t*)RVM_REG_GETP(dest)) = RVM_CPUREG_GET(cpu, ins->op1);
358 static void rvm_op_adds(rvmcpu_t *cpu, rvm_asmins_t *ins)
360 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
363 RVM_CPUREG_SETU(cpu, ins->op1, res);
364 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, res < op2 || res < op3);
365 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
366 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
367 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op2 & RVM_SIGN_BIT) == (op3 & RVM_SIGN_BIT) &&
368 (res & RVM_SIGN_BIT) != (op2 & RVM_SIGN_BIT));
372 static void rvm_op_adc(rvmcpu_t *cpu, rvm_asmins_t *ins)
374 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
376 res = op2 + op3 + (RVM_STATUS_GETBIT(cpu, RVM_STATUS_C) ? 1 : 0);
377 RVM_CPUREG_SETU(cpu, ins->op1, res);
378 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, res < op2 || res < op3);
379 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
380 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
381 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op2 & RVM_SIGN_BIT) == (op3 & RVM_SIGN_BIT) &&
382 (res & RVM_SIGN_BIT) != (op2 & RVM_SIGN_BIT));
386 static void rvm_op_and(rvmcpu_t *cpu, rvm_asmins_t *ins)
388 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
391 RVM_CPUREG_SETU(cpu, ins->op1, res);
392 RVM_STATUS_CLRALL(cpu);
393 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
394 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
398 static void rvm_op_orr(rvmcpu_t *cpu, rvm_asmins_t *ins)
400 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
403 RVM_CPUREG_SETU(cpu, ins->op1, res);
404 RVM_STATUS_CLRALL(cpu);
405 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
406 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
410 static void rvm_op_lsl(rvmcpu_t *cpu, rvm_asmins_t *ins)
412 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
415 RVM_CPUREG_SETU(cpu, ins->op1, res);
416 RVM_STATUS_CLRALL(cpu);
417 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
418 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
422 static void rvm_op_lsr(rvmcpu_t *cpu, rvm_asmins_t *ins)
424 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
427 RVM_CPUREG_SETU(cpu, ins->op1, res);
428 RVM_STATUS_CLRALL(cpu);
429 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
433 static void rvm_op_lsrs(rvmcpu_t *cpu, rvm_asmins_t *ins)
435 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
437 res = ((rword)op2) >> op3;
438 RVM_CPUREG_SETU(cpu, ins->op1, res);
439 RVM_STATUS_CLRALL(cpu);
440 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
444 static void rvm_op_asr(rvmcpu_t *cpu, rvm_asmins_t *ins)
446 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
449 res |= op2 & RVM_SIGN_BIT;
450 RVM_CPUREG_SETU(cpu, ins->op1, res);
451 RVM_STATUS_CLRALL(cpu);
452 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
453 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
457 static void rvm_op_ror(rvmcpu_t *cpu, rvm_asmins_t *ins)
460 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
463 for (i = 0; i < op3; i++) {
471 RVM_CPUREG_SETU(cpu, ins->op1, res);
472 RVM_STATUS_CLRALL(cpu);
473 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
474 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
475 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, res & RVM_SIGN_BIT);
479 static void rvm_op_tst(rvmcpu_t *cpu, rvm_asmins_t *ins)
481 ruword res, op1 = RVM_CPUREG_GETU(cpu, ins->op1), op2 = RVM_CPUREG_GETU(cpu, ins->op2);
484 RVM_STATUS_CLRALL(cpu);
485 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
486 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
490 static void rvm_op_xor(rvmcpu_t *cpu, rvm_asmins_t *ins)
492 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
495 RVM_CPUREG_SETU(cpu, ins->op1, res);
496 RVM_STATUS_CLRALL(cpu);
497 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
498 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
502 static void rvm_op_not(rvmcpu_t *cpu, rvm_asmins_t *ins)
504 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2);
507 RVM_CPUREG_SETU(cpu, ins->op1, res);
508 RVM_STATUS_CLRALL(cpu);
509 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
510 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
514 static void rvm_op_teq(rvmcpu_t *cpu, rvm_asmins_t *ins)
516 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
519 RVM_STATUS_CLRALL(cpu);
520 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
521 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
525 static void rvm_op_bic(rvmcpu_t *cpu, rvm_asmins_t *ins)
527 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
530 RVM_CPUREG_SETU(cpu, ins->op1, res);
531 RVM_STATUS_CLRALL(cpu);
532 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
533 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
537 static void rvm_op_clz(rvmcpu_t *cpu, rvm_asmins_t *ins)
539 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2);
541 for (res = RVM_REGISTER_BITS; op2; ) {
545 RVM_CPUREG_SETU(cpu, ins->op1, res);
549 static void rvm_op_add(rvmcpu_t *cpu, rvm_asmins_t *ins)
551 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) + RVM_CPUREG_GETU(cpu, ins->op3));
555 static void rvm_op_inc(rvmcpu_t *cpu, rvm_asmins_t *ins)
557 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op1) + 1);
561 static void rvm_op_dec(rvmcpu_t *cpu, rvm_asmins_t *ins)
563 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op1) - 1);
567 static void rvm_op_swi(rvmcpu_t *cpu, rvm_asmins_t *ins)
570 rvm_switable_t *switable;
571 unsigned int ntable = (unsigned int) RVM_SWI_TABLE(ins->swi);
572 unsigned int nswi = (unsigned int) RVM_SWI_NUM(ins->swi);
574 if (r_harray_length(cpu->switables) <= ntable)
575 RVM_ABORT(cpu, RVM_E_SWITABLE);
576 switable = r_harray_index(cpu->switables, ntable, rvm_switable_t*);
577 swi = switable[nswi].op;
582 static void rvm_op_swiid(rvmcpu_t *cpu, rvm_asmins_t *ins)
585 rvm_switable_t *switable;
586 unsigned int ntable = (unsigned int) RVM_SWI_TABLE(RVM_CPUREG_GETU(cpu, ins->op1));
587 unsigned int nswi = (unsigned int) RVM_SWI_NUM(RVM_CPUREG_GETU(cpu, ins->op1));
589 if (r_harray_length(cpu->switables) <= ntable)
590 RVM_ABORT(cpu, RVM_E_SWITABLE);
591 switable = r_harray_index(cpu->switables, ntable, rvm_switable_t*);
592 swi = switable[nswi].op;
597 static void rvm_op_call(rvmcpu_t *cpu, rvm_asmins_t *ins)
599 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
601 if (RVM_REG_GETTYPE(arg1) == RVM_DTYPE_SWIID) {
602 RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
603 rvm_op_swiid(cpu, ins);
604 } else if (RVM_REG_GETTYPE(arg1) == RVM_DTYPE_FUNCTION) {
605 rvm_op_bxl(cpu, ins);
606 } else if (RVM_REG_GETTYPE(arg1) == RVM_DTYPE_OPHANDLER) {
607 ((rvmcpu_op)RVM_REG_GETP(arg1))(cpu, ins);
609 RVM_ABORT(cpu, RVM_E_NOTFUNCTION);
614 static void rvm_op_sub(rvmcpu_t *cpu, rvm_asmins_t *ins)
616 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) - RVM_CPUREG_GETU(cpu, ins->op3));
620 static void rvm_op_subs(rvmcpu_t *cpu, rvm_asmins_t *ins)
622 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
625 RVM_CPUREG_SETU(cpu, ins->op1, res);
626 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, !(res > op2)); /* borrow = !carry */
627 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
628 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
629 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op2 & RVM_SIGN_BIT) != (op3 & RVM_SIGN_BIT) &&
630 (res & RVM_SIGN_BIT) == (op2 & RVM_SIGN_BIT));
634 static void rvm_op_sbc(rvmcpu_t *cpu, rvm_asmins_t *ins)
636 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
638 res = op2 - op3 + (RVM_STATUS_GETBIT(cpu, RVM_STATUS_C) ? 0 : -1);
639 RVM_CPUREG_SETU(cpu, ins->op1, res);
640 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, !(res > op2)); /* borrow = !carry */
641 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
642 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
643 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op2 & RVM_SIGN_BIT) != (op3 & RVM_SIGN_BIT) &&
644 (res & RVM_SIGN_BIT) == (op2 & RVM_SIGN_BIT));
648 static void rvm_op_mul(rvmcpu_t *cpu, rvm_asmins_t *ins)
650 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) * RVM_CPUREG_GETU(cpu, ins->op3));
654 static void rvm_op_mls(rvmcpu_t *cpu, rvm_asmins_t *ins)
657 rword op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
659 res = (rword)(op2 * op3);
660 RVM_CPUREG_SETU(cpu, ins->op1, res);
661 /* TBD: Not sure how to update the RVM_STATUS_C */
662 RVM_STATUS_CLRALL(cpu);
663 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
664 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
668 static void rvm_op_muls(rvmcpu_t *cpu, rvm_asmins_t *ins)
670 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
673 RVM_CPUREG_SETU(cpu, ins->op1, res);
674 RVM_STATUS_CLRALL(cpu);
675 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, op2 && (res / op2) != op3);
676 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
677 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
681 static void rvm_op_div(rvmcpu_t *cpu, rvm_asmins_t *ins)
683 if (!RVM_CPUREG_GETU(cpu, ins->op3))
684 RVM_ABORT(cpu, RVM_E_DIVZERO);
686 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) / RVM_CPUREG_GETU(cpu, ins->op3));
690 static void rvm_op_divs(rvmcpu_t *cpu, rvm_asmins_t *ins)
692 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
695 RVM_ABORT(cpu, RVM_E_DIVZERO);
697 RVM_CPUREG_SETU(cpu, ins->op1, res);
698 RVM_STATUS_CLRALL(cpu);
699 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
700 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
704 static void rvm_op_mod(rvmcpu_t *cpu, rvm_asmins_t *ins)
706 if (!RVM_CPUREG_GETU(cpu, ins->op3))
707 RVM_ABORT(cpu, RVM_E_DIVZERO);
709 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) % RVM_CPUREG_GETU(cpu, ins->op3));
713 static void rvm_op_mods(rvmcpu_t *cpu, rvm_asmins_t *ins)
715 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
718 RVM_ABORT(cpu, RVM_E_DIVZERO);
720 r_printf("mod RES: %ld\n", res);
721 RVM_CPUREG_SETU(cpu, ins->op1, res);
722 RVM_STATUS_CLRALL(cpu);
723 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
724 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
728 static void rvm_op_dvs(rvmcpu_t *cpu, rvm_asmins_t *ins)
731 rword op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
734 RVM_ABORT(cpu, RVM_E_DIVZERO);
735 res = (rword)(op2 / op3);
736 RVM_CPUREG_SETU(cpu, ins->op1, res);
737 RVM_STATUS_CLRALL(cpu);
738 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
739 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
743 static void rvm_op_push(rvmcpu_t *cpu, rvm_asmins_t *ins)
745 ruword sp = RVM_CPUREG_GETU(cpu, SP) + 1;
747 if (!RVM_STACK_CHECKSIZE(cpu, cpu->stack, sp))
748 RVM_ABORT(cpu, RVM_E_NOMEM);
749 RVM_STACK_WRITE(cpu->stack, sp, &RVM_CPUREG_GET(cpu, ins->op1));
750 RVM_CPUREG_SETU(cpu, SP, sp);
754 static void rvm_op_lds(rvmcpu_t *cpu, rvm_asmins_t *ins)
756 ruword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
758 RVM_CPUREG_SET(cpu, ins->op1, RVM_STACK_READ(cpu->stack, sp));
762 static void rvm_op_sts(rvmcpu_t *cpu, rvm_asmins_t *ins)
764 ruword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
766 if (!RVM_STACK_CHECKSIZE(cpu, cpu->stack, sp))
767 RVM_ABORT(cpu, RVM_E_NOMEM);
768 RVM_STACK_WRITE(cpu->stack, sp, &RVM_CPUREG_GET(cpu, ins->op1));
772 static void rvm_op_pushm(rvmcpu_t *cpu, rvm_asmins_t *ins)
775 ruword bits = RVM_CPUREG_GETU(cpu, ins->op1);
776 ruword sp = RVM_CPUREG_GETU(cpu, SP);
778 if (!RVM_STACK_CHECKSIZE(cpu, cpu->stack, sp + RVM_REGS_NUM))
779 RVM_ABORT(cpu, RVM_E_NOMEM);
781 if (!(bits & ((1<<(RVM_REGS_NUM / 2)) - 1)))
782 i = RVM_REGS_NUM / 2;
783 for (;bits && i < RLST; i++) {
784 n = ((ruword)1) << i;
787 RVM_STACK_WRITE(cpu->stack, sp, &RVM_CPUREG_GET(cpu, i));
791 RVM_CPUREG_SETU(cpu, SP, sp);
795 static void rvm_op_popm(rvmcpu_t *cpu, rvm_asmins_t *ins)
798 ruword bits = RVM_CPUREG_GETU(cpu, ins->op1);
799 ruword savedbits = bits;
800 ruword sp = RVM_CPUREG_GETU(cpu, SP);
802 if (!(bits & ~((1 << (RVM_REGS_NUM / 2)) - 1)))
803 i = RVM_REGS_NUM / 2 - 1;
804 for (; bits && i >= 0; i--) {
807 RVM_CPUREG_SET(cpu, i, RVM_STACK_READ(cpu->stack, sp));
812 if (!(((ruword)(1 << SP)) & savedbits))
813 RVM_CPUREG_SETU(cpu, SP, sp);
817 static void rvm_op_pop(rvmcpu_t *cpu, rvm_asmins_t *ins)
819 ruword sp = RVM_CPUREG_GETU(cpu, SP);
821 RVM_CPUREG_SET(cpu, ins->op1, RVM_STACK_READ(cpu->stack, sp));
823 RVM_CPUREG_SETU(cpu, SP, sp - 1);
827 static void rvm_op_addrs(rvmcpu_t *cpu, rvm_asmins_t *ins)
829 ruword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
831 if (!RVM_STACK_CHECKSIZE(cpu, cpu->stack, sp))
832 RVM_ABORT(cpu, RVM_E_NOMEM);
834 RVM_CPUREG_CLEAR(cpu, ins->op1);
835 RVM_CPUREG_SETTYPE(cpu, ins->op1, RVM_DTYPE_POINTER);
836 RVM_CPUREG_SETP(cpu, ins->op1, RVM_STACK_ADDR(cpu->stack, sp));
840 static void rvm_op_stm(rvmcpu_t *cpu, rvm_asmins_t *ins)
843 ruword *dst = (ruword*) RVM_CPUREG_GETU(cpu, ins->op1);
844 ruword bits = RVM_CPUREG_GETU(cpu, ins->op2);
846 for (n = 0; bits && n < RLST; n++) {
847 if (((ruword)(1 << n)) & bits) {
848 *dst = RVM_CPUREG_GETU(cpu, n);
856 static void rvm_op_ldm(rvmcpu_t *cpu, rvm_asmins_t *ins)
859 ruword *src = (ruword*)RVM_CPUREG_GETU(cpu, ins->op1);
860 ruword bits = RVM_CPUREG_GETU(cpu, ins->op2);
862 for (n = 0; bits && n < RLST; n++) {
863 if (((ruword)(1 << n)) & bits) {
864 RVM_CPUREG_CLEAR(cpu, n);
865 RVM_CPUREG_SETU(cpu, n, *src);
873 static void rvm_op_cmp(rvmcpu_t *cpu, rvm_asmins_t *ins)
875 ruword op1 = RVM_CPUREG_GETU(cpu, ins->op1), op2 = RVM_CPUREG_GETU(cpu, ins->op2);
876 ruword res = (ruword)(op1 - op2);
878 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, op1 < op2);
879 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
880 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
881 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op1 & RVM_SIGN_BIT) != (op2 & RVM_SIGN_BIT) &&
882 (res & RVM_SIGN_BIT) == (op1 & RVM_SIGN_BIT));
886 static void rvm_op_cmn(rvmcpu_t *cpu, rvm_asmins_t *ins)
888 ruword op1 = RVM_CPUREG_GETU(cpu, ins->op1), op2 = RVM_CPUREG_GETU(cpu, ins->op2);
889 ruword res = (ruword)(op1 + op2);
891 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, res < op1 || res < op2);
892 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
893 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
894 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op1 & RVM_SIGN_BIT) == (op2 & RVM_SIGN_BIT) &&
895 (res & RVM_SIGN_BIT) != (op1 & RVM_SIGN_BIT));
900 static void rvm_op_nop(rvmcpu_t *cpu, rvm_asmins_t *ins)
902 // fprintf(stdout, "nop\n");
906 static void rvm_op_ret(rvmcpu_t *cpu, rvm_asmins_t *ins)
908 RVM_CPUREG_SETU(cpu, PC, RVM_CPUREG_GETU(cpu, LR));
912 static int rvm_vsnprintf(char *str, unsigned int size, const char *format, va_list ap)
914 return vsnprintf(str, size, format, ap);
918 static int rvm_snprintf(char *str, unsigned int size, const char *format, ...)
923 va_start(ap, format);
924 ret = rvm_vsnprintf(str, size, format, ap);
930 static int rvm_printf(const char *format, ...)
935 va_start(ap, format);
936 ret = vfprintf(stdout, format, ap);
942 int rvm_asm_dump_reg_to_str(unsigned int reg, char *str, unsigned int size)
947 ret = rvm_snprintf(str, size, "XX ");
949 ret = rvm_snprintf(str, size, "IP ");
951 ret = rvm_snprintf(str, size, "TP ");
953 ret = rvm_snprintf(str, size, "FP ");
955 ret = rvm_snprintf(str, size, "SP ");
957 ret = rvm_snprintf(str, size, "LR ");
959 ret = rvm_snprintf(str, size, "PC ");
961 ret = rvm_snprintf(str, size, "DA ");
963 ret = rvm_snprintf(str, size, "R%d ", reg);
969 static void rvm_op_prn(rvmcpu_t *cpu, rvm_asmins_t *ins)
971 rvmreg_t *r = RVM_CPUREG_PTR(cpu, ins->op1);
973 if (rvm_reg_gettype(r) == RVM_DTYPE_UNSIGNED)
974 rvm_printf("(UNSIGNED) R%d = %lu(0x%lx)\n", ins->op1, RVM_REG_GETU(r), RVM_REG_GETU(r));
975 else if (rvm_reg_gettype(r) == RVM_DTYPE_BOOLEAN)
976 rvm_printf("(UNSIGNED) R%d = %lu(0x%lx)\n", ins->op1, RVM_REG_GETU(r), RVM_REG_GETU(r));
977 else if (rvm_reg_gettype(r) == RVM_DTYPE_POINTER)
978 rvm_printf("(POINTER) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
979 else if (rvm_reg_gettype(r) == RVM_DTYPE_SIGNED)
980 rvm_printf("(LONG) R%d = %ld\n", ins->op1, RVM_REG_GETL(r));
981 else if (rvm_reg_gettype(r) == RVM_DTYPE_DOUBLE)
982 rvm_printf("(DOUBLE) R%d = %0.2f\n", ins->op1, RVM_REG_GETD(r));
983 else if (rvm_reg_gettype(r) == RVM_DTYPE_STRING)
984 rvm_printf("(STRING) R%d = %s\n", ins->op1, ((rstring_t*) RVM_REG_GETP(r))->s.str);
985 else if (rvm_reg_gettype(r) == RVM_DTYPE_ARRAY)
986 rvm_printf("(ARRAY) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
987 else if (rvm_reg_gettype(r) == RVM_DTYPE_MAP)
988 rvm_printf("(Object) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
989 else if (rvm_reg_gettype(r) == RVM_DTYPE_SWIID)
990 rvm_printf("(SWI) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
991 else if (rvm_reg_gettype(r) == RVM_DTYPE_FUNCTION)
992 rvm_printf("(FUNCTION) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
994 rvm_printf("(UNKNOWN) R%d = ?\n", ins->op1);
998 int rvm_asm_dump_pi_to_str(rvmcpu_t *vm, rvm_asmins_t *pi, char *str, unsigned int size)
1000 int ret = 0, sz = size;
1002 if (pi->opcode == RVM_SWI) {
1004 r_memset(szSwi, 0, sizeof(szSwi));
1006 rvm_snprintf(szSwi, sizeof(szSwi) - 1, "OPCODE(%d)", pi->opcode);
1008 rvm_switable_t *switable;
1009 unsigned int ntable = (unsigned int) RVM_SWI_TABLE(pi->swi);
1010 unsigned int nswi = (unsigned int) RVM_SWI_NUM(pi->swi);
1012 if (ntable < r_harray_length(vm->switables)) {
1013 switable = r_harray_index(vm->switables, ntable, rvm_switable_t*);
1014 rvm_snprintf(szSwi, sizeof(szSwi) - 1, "(%s)", switable[nswi].name ? switable[nswi].name : "unknown");
1017 if ((ret = rvm_snprintf(str, sz, "%16s ", szSwi)) < 0)
1020 if ((ret = rvm_snprintf(str, sz, "%16s ", vm->ops[pi->opcode].name)) < 0)
1026 if ((ret = rvm_asm_dump_reg_to_str(pi->op1, str, sz)) < 0)
1031 if ((ret = rvm_snprintf(str, sz, " ")) < 0)
1036 if ((ret = rvm_asm_dump_reg_to_str(pi->op2, str, sz)) < 0)
1041 if ((ret = rvm_snprintf(str, sz, " ")) < 0)
1046 if ((ret = rvm_asm_dump_reg_to_str(pi->op3, str, sz)) < 0)
1051 if ((ret = rvm_snprintf(str, sz, " ")) < 0)
1057 if (RVM_REG_GETTYPE(&pi->data) == RVM_DTYPE_DOUBLE) {
1058 if ((ret = rvm_snprintf(str, sz, "%f ", RVM_REG_GETD(&pi->data))) < 0)
1060 } else if (RVM_REG_GETTYPE(&pi->data) == RVM_DTYPE_SIGNED) {
1061 if ((ret = rvm_snprintf(str, sz, "%ld ", RVM_REG_GETL(&pi->data))) < 0)
1064 if ((ret = rvm_snprintf(str, sz, "0x%lx ", (unsigned long)RVM_REG_GETU(&pi->data))) < 0)
1075 void rvm_asm_dump(rvmcpu_t *cpu, rvm_asmins_t *pi, unsigned int count)
1079 rvm_asm_dump_pi_to_str(cpu, pi, buffer, sizeof(buffer));
1080 rvm_printf("%s\n", buffer);
1087 void rvm_cpu_dumpregs(rvmcpu_t *vm, rvm_asmins_t *pi)
1092 ret = rvm_asm_dump_pi_to_str(vm, pi, buffer, sizeof(buffer));
1095 ret = rvm_snprintf(buffer + ret, sizeof(buffer) - ret, " ");
1097 rvm_printf("%s", buffer);
1099 rvm_printf("0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, TP=%p, FP=%ld, SP=%ld, LR=0x%lx, PC=0x%lx, DA=0x%lx, S( %c%c%c%c%c )",
1100 RVM_CPUREG_GETU(vm, 0), RVM_CPUREG_GETU(vm, 1), RVM_CPUREG_GETU(vm, 2), RVM_CPUREG_GETU(vm, 3),
1101 RVM_CPUREG_GETU(vm, 4), RVM_CPUREG_GETU(vm, 5), RVM_CPUREG_GETU(vm, 6), RVM_CPUREG_GETU(vm, 7),
1102 RVM_CPUREG_GETU(vm, 8), RVM_CPUREG_GETP(vm, TP), (long int)RVM_CPUREG_GETU(vm, FP), (long int)RVM_CPUREG_GETU(vm, SP),
1103 (long int)RVM_CPUREG_GETU(vm, LR), (long int)RVM_CPUREG_GETU(vm, PC), RVM_CPUREG_GETU(vm, DA),
1104 vm->status & RVM_STATUS_E ? 'E' : '_',
1105 vm->status & RVM_STATUS_V ? 'V' : '_',
1106 vm->status & RVM_STATUS_C ? 'C' : '_',
1107 vm->status & RVM_STATUS_N ? 'N' : '_',
1108 vm->status & RVM_STATUS_Z ? 'Z' : '_');
1113 static void rvm_op_type(rvmcpu_t *cpu, rvm_asmins_t *ins)
1115 rvmreg_type_t type = (rvmreg_type_t)RVM_CPUREG_GETTYPE(cpu, ins->op2);
1117 RVM_CPUREG_SETU(cpu, ins->op1, type);
1118 RVM_CPUREG_SETTYPE(cpu, ins->op1, RVM_DTYPE_UNSIGNED);
1122 static void rvm_op_settype(rvmcpu_t *cpu, rvm_asmins_t *ins)
1124 rvmreg_type_t type = (rvmreg_type_t)RVM_CPUREG_GETU(cpu, ins->op2);
1126 RVM_CPUREG_SETTYPE(cpu, ins->op1, type);
1130 static void rvm_op_abort(rvmcpu_t *cpu, rvm_asmins_t *ins)
1132 RVM_ABORT(cpu, RVM_CPUREG_GETU(cpu, ins->op1));
1136 static rvmcpu_op ops[] = {
1137 rvm_op_exit, // RVM_EXT
1138 rvm_op_abort, // RVM_ABORT
1139 rvm_op_prn, // RVM_PRN
1140 rvm_op_asr, // RVM_ASR
1141 rvm_op_swi, // RVM_SWI
1142 rvm_op_swiid, // RVM_SWIID
1143 rvm_op_call, // RVM_CALL
1144 rvm_op_mov, // RVM_MOV
1145 rvm_op_movs, // RVM_MOVS
1146 rvm_op_swp, // RVM_SWP
1147 rvm_op_inc, // RVM_INC
1148 rvm_op_dec, // RVM_DEC
1149 rvm_op_add, // RVM_ADD
1150 rvm_op_adds, // RVM_ADDS
1151 rvm_op_adc, // RVM_ADC
1152 rvm_op_and, // RVM_AND
1153 rvm_op_bic, // RVM_BIC
1154 rvm_op_clz, // RVM_CLZ
1155 rvm_op_cmn, // RVM_CMN
1156 rvm_op_xor, // RVM_XOR
1157 rvm_op_sub, // RVM_SUB
1158 rvm_op_subs, // RVM_SUBS
1159 rvm_op_sbc, // RVM_SBC
1160 rvm_op_mul, // RVM_MUL
1161 rvm_op_mls, // RVM_MLS
1162 rvm_op_muls, // RVM_MULS
1163 rvm_op_not, // RVM_NOT
1164 rvm_op_div, // RVM_DIV
1165 rvm_op_dvs, // RVM_DVS
1166 rvm_op_divs, // RVM_DIVS
1167 rvm_op_mod, // RVM_MOD
1168 rvm_op_mods, // RVM_MODS
1169 rvm_op_bx, // RVM_BX
1170 rvm_op_bxeq, // RVM_BXEQ
1171 rvm_op_bxneq, // RVM_BXNEQ
1172 rvm_op_bxleq, // RVM_BXLEQ
1173 rvm_op_bxgeq, // RVM_BXGEQ
1174 rvm_op_bxles, // RVM_BXLES
1175 rvm_op_bxgre, // RVM_BXGRE
1176 rvm_op_bxl, // RVM_BXL
1177 rvm_op_bl, // RVM_BL
1179 rvm_op_str, // RVM_STR
1180 rvm_op_strp, // RVM_STRP
1181 rvm_op_strb, // RVM_STRB
1182 rvm_op_strh, // RVM_STRH
1183 rvm_op_strw, // RVM_STRW
1184 rvm_op_strr, // RVM_STRR
1185 rvm_op_ldr, // RVM_LDR
1186 rvm_op_ldrp, // RVM_LDRP
1187 rvm_op_ldrb, // RVM_LDRB
1188 rvm_op_ldrh, // RVM_LDRH
1189 rvm_op_ldrw, // RVM_LDRW
1190 rvm_op_ldrr, // RVM_LDRR
1191 rvm_op_cflag, // RVM_CFLAG
1192 rvm_op_clr, // RVM_CLR
1193 rvm_op_clrr, // RVM_CLRR
1194 rvm_op_lsl, // RVM_LSL
1195 rvm_op_lsr, // RVM_LSR
1196 rvm_op_lsrs, // RVM_LSRS
1197 rvm_op_stm, // RVM_STM
1198 rvm_op_ldm, // RVM_LDM
1199 rvm_op_sts, // RVM_STS
1200 rvm_op_lds, // RVM_LDS
1201 rvm_op_orr, // RVM_ORR
1202 rvm_op_push, // RVM_PUSH
1203 rvm_op_pop, // RVM_POP
1204 rvm_op_cmp, // RVM_CMP
1205 rvm_op_nop, // RVM_NOP
1206 rvm_op_beq, // RVM_BEQ
1207 rvm_op_bneq, // RVM_BNEQ
1208 rvm_op_bleq, // RVM_BLEQ
1209 rvm_op_bgeq, // RVM_BGEQ
1210 rvm_op_bles, // RVM_BLES
1211 rvm_op_bgre, // RVM_BGRE
1212 rvm_op_ret, // RVM_RET
1213 rvm_op_ror, // RVM_ROR
1214 rvm_op_pushm, // RVM_PUSHM
1215 rvm_op_popm, // RVM_POPM
1216 rvm_op_tst, // RVM_TST
1217 rvm_op_teq, // RVM_TEQ
1218 rvm_op_addrs, // RVM_ADDRS
1220 /* Extended VM instructions */
1221 rvm_op_cast, // RVM_CAST
1222 rvm_op_type, // RVM_TYPE
1223 rvm_op_settype, // RVM_SETTYPE
1224 rvm_op_emov, // RVM_EMOV
1225 rvm_op_eneg, // RVM_ENEG
1226 rvm_op_eadd, // RVM_EADD
1227 rvm_op_esub, // RVM_ESUB
1228 rvm_op_emul, // RVM_EMUL
1229 rvm_op_ediv, // RVM_EDIV
1230 rvm_op_emod, // RVM_MOD
1231 rvm_op_elsl, // RVM_ELSL
1232 rvm_op_elsr, // RVM_ELSR
1233 rvm_op_elsru, // RVM_ELSRU
1234 rvm_op_eand, // RVM_EAND
1235 rvm_op_eorr, // RVM_EORR
1236 rvm_op_exor, // RVM_EXOR
1237 rvm_op_enot, // RVM_ENOT
1239 rvm_op_eland, // RVM_ELAND
1240 rvm_op_elor, // RVM_ELOR
1241 rvm_op_elnot, // RVM_ELNOT
1242 rvm_op_eeq, // RVM_EEQ
1243 rvm_op_enoteq, // RVM_ENOTEQ
1244 rvm_op_egreat, // RVM_EGREAT
1245 rvm_op_egreateq, // RVM_EGREATEQ
1246 rvm_op_eless, // RVM_ELESS
1247 rvm_op_elesseq, // RVM_ELESSEQ
1248 rvm_op_ecmp, // RVM_ECMP
1249 rvm_op_ecmn, // RVM_ECMN
1251 rvm_op_proplookup, // RVM_PROPLKUP
1252 rvm_op_proplookupadd, //RVM_PROPLKUPADD
1253 rvm_op_propldr, // RVM_PROPLDR
1254 rvm_op_propstr, // RVM_PROPSTR,
1255 rvm_op_propaddr, // RVM_PROPADDR
1256 rvm_op_propkeyldr, // RVM_PROPKEYLDR
1257 rvm_op_propdel, // RVM_PROPDEL
1258 rvm_op_propnext, // RVM_PROPNEXT
1259 rvm_op_propprev, // RVM_PROPPREV
1262 rvm_op_stralloc, // RVM_STRALLOC
1263 rvm_op_arralloc, // RVM_ARRALLOC
1264 rvm_op_addra, // RVM_ADDRA
1265 rvm_op_lda, // RVM_LDA
1266 rvm_op_sta, // RVM_STA
1267 rvm_op_mapalloc, // RVM_MAPALLOC
1268 rvm_op_mapaddr, // RVM_MAPADDR,
1269 rvm_op_mapkeyldr, // RVM_MAPKEYLDR,
1270 rvm_op_mapldr, // RVM_MAPLDR,
1271 rvm_op_mapstr, // RVM_MAPSTR,
1272 rvm_op_mapdel, // RVM_MAPDEL,
1273 rvm_op_maplookup, // RVM_MAPLKUP,
1274 rvm_op_mapadd, // RVM_MAPADD,
1275 rvm_op_maplookupadd,// RVM_MAPLKUPADD,
1276 rvm_op_mapnext, // RVM_MAPNEXT,
1277 rvm_op_mapprev, // RVM_MAPPREV,
1291 int rvm_cpu_setophandler(rvmcpu_t *cpu, unsigned int opcode, const char *opname, rvmcpu_op op)
1293 if (opcode >= RVM_COUNT)
1295 cpu->ops[opcode].name = opname;
1296 cpu->ops[opcode].op = op;
1301 rvmcpu_t *rvm_cpu_create(unsigned long stacksize)
1305 cpu = (rvmcpu_t *)r_malloc(sizeof(*cpu));
1308 r_memset(cpu, 0, sizeof(*cpu));
1309 cpu->stacksize = stacksize;
1310 cpu->switables = r_harray_create(sizeof(rvm_switable_t*));
1311 cpu->stack = r_malloc(stacksize * sizeof(rvmreg_t));
1312 cpu->data = r_carray_create(sizeof(rvmreg_t));
1313 cpu->gc = r_gc_create();
1315 rvm_cpu_setophandler(cpu, RVM_EXT, "EXT", rvm_op_exit);
1316 rvm_cpu_setophandler(cpu, RVM_ABORT, "ABORT", rvm_op_abort);
1317 rvm_cpu_setophandler(cpu, RVM_PRN, "PRN", rvm_op_prn);
1318 rvm_cpu_setophandler(cpu, RVM_ASR, "ASR", rvm_op_asr);
1319 rvm_cpu_setophandler(cpu, RVM_SWI, "SWI", rvm_op_swi);
1320 rvm_cpu_setophandler(cpu, RVM_SWIID, "SWIID", rvm_op_swiid);
1321 rvm_cpu_setophandler(cpu, RVM_CALL, "CALL", rvm_op_call);
1322 rvm_cpu_setophandler(cpu, RVM_MOV, "MOV", rvm_op_mov);
1323 rvm_cpu_setophandler(cpu, RVM_MOVS, "MOVS", rvm_op_movs);
1324 rvm_cpu_setophandler(cpu, RVM_SWP, "SWP", rvm_op_swp);
1325 rvm_cpu_setophandler(cpu, RVM_INC, "INC", rvm_op_inc);
1326 rvm_cpu_setophandler(cpu, RVM_DEC, "DEC", rvm_op_dec);
1327 rvm_cpu_setophandler(cpu, RVM_ADD, "ADD", rvm_op_add);
1328 rvm_cpu_setophandler(cpu, RVM_ADDS, "ADDS", rvm_op_adds);
1329 rvm_cpu_setophandler(cpu, RVM_ADC, "ADC", rvm_op_adc);
1330 rvm_cpu_setophandler(cpu, RVM_AND, "AND", rvm_op_and);
1331 rvm_cpu_setophandler(cpu, RVM_BIC, "BIC", rvm_op_bic);
1332 rvm_cpu_setophandler(cpu, RVM_CLZ, "CLZ", rvm_op_clz);
1333 rvm_cpu_setophandler(cpu, RVM_CMN, "CMN", rvm_op_cmn);
1334 rvm_cpu_setophandler(cpu, RVM_XOR, "XOR", rvm_op_xor);
1335 rvm_cpu_setophandler(cpu, RVM_SUB, "SUB", rvm_op_sub);
1336 rvm_cpu_setophandler(cpu, RVM_SUBS, "SUBS", rvm_op_subs);
1337 rvm_cpu_setophandler(cpu, RVM_SBC, "SBC", rvm_op_sbc);
1338 rvm_cpu_setophandler(cpu, RVM_MUL, "MUL", rvm_op_mul);
1339 rvm_cpu_setophandler(cpu, RVM_MLS, "MLS", rvm_op_mls);
1340 rvm_cpu_setophandler(cpu, RVM_MULS, "MULS", rvm_op_muls);
1341 rvm_cpu_setophandler(cpu, RVM_NOT, "NOT", rvm_op_not);
1342 rvm_cpu_setophandler(cpu, RVM_DIV, "DIV", rvm_op_div);
1343 rvm_cpu_setophandler(cpu, RVM_DVS, "DVS", rvm_op_dvs);
1344 rvm_cpu_setophandler(cpu, RVM_DIVS, "DIVS", rvm_op_divs);
1345 rvm_cpu_setophandler(cpu, RVM_MOD, "MOD", rvm_op_mod);
1346 rvm_cpu_setophandler(cpu, RVM_MODS, "MODS", rvm_op_mods);
1347 rvm_cpu_setophandler(cpu, RVM_BX, "BX", rvm_op_bx);
1348 rvm_cpu_setophandler(cpu, RVM_BXEQ, "BXEQ", rvm_op_bxeq);
1349 rvm_cpu_setophandler(cpu, RVM_BXNEQ, "BXNEQ", rvm_op_bxneq);
1350 rvm_cpu_setophandler(cpu, RVM_BXLEQ, "BXLEQ", rvm_op_bxleq);
1351 rvm_cpu_setophandler(cpu, RVM_BXGEQ, "BXGEQ", rvm_op_bxgeq);
1352 rvm_cpu_setophandler(cpu, RVM_BXLES, "BXLES", rvm_op_bxles);
1353 rvm_cpu_setophandler(cpu, RVM_BXGRE, "BXGRE", rvm_op_bxgre);
1354 rvm_cpu_setophandler(cpu, RVM_BXL, "BXL", rvm_op_bxl);
1355 rvm_cpu_setophandler(cpu, RVM_BL, "BL", rvm_op_bl);
1356 rvm_cpu_setophandler(cpu, RVM_B, "B", rvm_op_b);
1357 rvm_cpu_setophandler(cpu, RVM_STR, "STR", rvm_op_str);
1358 rvm_cpu_setophandler(cpu, RVM_STRP, "STRP", rvm_op_strp);
1359 rvm_cpu_setophandler(cpu, RVM_STRB, "STRB", rvm_op_strb);
1360 rvm_cpu_setophandler(cpu, RVM_STRH, "STRH", rvm_op_strh);
1361 rvm_cpu_setophandler(cpu, RVM_STRW, "STRW", rvm_op_strw);
1362 rvm_cpu_setophandler(cpu, RVM_STRR, "STRR", rvm_op_strr);
1363 rvm_cpu_setophandler(cpu, RVM_LDR, "LDR", rvm_op_ldr);
1364 rvm_cpu_setophandler(cpu, RVM_LDRP, "LDRP", rvm_op_ldrp);
1365 rvm_cpu_setophandler(cpu, RVM_LDRB, "LDRB", rvm_op_ldrb);
1366 rvm_cpu_setophandler(cpu, RVM_LDRH, "LDRH", rvm_op_ldrh);
1367 rvm_cpu_setophandler(cpu, RVM_LDRW, "LDRW", rvm_op_ldrw);
1368 rvm_cpu_setophandler(cpu, RVM_LDRR, "LDRR", rvm_op_ldrr);
1369 rvm_cpu_setophandler(cpu, RVM_CFLAG, "CFLAG", rvm_op_cflag);
1370 rvm_cpu_setophandler(cpu, RVM_CLR, "CLR", rvm_op_clr);
1371 rvm_cpu_setophandler(cpu, RVM_CLRR, "CLRR", rvm_op_clrr);
1372 rvm_cpu_setophandler(cpu, RVM_LSL, "LSL", rvm_op_lsl);
1373 rvm_cpu_setophandler(cpu, RVM_LSR, "LSR", rvm_op_lsr);
1374 rvm_cpu_setophandler(cpu, RVM_LSRS, "LSRS", rvm_op_lsrs);
1375 rvm_cpu_setophandler(cpu, RVM_STM, "STM", rvm_op_stm);
1376 rvm_cpu_setophandler(cpu, RVM_LDM, "LDM", rvm_op_ldm);
1377 rvm_cpu_setophandler(cpu, RVM_STS, "STS", rvm_op_sts);
1378 rvm_cpu_setophandler(cpu, RVM_LDS, "LDS", rvm_op_lds);
1379 rvm_cpu_setophandler(cpu, RVM_ORR, "ORR", rvm_op_orr);
1380 rvm_cpu_setophandler(cpu, RVM_PUSH, "PUSH", rvm_op_push);
1381 rvm_cpu_setophandler(cpu, RVM_POP, "POP", rvm_op_pop);
1382 rvm_cpu_setophandler(cpu, RVM_CMP, "CMP", rvm_op_cmp);
1383 rvm_cpu_setophandler(cpu, RVM_NOP, "NOP", rvm_op_nop);
1384 rvm_cpu_setophandler(cpu, RVM_BEQ, "BEQ", rvm_op_beq);
1385 rvm_cpu_setophandler(cpu, RVM_BNEQ, "BNEQ", rvm_op_bneq);
1386 rvm_cpu_setophandler(cpu, RVM_BLEQ, "BLEQ", rvm_op_bleq);
1387 rvm_cpu_setophandler(cpu, RVM_BGEQ, "BGEQ", rvm_op_bgeq);
1388 rvm_cpu_setophandler(cpu, RVM_BLES, "BLES", rvm_op_bles);
1389 rvm_cpu_setophandler(cpu, RVM_BGRE, "BGRE", rvm_op_bgre);
1390 rvm_cpu_setophandler(cpu, RVM_RET, "RET", rvm_op_ret);
1391 rvm_cpu_setophandler(cpu, RVM_ROR, "ROR", rvm_op_ror);
1392 rvm_cpu_setophandler(cpu, RVM_PUSHM, "PUSHM", rvm_op_pushm);
1393 rvm_cpu_setophandler(cpu, RVM_POPM, "POPM", rvm_op_popm);
1394 rvm_cpu_setophandler(cpu, RVM_TST, "TST", rvm_op_tst);
1395 rvm_cpu_setophandler(cpu, RVM_TEQ, "TEQ", rvm_op_teq);
1396 rvm_cpu_setophandler(cpu, RVM_ADDRS, "ADDRS", rvm_op_addrs);
1397 rvm_cpu_setophandler(cpu, RVM_SETTYPE, "SETTYPE", rvm_op_settype);
1398 rvm_cpu_setophandler(cpu, RVM_TYPE, "TYPE", rvm_op_type);
1404 rvmcpu_t *rvm_cpu_create_default()
1406 return rvm_cpu_create(RVM_DEFAULT_STACKSIZE);
1410 void rvm_cpu_destroy(rvmcpu_t *cpu)
1412 r_gc_deallocateall(cpu->gc);
1413 r_gc_destroy(cpu->gc);
1414 r_object_destroy((robject_t*)cpu->switables);
1416 r_object_destroy((robject_t*)cpu->data);
1421 int rvm_cpu_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, ruword off)
1424 rvmreg_t *regda = RVM_CPUREG_PTR(cpu, DA);
1425 rvmreg_t *regpc = RVM_CPUREG_PTR(cpu, PC);
1427 RVM_CPUREG_SETIP(cpu, PC, prog + off);
1431 pi = RVM_REG_GETIP(regpc);
1435 #if RVM_CONDITIONAL_INSTRUCTIONS
1439 if (!((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0))
1443 if (!((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1))
1447 if (!((cpu->status & RVM_STATUS_Z)))
1451 if (!((cpu->status & RVM_STATUS_Z) == 0))
1455 if (!((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z)))
1459 if (!((cpu->status & RVM_STATUS_N)))
1467 cpu->ops[pi->opcode].op(cpu, pi);
1468 #if RVM_CONDITIONAL_INSTRUCTIONS
1471 RVM_REG_INCIP(regpc, 1);
1472 } while (!cpu->abort);
1479 int rvm_cpu_exec_debug(rvmcpu_t *cpu, rvm_asmins_t *prog, ruword off)
1482 rvmreg_t *regda = RVM_CPUREG_PTR(cpu, DA);
1483 rvmreg_t *regpc = RVM_CPUREG_PTR(cpu, PC);
1485 RVM_CPUREG_SETIP(cpu, PC, prog + off);
1489 pi = RVM_REG_GETIP(regpc);
1493 #if RVM_CONDITIONAL_INSTRUCTIONS
1497 if (!((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0))
1501 if (!((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1))
1505 if (!((cpu->status & RVM_STATUS_Z)))
1509 if (!((cpu->status & RVM_STATUS_Z) == 0))
1513 if (!((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z)))
1517 if (!((cpu->status & RVM_STATUS_N)))
1525 cpu->ops[pi->opcode].op(cpu, pi);
1526 rvm_cpu_dumpregs(cpu, pi);
1527 #if RVM_CONDITIONAL_INSTRUCTIONS
1530 RVM_REG_INCIP(regpc, 1);
1531 } while (!cpu->abort);
1538 int rvm_cpu_global_swilookup(rvmcpu_t *cpu, const char *swiname, unsigned long size)
1541 rvm_switable_t *swientry;
1542 unsigned long ntable;
1544 for (ntable = 0; ntable < r_harray_length(cpu->switables); ntable++) {
1545 swientry = r_harray_index(cpu->switables, ntable, rvm_switable_t*);
1548 for (nswi = 0; swientry[nswi].name; nswi++) {
1549 if (r_strncmp(swientry[nswi].name, swiname, size) == 0 && r_strlen(swientry[nswi].name) == size)
1550 return (int)RVM_SWI_ID(ntable, nswi);
1557 int rvm_cpu_table_swilookup(rvmcpu_t *cpu, const char *tabname, const char *swiname, unsigned long size)
1560 rvm_switable_t *swientry;
1561 long ntable = r_harray_lookup_s(cpu->switables, tabname);
1565 swientry = r_harray_index(cpu->switables, ntable, rvm_switable_t*);
1568 for (nswi = 0; swientry[nswi].name; nswi++) {
1569 if (r_strncmp(swientry[nswi].name, swiname, size) == 0 && r_strlen(swientry[nswi].name) == size)
1570 return (int)RVM_SWI_ID(ntable, nswi);
1576 int rvm_cpu_swilookup(rvmcpu_t *cpu, const char *tabname, const char *swiname, unsigned long size)
1578 return tabname ? rvm_cpu_table_swilookup(cpu, tabname, swiname, size) : rvm_cpu_global_swilookup(cpu, swiname, size);
1582 int rvm_cpu_swilookup_s(rvmcpu_t *cpu, const char *tabname, const char *swiname)
1584 return rvm_cpu_swilookup(cpu, tabname, swiname, r_strlen(swiname));
1588 int rvm_cpu_addswitable(rvmcpu_t *cpu, const char *tabname, rvm_switable_t *switable)
1590 return r_harray_replace_s(cpu->switables, tabname, &switable);
1594 int rvm_cpu_abort(rvmcpu_t *cpu)
1598 cpu->error = RVM_E_USERABORT;
1604 rvm_asmins_t rvm_cond_asma(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, char *data, unsigned long size)
1608 r_memset(&a, 0, sizeof(a));
1609 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
1610 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
1611 a.op1 = (ruint8)op1;
1612 a.op2 = (ruint8)op2;
1613 a.op3 = (ruint8)op3;
1614 a.cond = (ruint8)cond;
1615 rvm_reg_setstrptr(&a.data, data, size);
1616 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
1622 rvm_asmins_t rvm_asma(ruword opcode, ruword op1, ruword op2, ruword op3, char *data, unsigned long size)
1624 return rvm_cond_asma(0, opcode, op1, op2, op3, data, size);
1628 rvm_asmins_t rvm_cond_asmp(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, rpointer data)
1632 r_memset(&a, 0, sizeof(a));
1633 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
1634 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
1635 a.op1 = (ruint8)op1;
1636 a.op2 = (ruint8)op2;
1637 a.op3 = (ruint8)op3;
1638 a.cond = (ruint8)cond;
1639 rvm_reg_setpointer(&a.data, data);
1640 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
1646 rvm_asmins_t rvm_asmp(ruword opcode, ruword op1, ruword op2, ruword op3, rpointer data)
1648 return rvm_cond_asmp(0, opcode, op1, op2, op3, data);
1652 rvm_asmins_t rvm_cond_asms(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, ruword data)
1656 r_memset(&a, 0, sizeof(a));
1657 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
1658 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
1659 a.op1 = (ruint8)op1;
1660 a.op2 = (ruint8)op2;
1661 a.op3 = (ruint8)op3;
1662 a.cond = (ruint8)cond;
1663 rvm_reg_setunsigned(&a.data, data);
1664 RVM_REG_SETTYPE(&a.data, RVM_DTYPE_SWIID)
1665 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
1671 rvm_asmins_t rvm_asms(ruword opcode, ruword op1, ruword op2, ruword op3, ruword data)
1673 return rvm_cond_asms(0, opcode, op1, op2, op3, data);
1677 rvm_asmins_t rvm_cond_asmf(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, ruword data)
1681 r_memset(&a, 0, sizeof(a));
1682 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
1683 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
1684 a.op1 = (ruint8)op1;
1685 a.op2 = (ruint8)op2;
1686 a.op3 = (ruint8)op3;
1687 a.cond = (ruint8)cond;
1688 rvm_reg_setunsigned(&a.data, data);
1689 RVM_REG_SETTYPE(&a.data, RVM_DTYPE_FUNCTION)
1690 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
1695 rvm_asmins_t rvm_asmf(ruword opcode, ruword op1, ruword op2, ruword op3, ruword data)
1697 return rvm_cond_asmf(0, opcode, op1, op2, op3, data);
1701 rvm_asmins_t rvm_cond_asm(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, ruword data)
1705 r_memset(&a, 0, sizeof(a));
1706 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
1707 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
1708 a.op1 = (ruint8)op1;
1709 a.op2 = (ruint8)op2;
1710 a.op3 = (ruint8)op3;
1711 a.cond = (ruint8)cond;
1712 rvm_reg_setunsigned(&a.data, data);
1713 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
1719 rvm_asmins_t rvm_asm(ruword opcode, ruword op1, ruword op2, ruword op3, ruword data)
1721 return rvm_cond_asm(0, opcode, op1, op2, op3, data);
1726 rvm_asmins_t rvm_cond_asml(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, long data)
1730 r_memset(&a, 0, sizeof(a));
1731 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
1732 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
1733 a.op1 = (ruint8)op1;
1734 a.op2 = (ruint8)op2;
1735 a.op3 = (ruint8)op3;
1736 a.cond = (ruint8)cond;
1737 rvm_reg_setsigned(&a.data, data);
1738 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
1744 rvm_asmins_t rvm_asml(ruword opcode, ruword op1, ruword op2, ruword op3, long data)
1746 return rvm_cond_asml(0, opcode, op1, op2, op3, data);
1750 rvm_asmins_t rvm_cond_asmb(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, unsigned int data)
1754 r_memset(&a, 0, sizeof(a));
1755 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
1756 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
1757 a.op1 = (ruint8)op1;
1758 a.op2 = (ruint8)op2;
1759 a.op3 = (ruint8)op3;
1760 a.cond = (ruint8)cond;
1761 rvm_reg_setboolean(&a.data, data);
1762 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
1768 rvm_asmins_t rvm_asmb(ruword opcode, ruword op1, ruword op2, ruword op3, unsigned int data)
1770 return rvm_cond_asmb(0, opcode, op1, op2, op3, data);
1774 rvm_asmins_t rvm_cond_asmd(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, double data)
1778 r_memset(&a, 0, sizeof(a));
1779 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
1780 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
1781 a.op1 = (ruint8)op1;
1782 a.op2 = (ruint8)op2;
1783 a.op3 = (ruint8)op3;
1784 a.cond = (ruint8)cond;
1785 rvm_reg_setdouble(&a.data, data);
1786 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
1791 rvm_asmins_t rvm_asmd(ruword opcode, ruword op1, ruword op2, ruword op3, double data)
1793 return rvm_cond_asmd(0, opcode, op1, op2, op3, data);
1797 rvm_asmins_t rvm_cond_asm2(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, ruint32 p1, ruint32 p2)
1801 r_memset(&a, 0, sizeof(a));
1802 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
1803 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
1804 a.op1 = (ruint8)op1;
1805 a.op2 = (ruint8)op2;
1806 a.op3 = (ruint8)op3;
1807 a.cond = (ruint8)cond;
1808 rvm_reg_setpair(&a.data, p1, p2);
1809 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
1815 rvm_asmins_t rvm_asm2(ruword opcode, ruword op1, ruword op2, ruword op3, ruint32 p1, ruint32 p2)
1817 return rvm_cond_asm2(0, opcode, op1, op2, op3, p1, p2);
1820 rvmreg_t *rvm_cpu_alloc_global(rvmcpu_t *cpu)
1823 int index = r_carray_add(cpu->data, NULL);
1825 global = (rvmreg_t*)r_carray_slot(cpu->data, index);
1826 RVM_REG_CLEAR(global);
1827 RVM_REG_SETTYPE(global, RVM_DTYPE_UNDEF);
1832 int rvm_cpu_setreg(rvmcpu_t *cpu, ruword regnum, const rvmreg_t *src)
1836 RVM_CPUREG_SET(cpu, regnum, *src);
1841 rvmreg_t *rvm_cpu_getreg(rvmcpu_t *cpu, ruword regnum)
1845 return RVM_CPUREG_PTR(cpu, regnum);