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/rvmoperator.h"
25 #include "rvm/rvmoperatorbin.h"
26 #include "rvm/rvmoperatorcast.h"
27 #include "rvm/rvmoperatornot.h"
28 #include "rvm/rvmoperatorlogicnot.h"
29 #include "rvm/rvmcodemap.h"
30 #include "rlib/rmem.h"
31 #include "rlib/rstring.h"
32 #include "rvm/rvmreg.h"
33 #include "rlib/rmap.h"
35 #define RVM_DEFAULT_STACKSIZE (4 * 1024)
37 static const char *stropcalls[] = {
121 "CAST", /* Cast: op1 = (op3)op2 */
122 "TYPE", /* Type: op1 = typeof(op2) */
123 "SETTYPE", /* Type: op1.type = op2 */
175 static void rvm_op_b(rvmcpu_t *cpu, rvm_asmins_t *ins)
179 // if (ins->op1 != XX)
180 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
181 // if (ins->op2 != XX)
182 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
183 // if (ins->op3 != XX)
184 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
185 pc += RVM_CPUREG_GETU(cpu, ins->op1);
186 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
190 static void rvm_op_beq(rvmcpu_t *cpu, rvm_asmins_t *ins)
194 if ((cpu->status & RVM_STATUS_Z)) {
195 // if (ins->op1 != XX)
196 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
197 // if (ins->op2 != XX)
198 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
199 // if (ins->op3 != XX)
200 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
201 pc += RVM_CPUREG_GETU(cpu, ins->op1);
202 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
207 static void rvm_op_bneq(rvmcpu_t *cpu, rvm_asmins_t *ins)
211 if ((cpu->status & RVM_STATUS_Z) == 0) {
212 // if (ins->op1 != XX)
213 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
214 // if (ins->op2 != XX)
215 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
216 // if (ins->op3 != XX)
217 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
218 pc += RVM_CPUREG_GETU(cpu, ins->op1);
219 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
224 static void rvm_op_bleq(rvmcpu_t *cpu, rvm_asmins_t *ins)
228 if ((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z)) {
229 // if (ins->op1 != XX)
230 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
231 // if (ins->op2 != XX)
232 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
233 // if (ins->op3 != XX)
234 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
235 pc += RVM_CPUREG_GETU(cpu, ins->op1);
236 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
240 static void rvm_op_bgeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
244 if ((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1) {
245 // if (ins->op1 != XX)
246 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
247 // if (ins->op2 != XX)
248 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
249 // if (ins->op3 != XX)
250 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
251 pc += RVM_CPUREG_GETU(cpu, ins->op1);
252 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
257 static void rvm_op_bles(rvmcpu_t *cpu, rvm_asmins_t *ins)
262 if ((cpu->status & RVM_STATUS_N)) {
263 // if (ins->op1 != XX)
264 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
265 // if (ins->op2 != XX)
266 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
267 // if (ins->op3 != XX)
268 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
269 pc += RVM_CPUREG_GETU(cpu, ins->op1);
270 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
275 static void rvm_op_bgre(rvmcpu_t *cpu, rvm_asmins_t *ins)
279 if ((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0) {
280 // if (ins->op1 != XX)
281 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
282 // if (ins->op2 != XX)
283 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
284 // if (ins->op3 != XX)
285 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
286 pc += RVM_CPUREG_GETU(cpu, ins->op1);
287 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
292 static void rvm_op_bx(rvmcpu_t *cpu, rvm_asmins_t *ins)
294 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
298 static void rvm_op_bxleq(rvmcpu_t *cpu, rvm_asmins_t *ins)
300 if ((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z)) {
301 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
306 static void rvm_op_bxgeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
308 if ((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1){
309 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
314 static void rvm_op_bxles(rvmcpu_t *cpu, rvm_asmins_t *ins)
316 if ((cpu->status & RVM_STATUS_N)) {
317 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
322 static void rvm_op_bxgre(rvmcpu_t *cpu, rvm_asmins_t *ins)
324 if ((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0) {
325 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
330 static void rvm_op_bxeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
332 if ((cpu->status & RVM_STATUS_Z)) {
333 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
338 static void rvm_op_bxneq(rvmcpu_t *cpu, rvm_asmins_t *ins)
340 if (!(cpu->status & RVM_STATUS_Z)) {
341 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
346 static void rvm_op_bxl(rvmcpu_t *cpu, rvm_asmins_t *ins)
348 RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
349 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
353 static void rvm_op_bl(rvmcpu_t *cpu, rvm_asmins_t *ins)
357 // if (ins->op1 != XX)
358 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
359 // if (ins->op2 != XX)
360 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
361 // if (ins->op3 != XX)
362 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
363 pc += RVM_CPUREG_GETU(cpu, ins->op1);
364 RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
365 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
369 static void rvm_op_exit(rvmcpu_t *cpu, rvm_asmins_t *ins)
375 static void rvm_op_mov(rvmcpu_t *cpu, rvm_asmins_t *ins)
377 RVM_CPUREG_SET(cpu, ins->op1, RVM_CPUREG_GET(cpu, ins->op2));
381 static void rvm_op_movs(rvmcpu_t *cpu, rvm_asmins_t *ins)
383 ruword op2 = RVM_CPUREG_GETU(cpu, ins->op2);;
385 RVM_CPUREG_SETU(cpu, ins->op1, op2);
386 RVM_STATUS_CLRALL(cpu);
387 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !op2);
388 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, op2 & RVM_SIGN_BIT);
392 static void rvm_op_swp(rvmcpu_t *cpu, rvm_asmins_t *ins)
394 rvmreg_t tmp = RVM_CPUREG_GET(cpu, ins->op1);
395 RVM_CPUREG_SET(cpu, ins->op1, RVM_CPUREG_GET(cpu, ins->op2));
396 RVM_CPUREG_SET(cpu, ins->op2, tmp);
400 static void rvm_op_ldr(rvmcpu_t *cpu, rvm_asmins_t *ins)
402 RVM_CPUREG_SETU(cpu, ins->op1, *((ruword*)RVM_CPUREG_GETU(cpu, ins->op2)));
407 static void rvm_op_ldrp(rvmcpu_t *cpu, rvm_asmins_t *ins)
409 RVM_CPUREG_SETU(cpu, ins->op1, *((rpointer*)RVM_CPUREG_GETU(cpu, ins->op2)));
413 static void rvm_op_ldrb(rvmcpu_t *cpu, rvm_asmins_t *ins)
415 RVM_CPUREG_SETU(cpu, ins->op1, *((ruint8*)RVM_CPUREG_GETU(cpu, ins->op2)));
419 static void rvm_op_ldrh(rvmcpu_t *cpu, rvm_asmins_t *ins)
421 RVM_CPUREG_SETU(cpu, ins->op1, *((ruint16*)RVM_CPUREG_GETU(cpu, ins->op2)));
425 static void rvm_op_ldrw(rvmcpu_t *cpu, rvm_asmins_t *ins)
427 RVM_CPUREG_SETU(cpu, ins->op1, *((ruint32*)RVM_CPUREG_GETU(cpu, ins->op2)));
431 static void rvm_op_ldrr(rvmcpu_t *cpu, rvm_asmins_t *ins)
433 RVM_CPUREG_SET(cpu, ins->op1, *((rvmreg_t*)RVM_CPUREG_GETU(cpu, ins->op2)));
437 static void rvm_op_clr(rvmcpu_t *cpu, rvm_asmins_t *ins)
439 RVM_REG_CLEAR(((rvmreg_t*)RVM_CPUREG_PTR(cpu, ins->op1)));
440 RVM_REG_SETTYPE(((rvmreg_t*)RVM_CPUREG_PTR(cpu, ins->op1)), RVM_DTYPE_UNDEF);
444 static void rvm_op_cflag(rvmcpu_t *cpu, rvm_asmins_t *ins)
446 ruword op1 = RVM_CPUREG_GETU(cpu, ins->op1);
447 RVM_STATUS_CLRBIT(cpu, op1);
451 static void rvm_op_clrr(rvmcpu_t *cpu, rvm_asmins_t *ins)
453 RVM_REG_CLEAR(((rvmreg_t*)RVM_CPUREG_GETP(cpu, ins->op1)));
454 RVM_REG_SETTYPE(((rvmreg_t*)RVM_CPUREG_GETP(cpu, ins->op1)), RVM_DTYPE_UNDEF);
458 static void rvm_op_str(rvmcpu_t *cpu, rvm_asmins_t *ins)
460 *((ruword*)RVM_CPUREG_GETP(cpu, ins->op2)) = RVM_CPUREG_GETU(cpu, ins->op1);
464 static void rvm_op_strp(rvmcpu_t *cpu, rvm_asmins_t *ins)
466 *((rpointer*)RVM_CPUREG_GETP(cpu, ins->op2)) = (rpointer)RVM_CPUREG_GETP(cpu, ins->op1);
470 static void rvm_op_strb(rvmcpu_t *cpu, rvm_asmins_t *ins)
472 *((ruint8*)RVM_CPUREG_GETP(cpu, ins->op2)) = (ruint8)RVM_CPUREG_GETU(cpu, ins->op1);
476 static void rvm_op_strh(rvmcpu_t *cpu, rvm_asmins_t *ins)
478 *((ruint16*)RVM_CPUREG_GETP(cpu, ins->op2)) = (ruint16)RVM_CPUREG_GETU(cpu, ins->op1);
483 static void rvm_op_strw(rvmcpu_t *cpu, rvm_asmins_t *ins)
485 *((ruint32*)RVM_CPUREG_GETP(cpu, ins->op2)) = (ruint32)RVM_CPUREG_GETU(cpu, ins->op1);
490 static void rvm_op_strr(rvmcpu_t *cpu, rvm_asmins_t *ins)
492 rvmreg_t *dest = RVM_CPUREG_PTR(cpu, ins->op2);
493 if (RVM_REG_GETTYPE(dest) != RVM_DTYPE_POINTER)
494 RVM_ABORT(cpu, RVM_E_LVALUE);
496 *((rvmreg_t*)RVM_REG_GETP(dest)) = RVM_CPUREG_GET(cpu, ins->op1);
500 static void rvm_op_adds(rvmcpu_t *cpu, rvm_asmins_t *ins)
502 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
505 RVM_CPUREG_SETU(cpu, ins->op1, res);
506 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, res < op2 || res < op3);
507 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
508 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
509 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op2 & RVM_SIGN_BIT) == (op3 & RVM_SIGN_BIT) &&
510 (res & RVM_SIGN_BIT) != (op2 & RVM_SIGN_BIT));
514 static void rvm_op_adc(rvmcpu_t *cpu, rvm_asmins_t *ins)
516 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
518 res = op2 + op3 + (RVM_STATUS_GETBIT(cpu, RVM_STATUS_C) ? 1 : 0);
519 RVM_CPUREG_SETU(cpu, ins->op1, res);
520 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, res < op2 || res < op3);
521 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
522 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
523 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op2 & RVM_SIGN_BIT) == (op3 & RVM_SIGN_BIT) &&
524 (res & RVM_SIGN_BIT) != (op2 & RVM_SIGN_BIT));
528 static void rvm_op_and(rvmcpu_t *cpu, rvm_asmins_t *ins)
530 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
533 RVM_CPUREG_SETU(cpu, ins->op1, res);
534 RVM_STATUS_CLRALL(cpu);
535 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
536 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
540 static void rvm_op_orr(rvmcpu_t *cpu, rvm_asmins_t *ins)
542 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
545 RVM_CPUREG_SETU(cpu, ins->op1, res);
546 RVM_STATUS_CLRALL(cpu);
547 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
548 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
552 static void rvm_op_lsl(rvmcpu_t *cpu, rvm_asmins_t *ins)
554 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
557 RVM_CPUREG_SETU(cpu, ins->op1, res);
558 RVM_STATUS_CLRALL(cpu);
559 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
560 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
564 static void rvm_op_lsr(rvmcpu_t *cpu, rvm_asmins_t *ins)
566 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
569 RVM_CPUREG_SETU(cpu, ins->op1, res);
570 RVM_STATUS_CLRALL(cpu);
571 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
575 static void rvm_op_lsrs(rvmcpu_t *cpu, rvm_asmins_t *ins)
577 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
579 res = ((rword)op2) >> op3;
580 RVM_CPUREG_SETU(cpu, ins->op1, res);
581 RVM_STATUS_CLRALL(cpu);
582 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
586 static void rvm_op_asr(rvmcpu_t *cpu, rvm_asmins_t *ins)
588 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
591 res |= op2 & RVM_SIGN_BIT;
592 RVM_CPUREG_SETU(cpu, ins->op1, res);
593 RVM_STATUS_CLRALL(cpu);
594 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
595 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
599 static void rvm_op_ror(rvmcpu_t *cpu, rvm_asmins_t *ins)
602 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
605 for (i = 0; i < op3; i++) {
613 RVM_CPUREG_SETU(cpu, ins->op1, res);
614 RVM_STATUS_CLRALL(cpu);
615 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
616 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
617 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, res & RVM_SIGN_BIT);
621 static void rvm_op_tst(rvmcpu_t *cpu, rvm_asmins_t *ins)
623 ruword res, op1 = RVM_CPUREG_GETU(cpu, ins->op1), op2 = RVM_CPUREG_GETU(cpu, ins->op2);
626 RVM_STATUS_CLRALL(cpu);
627 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
628 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
632 static void rvm_op_xor(rvmcpu_t *cpu, rvm_asmins_t *ins)
634 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
637 RVM_CPUREG_SETU(cpu, ins->op1, res);
638 RVM_STATUS_CLRALL(cpu);
639 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
640 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
644 static void rvm_op_not(rvmcpu_t *cpu, rvm_asmins_t *ins)
646 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2);
649 RVM_CPUREG_SETU(cpu, ins->op1, res);
650 RVM_STATUS_CLRALL(cpu);
651 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
652 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
656 static void rvm_op_teq(rvmcpu_t *cpu, rvm_asmins_t *ins)
658 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
661 RVM_STATUS_CLRALL(cpu);
662 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
663 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
667 static void rvm_op_bic(rvmcpu_t *cpu, rvm_asmins_t *ins)
669 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
672 RVM_CPUREG_SETU(cpu, ins->op1, res);
673 RVM_STATUS_CLRALL(cpu);
674 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
675 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
679 static void rvm_op_clz(rvmcpu_t *cpu, rvm_asmins_t *ins)
681 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2);
683 for (res = RVM_REGISTER_BITS; op2; ) {
687 RVM_CPUREG_SETU(cpu, ins->op1, res);
691 static void rvm_op_add(rvmcpu_t *cpu, rvm_asmins_t *ins)
693 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) + RVM_CPUREG_GETU(cpu, ins->op3));
697 static void rvm_op_inc(rvmcpu_t *cpu, rvm_asmins_t *ins)
699 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op1) + 1);
703 static void rvm_op_dec(rvmcpu_t *cpu, rvm_asmins_t *ins)
705 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op1) - 1);
709 static void rvm_op_swi(rvmcpu_t *cpu, rvm_asmins_t *ins)
712 rvm_switable_t *switable;
713 unsigned int ntable = (unsigned int) RVM_SWI_TABLE(ins->swi);
714 unsigned int nswi = (unsigned int) RVM_SWI_NUM(ins->swi);
716 if (r_harray_length(cpu->switables) <= ntable)
717 RVM_ABORT(cpu, RVM_E_SWITABLE);
718 switable = r_harray_index(cpu->switables, ntable, rvm_switable_t*);
719 swi = switable[nswi].op;
724 static void rvm_op_swiid(rvmcpu_t *cpu, rvm_asmins_t *ins)
727 rvm_switable_t *switable;
728 unsigned int ntable = (unsigned int) RVM_SWI_TABLE(RVM_CPUREG_GETU(cpu, ins->op1));
729 unsigned int nswi = (unsigned int) RVM_SWI_NUM(RVM_CPUREG_GETU(cpu, ins->op1));
731 if (r_harray_length(cpu->switables) <= ntable)
732 RVM_ABORT(cpu, RVM_E_SWITABLE);
733 switable = r_harray_index(cpu->switables, ntable, rvm_switable_t*);
734 swi = switable[nswi].op;
739 static void rvm_op_call(rvmcpu_t *cpu, rvm_asmins_t *ins)
741 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
743 if (RVM_REG_GETTYPE(arg1) == RVM_DTYPE_SWIID) {
744 RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
745 rvm_op_swiid(cpu, ins);
746 } else if (RVM_REG_GETTYPE(arg1) == RVM_DTYPE_FUNCTION) {
747 rvm_op_bxl(cpu, ins);
749 RVM_ABORT(cpu, RVM_E_NOTFUNCTION);
754 static void rvm_op_sub(rvmcpu_t *cpu, rvm_asmins_t *ins)
756 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) - RVM_CPUREG_GETU(cpu, ins->op3));
760 static void rvm_op_subs(rvmcpu_t *cpu, rvm_asmins_t *ins)
762 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
765 RVM_CPUREG_SETU(cpu, ins->op1, res);
766 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, !(res > op2)); /* borrow = !carry */
767 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
768 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
769 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op2 & RVM_SIGN_BIT) != (op3 & RVM_SIGN_BIT) &&
770 (res & RVM_SIGN_BIT) == (op2 & RVM_SIGN_BIT));
774 static void rvm_op_sbc(rvmcpu_t *cpu, rvm_asmins_t *ins)
776 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
778 res = op2 - op3 + (RVM_STATUS_GETBIT(cpu, RVM_STATUS_C) ? 0 : -1);
779 RVM_CPUREG_SETU(cpu, ins->op1, res);
780 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, !(res > op2)); /* borrow = !carry */
781 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
782 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
783 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op2 & RVM_SIGN_BIT) != (op3 & RVM_SIGN_BIT) &&
784 (res & RVM_SIGN_BIT) == (op2 & RVM_SIGN_BIT));
788 static void rvm_op_mul(rvmcpu_t *cpu, rvm_asmins_t *ins)
790 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) * RVM_CPUREG_GETU(cpu, ins->op3));
794 static void rvm_op_mls(rvmcpu_t *cpu, rvm_asmins_t *ins)
797 rword op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
799 res = (rword)(op2 * op3);
800 RVM_CPUREG_SETU(cpu, ins->op1, res);
801 /* TBD: Not sure how to update the RVM_STATUS_C */
802 RVM_STATUS_CLRALL(cpu);
803 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
804 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
808 static void rvm_op_muls(rvmcpu_t *cpu, rvm_asmins_t *ins)
810 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
813 RVM_CPUREG_SETU(cpu, ins->op1, res);
814 RVM_STATUS_CLRALL(cpu);
815 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, op2 && (res / op2) != op3);
816 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
817 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
821 static void rvm_op_div(rvmcpu_t *cpu, rvm_asmins_t *ins)
823 if (!RVM_CPUREG_GETU(cpu, ins->op3))
824 RVM_ABORT(cpu, RVM_E_DIVZERO);
826 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) / RVM_CPUREG_GETU(cpu, ins->op3));
830 static void rvm_op_divs(rvmcpu_t *cpu, rvm_asmins_t *ins)
832 ruword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
835 RVM_ABORT(cpu, RVM_E_DIVZERO);
837 RVM_CPUREG_SETU(cpu, ins->op1, res);
838 RVM_STATUS_CLRALL(cpu);
839 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
840 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
844 static void rvm_op_mod(rvmcpu_t *cpu, rvm_asmins_t *ins)
846 if (!RVM_CPUREG_GETU(cpu, ins->op3))
847 RVM_ABORT(cpu, RVM_E_DIVZERO);
849 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) % RVM_CPUREG_GETU(cpu, ins->op3));
853 static void rvm_op_mods(rvmcpu_t *cpu, rvm_asmins_t *ins)
855 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
858 RVM_ABORT(cpu, RVM_E_DIVZERO);
860 r_printf("mod RES: %ld\n", res);
861 RVM_CPUREG_SETU(cpu, ins->op1, res);
862 RVM_STATUS_CLRALL(cpu);
863 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
864 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
868 static void rvm_op_dvs(rvmcpu_t *cpu, rvm_asmins_t *ins)
871 rword op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
874 RVM_ABORT(cpu, RVM_E_DIVZERO);
875 res = (rword)(op2 / op3);
876 RVM_CPUREG_SETU(cpu, ins->op1, res);
877 RVM_STATUS_CLRALL(cpu);
878 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
879 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
883 static void rvm_op_push(rvmcpu_t *cpu, rvm_asmins_t *ins)
885 ruword sp = RVM_CPUREG_GETU(cpu, SP) + 1;
887 if (!RVM_STACK_CHECKSIZE(cpu, cpu->stack, sp))
888 RVM_ABORT(cpu, RVM_E_NOMEM);
889 RVM_STACK_WRITE(cpu->stack, sp, &RVM_CPUREG_GET(cpu, ins->op1));
890 RVM_CPUREG_SETU(cpu, SP, sp);
894 static void rvm_op_lds(rvmcpu_t *cpu, rvm_asmins_t *ins)
896 ruword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
898 RVM_CPUREG_SET(cpu, ins->op1, RVM_STACK_READ(cpu->stack, sp));
902 static void rvm_op_sts(rvmcpu_t *cpu, rvm_asmins_t *ins)
904 ruword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
906 if (!RVM_STACK_CHECKSIZE(cpu, cpu->stack, sp))
907 RVM_ABORT(cpu, RVM_E_NOMEM);
908 RVM_STACK_WRITE(cpu->stack, sp, &RVM_CPUREG_GET(cpu, ins->op1));
912 static void rvm_op_pushm(rvmcpu_t *cpu, rvm_asmins_t *ins)
915 ruword bits = RVM_CPUREG_GETU(cpu, ins->op1);
916 ruword sp = RVM_CPUREG_GETU(cpu, SP);
918 if (!RVM_STACK_CHECKSIZE(cpu, cpu->stack, sp + RVM_REGS_NUM))
919 RVM_ABORT(cpu, RVM_E_NOMEM);
921 if (!(bits & ((1<<(RVM_REGS_NUM / 2)) - 1)))
922 i = RVM_REGS_NUM / 2;
923 for (;bits && i < RLST; i++) {
924 n = ((ruword)1) << i;
927 RVM_STACK_WRITE(cpu->stack, sp, &RVM_CPUREG_GET(cpu, i));
931 RVM_CPUREG_SETU(cpu, SP, sp);
935 static void rvm_op_popm(rvmcpu_t *cpu, rvm_asmins_t *ins)
938 ruword bits = RVM_CPUREG_GETU(cpu, ins->op1);
939 ruword savedbits = bits;
940 ruword sp = RVM_CPUREG_GETU(cpu, SP);
942 if (!(bits & ~((1 << (RVM_REGS_NUM / 2)) - 1)))
943 i = RVM_REGS_NUM / 2 - 1;
944 for (; bits && i >= 0; i--) {
947 RVM_CPUREG_SET(cpu, i, RVM_STACK_READ(cpu->stack, sp));
952 if (!(((ruword)(1 << SP)) & savedbits))
953 RVM_CPUREG_SETU(cpu, SP, sp);
957 static void rvm_op_pop(rvmcpu_t *cpu, rvm_asmins_t *ins)
959 ruword sp = RVM_CPUREG_GETU(cpu, SP);
961 RVM_CPUREG_SET(cpu, ins->op1, RVM_STACK_READ(cpu->stack, sp));
963 RVM_CPUREG_SETU(cpu, SP, sp - 1);
967 static void rvm_op_addrs(rvmcpu_t *cpu, rvm_asmins_t *ins)
969 ruword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
971 if (!RVM_STACK_CHECKSIZE(cpu, cpu->stack, sp))
972 RVM_ABORT(cpu, RVM_E_NOMEM);
974 RVM_CPUREG_CLEAR(cpu, ins->op1);
975 RVM_CPUREG_SETTYPE(cpu, ins->op1, RVM_DTYPE_POINTER);
976 RVM_CPUREG_SETP(cpu, ins->op1, RVM_STACK_ADDR(cpu->stack, sp));
980 static void rvm_op_stm(rvmcpu_t *cpu, rvm_asmins_t *ins)
983 ruword *dst = (ruword*) RVM_CPUREG_GETU(cpu, ins->op1);
984 ruword bits = RVM_CPUREG_GETU(cpu, ins->op2);
986 for (n = 0; bits && n < RLST; n++) {
987 if (((ruword)(1 << n)) & bits) {
988 *dst = RVM_CPUREG_GETU(cpu, n);
996 static void rvm_op_ldm(rvmcpu_t *cpu, rvm_asmins_t *ins)
999 ruword *src = (ruword*)RVM_CPUREG_GETU(cpu, ins->op1);
1000 ruword bits = RVM_CPUREG_GETU(cpu, ins->op2);
1002 for (n = 0; bits && n < RLST; n++) {
1003 if (((ruword)(1 << n)) & bits) {
1004 RVM_CPUREG_CLEAR(cpu, n);
1005 RVM_CPUREG_SETU(cpu, n, *src);
1013 static void rvm_op_cmp(rvmcpu_t *cpu, rvm_asmins_t *ins)
1015 ruword op1 = RVM_CPUREG_GETU(cpu, ins->op1), op2 = RVM_CPUREG_GETU(cpu, ins->op2);
1016 ruword res = (ruword)(op1 - op2);
1018 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, op1 < op2);
1019 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
1020 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
1021 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op1 & RVM_SIGN_BIT) != (op2 & RVM_SIGN_BIT) &&
1022 (res & RVM_SIGN_BIT) == (op1 & RVM_SIGN_BIT));
1026 static void rvm_op_cmn(rvmcpu_t *cpu, rvm_asmins_t *ins)
1028 ruword op1 = RVM_CPUREG_GETU(cpu, ins->op1), op2 = RVM_CPUREG_GETU(cpu, ins->op2);
1029 ruword res = (ruword)(op1 + op2);
1031 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, res < op1 || res < op2);
1032 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
1033 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
1034 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op1 & RVM_SIGN_BIT) == (op2 & RVM_SIGN_BIT) &&
1035 (res & RVM_SIGN_BIT) != (op1 & RVM_SIGN_BIT));
1040 static void rvm_op_nop(rvmcpu_t *cpu, rvm_asmins_t *ins)
1042 // fprintf(stdout, "nop\n");
1046 static void rvm_op_ret(rvmcpu_t *cpu, rvm_asmins_t *ins)
1048 RVM_CPUREG_SETU(cpu, PC, RVM_CPUREG_GETU(cpu, LR));
1052 static int rvm_vsnprintf(char *str, unsigned int size, const char *format, va_list ap)
1054 return vsnprintf(str, size, format, ap);
1058 static int rvm_snprintf(char *str, unsigned int size, const char *format, ...)
1063 va_start(ap, format);
1064 ret = rvm_vsnprintf(str, size, format, ap);
1070 static int rvm_printf(const char *format, ...)
1075 va_start(ap, format);
1076 ret = vfprintf(stdout, format, ap);
1082 int rvm_asm_dump_reg_to_str(unsigned int reg, char *str, unsigned int size)
1087 ret = rvm_snprintf(str, size, "XX ");
1089 ret = rvm_snprintf(str, size, "IP ");
1091 ret = rvm_snprintf(str, size, "TP ");
1093 ret = rvm_snprintf(str, size, "FP ");
1095 ret = rvm_snprintf(str, size, "SP ");
1097 ret = rvm_snprintf(str, size, "LR ");
1099 ret = rvm_snprintf(str, size, "PC ");
1101 ret = rvm_snprintf(str, size, "DA ");
1103 ret = rvm_snprintf(str, size, "R%d ", reg);
1109 static void rvm_op_prn(rvmcpu_t *cpu, rvm_asmins_t *ins)
1111 rvmreg_t *r = RVM_CPUREG_PTR(cpu, ins->op1);
1113 if (rvm_reg_gettype(r) == RVM_DTYPE_UNSIGNED)
1114 rvm_printf("(UNSIGNED) R%d = %lu(0x%lx)\n", ins->op1, RVM_REG_GETU(r), RVM_REG_GETU(r));
1115 else if (rvm_reg_gettype(r) == RVM_DTYPE_BOOLEAN)
1116 rvm_printf("(UNSIGNED) R%d = %lu(0x%lx)\n", ins->op1, RVM_REG_GETU(r), RVM_REG_GETU(r));
1117 else if (rvm_reg_gettype(r) == RVM_DTYPE_POINTER)
1118 rvm_printf("(POINTER) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
1119 else if (rvm_reg_gettype(r) == RVM_DTYPE_SINGED)
1120 rvm_printf("(LONG) R%d = %ld\n", ins->op1, RVM_REG_GETL(r));
1121 else if (rvm_reg_gettype(r) == RVM_DTYPE_DOUBLE)
1122 rvm_printf("(DOUBLE) R%d = %0.2f\n", ins->op1, RVM_REG_GETD(r));
1123 else if (rvm_reg_gettype(r) == RVM_DTYPE_STRING)
1124 rvm_printf("(STRING) R%d = %s\n", ins->op1, ((rstring_t*) RVM_REG_GETP(r))->s.str);
1125 else if (rvm_reg_gettype(r) == RVM_DTYPE_ARRAY)
1126 rvm_printf("(ARRAY) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
1127 else if (rvm_reg_gettype(r) == RVM_DTYPE_JSOBJECT)
1128 rvm_printf("(Object) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
1129 else if (rvm_reg_gettype(r) == RVM_DTYPE_SWIID)
1130 rvm_printf("(SWI) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
1131 else if (rvm_reg_gettype(r) == RVM_DTYPE_FUNCTION)
1132 rvm_printf("(FUNCTION) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
1134 rvm_printf("(UNKNOWN) R%d = ?\n", ins->op1);
1138 int rvm_asm_dump_pi_to_str(rvmcpu_t *vm, rvm_asmins_t *pi, char *str, unsigned int size)
1140 int ret = 0, sz = size;
1142 if (pi->opcode == RVM_SWI) {
1144 r_memset(szSwi, 0, sizeof(szSwi));
1146 rvm_snprintf(szSwi, sizeof(szSwi) - 1, "%s(%x)", stropcalls[pi->opcode], (ruint32)pi->swi);
1148 rvm_switable_t *switable;
1149 unsigned int ntable = (unsigned int) RVM_SWI_TABLE(pi->swi);
1150 unsigned int nswi = (unsigned int) RVM_SWI_NUM(pi->swi);
1152 if (ntable < r_harray_length(vm->switables)) {
1153 switable = r_harray_index(vm->switables, ntable, rvm_switable_t*);
1154 rvm_snprintf(szSwi, sizeof(szSwi) - 1, "(%s)", switable[nswi].name ? switable[nswi].name : "unknown");
1157 if ((ret = rvm_snprintf(str, sz, "%16s ", szSwi)) < 0)
1160 if ((ret = rvm_snprintf(str, sz, "%16s ", stropcalls[pi->opcode])) < 0)
1166 if ((ret = rvm_asm_dump_reg_to_str(pi->op1, str, sz)) < 0)
1171 if ((ret = rvm_snprintf(str, sz, " ")) < 0)
1176 if ((ret = rvm_asm_dump_reg_to_str(pi->op2, str, sz)) < 0)
1181 if ((ret = rvm_snprintf(str, sz, " ")) < 0)
1186 if ((ret = rvm_asm_dump_reg_to_str(pi->op3, str, sz)) < 0)
1191 if ((ret = rvm_snprintf(str, sz, " ")) < 0)
1197 if (RVM_REG_GETTYPE(&pi->data) == RVM_DTYPE_DOUBLE) {
1198 if ((ret = rvm_snprintf(str, sz, "%f ", RVM_REG_GETD(&pi->data))) < 0)
1200 } else if (RVM_REG_GETTYPE(&pi->data) == RVM_DTYPE_SINGED) {
1201 if ((ret = rvm_snprintf(str, sz, "%ld ", RVM_REG_GETL(&pi->data))) < 0)
1204 if ((ret = rvm_snprintf(str, sz, "0x%lx ", (unsigned long)RVM_REG_GETU(&pi->data))) < 0)
1215 void rvm_asm_dump(rvm_asmins_t *pi, unsigned int count)
1219 rvm_asm_dump_pi_to_str(NULL, pi, buffer, sizeof(buffer));
1220 rvm_printf("%s\n", buffer);
1227 void rvm_cpu_dumpregs(rvmcpu_t *vm, rvm_asmins_t *pi)
1232 ret = rvm_asm_dump_pi_to_str(vm, pi, buffer, sizeof(buffer));
1235 ret = rvm_snprintf(buffer + ret, sizeof(buffer) - ret, " ");
1237 rvm_printf("%s", buffer);
1239 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 )",
1240 RVM_CPUREG_GETU(vm, 0), RVM_CPUREG_GETU(vm, 1), RVM_CPUREG_GETU(vm, 2), RVM_CPUREG_GETU(vm, 3),
1241 RVM_CPUREG_GETU(vm, 4), RVM_CPUREG_GETU(vm, 5), RVM_CPUREG_GETU(vm, 6), RVM_CPUREG_GETU(vm, 7),
1242 RVM_CPUREG_GETU(vm, 8), RVM_CPUREG_GETP(vm, TP), (long int)RVM_CPUREG_GETU(vm, FP), (long int)RVM_CPUREG_GETU(vm, SP),
1243 (long int)RVM_CPUREG_GETU(vm, LR), (long int)RVM_CPUREG_GETU(vm, PC), RVM_CPUREG_GETU(vm, DA),
1244 vm->status & RVM_STATUS_E ? 'E' : '_',
1245 vm->status & RVM_STATUS_V ? 'V' : '_',
1246 vm->status & RVM_STATUS_C ? 'C' : '_',
1247 vm->status & RVM_STATUS_N ? 'N' : '_',
1248 vm->status & RVM_STATUS_Z ? 'Z' : '_');
1253 static void rvm_op_cast(rvmcpu_t *cpu, rvm_asmins_t *ins)
1255 rvmreg_type_t type = (rvmreg_type_t)RVM_CPUREG_GETU(cpu, ins->op3);
1258 RVM_REG_CLEAR(&tmp);
1259 RVM_REG_SETTYPE(&tmp, type);
1260 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, RVM_CPUREG_PTR(cpu, ins->op1), RVM_CPUREG_PTR(cpu, ins->op2), &tmp);
1264 static void rvm_op_type(rvmcpu_t *cpu, rvm_asmins_t *ins)
1266 rvmreg_type_t type = (rvmreg_type_t)RVM_CPUREG_GETTYPE(cpu, ins->op2);
1268 RVM_CPUREG_SETU(cpu, ins->op1, type);
1272 static void rvm_op_settype(rvmcpu_t *cpu, rvm_asmins_t *ins)
1274 rvmreg_type_t type = (rvmreg_type_t)RVM_CPUREG_GETU(cpu, ins->op2);
1276 RVM_CPUREG_SETTYPE(cpu, ins->op1, type);
1280 static void rvm_op_emov(rvmcpu_t *cpu, rvm_asmins_t *ins)
1282 rvm_op_mov(cpu, ins);
1286 static void rvm_op_eadd(rvmcpu_t *cpu, rvm_asmins_t *ins)
1288 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1289 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1291 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_ADD, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1295 static void rvm_op_esub(rvmcpu_t *cpu, rvm_asmins_t *ins)
1297 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1298 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1300 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_SUB, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1304 static void rvm_op_eneg(rvmcpu_t *cpu, rvm_asmins_t *ins)
1306 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1309 rvm_reg_setunsigned(&zero, 0);
1310 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_SUB, cpu, RVM_CPUREG_PTR(cpu, ins->op1), &zero, arg2);
1315 static void rvm_op_emul(rvmcpu_t *cpu, rvm_asmins_t *ins)
1317 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1318 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1320 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_MUL, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1324 static void rvm_op_ediv(rvmcpu_t *cpu, rvm_asmins_t *ins)
1326 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1327 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1329 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_DIV, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1333 static void rvm_op_emod(rvmcpu_t *cpu, rvm_asmins_t *ins)
1335 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1336 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1338 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_MOD, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1342 static void rvm_op_elsl(rvmcpu_t *cpu, rvm_asmins_t *ins)
1344 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1345 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1347 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LSL, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1351 static void rvm_op_elsr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1353 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1354 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1356 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LSR, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1360 static void rvm_op_elsru(rvmcpu_t *cpu, rvm_asmins_t *ins)
1362 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1363 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1365 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LSRU, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1369 static void rvm_op_eand(rvmcpu_t *cpu, rvm_asmins_t *ins)
1371 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1372 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1374 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_AND, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1378 static void rvm_op_eorr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1380 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1381 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1383 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_OR, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1387 static void rvm_op_exor(rvmcpu_t *cpu, rvm_asmins_t *ins)
1389 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1390 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1392 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_XOR, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1396 static void rvm_op_enot(rvmcpu_t *cpu, rvm_asmins_t *ins)
1398 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1400 rvm_opmap_invoke_unary_handler(cpu->opmap, RVM_OPID_NOT, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2);
1404 static void rvm_op_eland(rvmcpu_t *cpu, rvm_asmins_t *ins)
1406 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1407 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1409 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LOGICAND, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1413 static void rvm_op_elor(rvmcpu_t *cpu, rvm_asmins_t *ins)
1415 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1416 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1418 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LOGICOR, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1422 static void rvm_op_elnot(rvmcpu_t *cpu, rvm_asmins_t *ins)
1424 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1426 rvm_opmap_invoke_unary_handler(cpu->opmap, RVM_OPID_LOGICNOT, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2);
1430 static void rvm_op_eeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
1432 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1433 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1435 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_EQ, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1439 static void rvm_op_enoteq(rvmcpu_t *cpu, rvm_asmins_t *ins)
1441 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1442 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1444 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_NOTEQ, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1448 static void rvm_op_egreat(rvmcpu_t *cpu, rvm_asmins_t *ins)
1450 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1451 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1453 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_GREATER, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1457 static void rvm_op_egreateq(rvmcpu_t *cpu, rvm_asmins_t *ins)
1459 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1460 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1462 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_GREATEREQ, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1466 static void rvm_op_elesseq(rvmcpu_t *cpu, rvm_asmins_t *ins)
1468 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1469 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1471 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LESSEQ, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1475 static void rvm_op_eless(rvmcpu_t *cpu, rvm_asmins_t *ins)
1477 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1478 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1480 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LESS, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1484 static void rvm_op_ecmp(rvmcpu_t *cpu, rvm_asmins_t *ins)
1486 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1487 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1489 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CMP, cpu, NULL, arg1, arg2);
1493 static void rvm_op_ecmn(rvmcpu_t *cpu, rvm_asmins_t *ins)
1495 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1496 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1498 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CMN, cpu, NULL, arg1, arg2);
1502 static void rvm_op_allocstr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1504 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1505 rstring_t *s = r_string_create_strsize((const char*)RVM_CPUREG_GETP(cpu, ins->op2), (unsigned long)RVM_CPUREG_GETU(cpu, ins->op3));
1507 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1509 r_gc_add(cpu->gc, (robject_t*)s);
1510 rvm_reg_setstring(arg1, s);
1514 static void rvm_op_mapalloc(rvmcpu_t *cpu, rvm_asmins_t *ins)
1516 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1517 rmap_t *a = r_map_create(sizeof(rvmreg_t), 7);
1519 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1521 r_gc_add(cpu->gc, (robject_t*)a);
1522 rvm_reg_setjsobject(arg1, (robject_t*)a);
1526 static void rvm_op_allocarr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1528 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1529 ruword size = RVM_CPUREG_GETU(cpu, ins->op2);
1530 rcarray_t *a = r_carray_create_rvmreg();
1532 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1534 r_carray_setlength(a, (unsigned long)size);
1535 r_gc_add(cpu->gc, (robject_t*)a);
1536 rvm_reg_setarray(arg1, (robject_t*)a);
1540 static void rvm_op_maplookup(rvmcpu_t *cpu, rvm_asmins_t *ins)
1543 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1544 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1545 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1546 rmap_t *a = (rmap_t*)RVM_REG_GETP(arg2);
1548 if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT) {
1549 RVM_ABORT(cpu, RVM_E_NOTOBJECT);
1551 if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_SINGED || RVM_REG_GETTYPE(arg3) == RVM_DTYPE_UNSIGNED) {
1552 index = r_map_lookup_l(a, -1, (long)RVM_REG_GETL(arg3));
1553 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_DOUBLE) {
1554 index = r_map_lookup_d(a, -1, RVM_REG_GETD(arg3));
1555 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_STRING) {
1556 index = r_map_lookup(a, -1, ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.str, ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.size);
1557 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_POINTER) {
1558 index = r_map_lookup(a, -1, (char*)RVM_CPUREG_GETP(cpu, ins->op3), (unsigned int)RVM_CPUREG_GETL(cpu, ins->op1));
1560 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1563 RVM_REG_CLEAR(arg1);
1564 RVM_REG_SETTYPE(arg1, RVM_DTYPE_SINGED);
1565 RVM_REG_SETL(arg1, index);
1569 static void rvm_op_mapadd(rvmcpu_t *cpu, rvm_asmins_t *ins)
1572 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1573 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1574 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1575 rmap_t *a = (rmap_t*)RVM_REG_GETP(arg2);
1577 if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT) {
1578 RVM_ABORT(cpu, RVM_E_NOTOBJECT);
1580 if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_SINGED || RVM_REG_GETTYPE(arg3) == RVM_DTYPE_UNSIGNED) {
1581 index = r_map_gckey_add_l(a, cpu->gc, (long)RVM_REG_GETL(arg3), NULL);
1582 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_DOUBLE) {
1583 index = r_map_gckey_add_d(a, cpu->gc, RVM_REG_GETD(arg3), NULL);
1584 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_STRING) {
1585 index = r_map_gckey_add(a, cpu->gc, ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.str, ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.size, NULL);
1586 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_POINTER) {
1587 index = r_map_gckey_add(a, cpu->gc, (char*)RVM_CPUREG_GETP(cpu, ins->op3), (unsigned int)RVM_CPUREG_GETL(cpu, ins->op1), NULL);
1589 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1592 RVM_REG_CLEAR(arg1);
1593 RVM_REG_SETTYPE(arg1, RVM_DTYPE_SINGED);
1594 RVM_REG_SETL(arg1, index);
1598 static void rvm_op_maplookupadd(rvmcpu_t *cpu, rvm_asmins_t *ins)
1601 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1602 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1603 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1604 rmap_t *a = (rmap_t*)RVM_REG_GETP(arg2);
1606 if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT) {
1607 RVM_ABORT(cpu, RVM_E_NOTOBJECT);
1609 if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_SINGED || RVM_REG_GETTYPE(arg3) == RVM_DTYPE_UNSIGNED) {
1610 index = r_map_lookup_l(a, -1, (long)RVM_REG_GETL(arg3));
1612 index = r_map_gckey_add_l(a, cpu->gc, (long)RVM_REG_GETL(arg3), NULL);
1613 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_DOUBLE) {
1614 index = r_map_lookup_d(a, -1, RVM_REG_GETD(arg3));
1616 index = r_map_gckey_add_d(a, cpu->gc, RVM_REG_GETD(arg3), NULL);
1617 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_STRING) {
1618 index = r_map_lookup(a, -1, ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.str, ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.size);
1620 index = r_map_gckey_add(a, cpu->gc, ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.str, ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.size, NULL);
1621 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_POINTER) {
1622 index = r_map_lookup(a, -1, (char*)RVM_CPUREG_GETP(cpu, ins->op3), (unsigned int)RVM_CPUREG_GETL(cpu, ins->op1));
1624 index = r_map_gckey_add(a, cpu->gc, (char*)RVM_CPUREG_GETP(cpu, ins->op3), (unsigned int)RVM_CPUREG_GETL(cpu, ins->op1), NULL);
1626 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1628 RVM_REG_CLEAR(arg1);
1629 RVM_REG_SETTYPE(arg1, RVM_DTYPE_SINGED);
1630 RVM_REG_SETL(arg1, index);
1634 static void rvm_op_mapaddr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1636 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1637 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1638 rvmreg_t tmp = rvm_reg_create_signed(0);
1643 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, &tmp, RVM_CPUREG_PTR(cpu, ins->op3), &tmp);
1644 index = (long)RVM_REG_GETL(&tmp);
1645 if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT)
1646 RVM_ABORT(cpu, RVM_E_NOTOBJECT);
1647 a = (rmap_t*)RVM_REG_GETP(arg2);
1648 value = r_map_value(a, index);
1650 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1651 RVM_REG_CLEAR(arg1);
1652 RVM_REG_SETTYPE(arg1, RVM_DTYPE_POINTER);
1653 RVM_REG_SETP(arg1, value);
1657 static void rvm_op_mapldr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1659 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1660 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1661 rvmreg_t tmp = rvm_reg_create_signed(0);
1666 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, &tmp, RVM_CPUREG_PTR(cpu, ins->op3), &tmp);
1667 index = (long)RVM_REG_GETL(&tmp);
1668 if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT)
1669 RVM_ABORT(cpu, RVM_E_NOTOBJECT);
1670 a = (rmap_t*)RVM_REG_GETP(arg2);
1671 value = r_map_value(a, index);
1673 RVM_REG_CLEAR(arg1);
1674 RVM_REG_SETTYPE(arg1, RVM_DTYPE_UNDEF);
1676 *arg1 = *((rvmreg_t*)value);
1681 static void rvm_op_mapstr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1683 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1684 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1685 rvmreg_t tmp = rvm_reg_create_signed(0);
1690 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, &tmp, RVM_CPUREG_PTR(cpu, ins->op3), &tmp);
1691 index = (long)RVM_REG_GETL(&tmp);
1692 if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT)
1693 RVM_ABORT(cpu, RVM_E_NOTOBJECT);
1694 a = (rmap_t*)RVM_REG_GETP(arg2);
1695 value = r_map_value(a, index);
1697 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1698 r_map_setvalue(a, index, arg1);
1702 static void rvm_op_addra(rvmcpu_t *cpu, rvm_asmins_t *ins)
1704 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1705 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1706 rvmreg_t tmp = rvm_reg_create_signed(0);
1707 rcarray_t *a = RVM_REG_GETP(arg2);
1710 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, &tmp, RVM_CPUREG_PTR(cpu, ins->op3), &tmp);
1711 index = (long)RVM_REG_GETL(&tmp);
1713 if (rvm_reg_gettype(arg2) != RVM_DTYPE_ARRAY || index < 0) {
1714 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1716 RVM_REG_CLEAR(arg1);
1717 RVM_REG_SETTYPE(arg1, RVM_DTYPE_POINTER);
1718 RVM_REG_SETP(arg1, r_carray_slot_expand(a, index));
1722 static void rvm_op_lda(rvmcpu_t *cpu, rvm_asmins_t *ins)
1724 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1725 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1726 ruword index = RVM_CPUREG_GETU(cpu, ins->op3);
1727 rcarray_t *a = RVM_REG_GETP(arg2);
1729 if (rvm_reg_gettype(arg2) != RVM_DTYPE_ARRAY) {
1730 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1732 *arg1 = *((rvmreg_t*)r_carray_slot_expand(a, (unsigned long)index));
1736 static void rvm_op_sta(rvmcpu_t *cpu, rvm_asmins_t *ins)
1738 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1739 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1740 ruword index = RVM_CPUREG_GETU(cpu, ins->op3);
1741 rcarray_t *a = RVM_REG_GETP(arg2);
1743 if (rvm_reg_gettype(arg2) != RVM_DTYPE_ARRAY) {
1744 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1746 r_carray_replace(a, (unsigned long)index, arg1);
1750 static void rvm_op_abort(rvmcpu_t *cpu, rvm_asmins_t *ins)
1752 RVM_ABORT(cpu, RVM_CPUREG_GETU(cpu, ins->op1));
1756 static rvm_cpu_op ops[] = {
1757 rvm_op_exit, // RVM_EXT
1758 rvm_op_abort, // RVM_ABORT
1759 rvm_op_prn, // RVM_PRN
1760 rvm_op_asr, // RVM_ASR
1761 rvm_op_swi, // RVM_SWI
1762 rvm_op_swiid, // RVM_SWIID
1763 rvm_op_call, // RVM_CALL
1764 rvm_op_mov, // RVM_MOV
1765 rvm_op_movs, // RVM_MOVS
1766 rvm_op_swp, // RVM_SWP
1767 rvm_op_inc, // RVM_INC
1768 rvm_op_dec, // RVM_DEC
1769 rvm_op_add, // RVM_ADD
1770 rvm_op_adds, // RVM_ADDS
1771 rvm_op_adc, // RVM_ADC
1772 rvm_op_and, // RVM_AND
1773 rvm_op_bic, // RVM_BIC
1774 rvm_op_clz, // RVM_CLZ
1775 rvm_op_cmn, // RVM_CMN
1776 rvm_op_xor, // RVM_XOR
1777 rvm_op_sub, // RVM_SUB
1778 rvm_op_subs, // RVM_SUBS
1779 rvm_op_sbc, // RVM_SBC
1780 rvm_op_mul, // RVM_MUL
1781 rvm_op_mls, // RVM_MLS
1782 rvm_op_muls, // RVM_MULS
1783 rvm_op_not, // RVM_NOT
1784 rvm_op_div, // RVM_DIV
1785 rvm_op_dvs, // RVM_DVS
1786 rvm_op_divs, // RVM_DIVS
1787 rvm_op_mod, // RVM_MOD
1788 rvm_op_mods, // RVM_MODS
1789 rvm_op_bx, // RVM_BX
1790 rvm_op_bxeq, // RVM_BXEQ
1791 rvm_op_bxneq, // RVM_BXNEQ
1792 rvm_op_bxleq, // RVM_BXLEQ
1793 rvm_op_bxgeq, // RVM_BXGEQ
1794 rvm_op_bxles, // RVM_BXLES
1795 rvm_op_bxgre, // RVM_BXGRE
1796 rvm_op_bxl, // RVM_BXL
1797 rvm_op_bl, // RVM_BL
1799 rvm_op_str, // RVM_STR
1800 rvm_op_strp, // RVM_STRP
1801 rvm_op_strb, // RVM_STRB
1802 rvm_op_strh, // RVM_STRH
1803 rvm_op_strw, // RVM_STRW
1804 rvm_op_strr, // RVM_STRR
1805 rvm_op_ldr, // RVM_LDR
1806 rvm_op_ldrp, // RVM_LDRP
1807 rvm_op_ldrb, // RVM_LDRB
1808 rvm_op_ldrh, // RVM_LDRH
1809 rvm_op_ldrw, // RVM_LDRW
1810 rvm_op_ldrr, // RVM_LDRR
1811 rvm_op_cflag, // RVM_CFLAG
1812 rvm_op_clr, // RVM_CLR
1813 rvm_op_clrr, // RVM_CLRR
1814 rvm_op_lsl, // RVM_LSL
1815 rvm_op_lsr, // RVM_LSR
1816 rvm_op_lsrs, // RVM_LSRS
1817 rvm_op_stm, // RVM_STM
1818 rvm_op_ldm, // RVM_LDM
1819 rvm_op_sts, // RVM_STS
1820 rvm_op_lds, // RVM_LDS
1821 rvm_op_orr, // RVM_ORR
1822 rvm_op_push, // RVM_PUSH
1823 rvm_op_pop, // RVM_POP
1824 rvm_op_cmp, // RVM_CMP
1825 rvm_op_nop, // RVM_NOP
1826 rvm_op_beq, // RVM_BEQ
1827 rvm_op_bneq, // RVM_BNEQ
1828 rvm_op_bleq, // RVM_BLEQ
1829 rvm_op_bgeq, // RVM_BGEQ
1830 rvm_op_bles, // RVM_BLES
1831 rvm_op_bgre, // RVM_BGRE
1832 rvm_op_ret, // RVM_RET
1833 rvm_op_ror, // RVM_ROR
1834 rvm_op_pushm, // RVM_PUSHM
1835 rvm_op_popm, // RVM_POPM
1836 rvm_op_tst, // RVM_TST
1837 rvm_op_teq, // RVM_TEQ
1838 rvm_op_addrs, // RVM_ADDRS
1840 /* Extended VM instructions */
1841 rvm_op_cast, // RVM_CAST
1842 rvm_op_type, // RVM_TYPE
1843 rvm_op_settype, // RVM_SETTYPE
1844 rvm_op_emov, // RVM_EMOV
1845 rvm_op_eneg, // RVM_ENEG
1846 rvm_op_eadd, // RVM_EADD
1847 rvm_op_esub, // RVM_ESUB
1848 rvm_op_emul, // RVM_EMUL
1849 rvm_op_ediv, // RVM_EDIV
1850 rvm_op_emod, // RVM_MOD
1851 rvm_op_elsl, // RVM_ELSL
1852 rvm_op_elsr, // RVM_ELSR
1853 rvm_op_elsru, // RVM_ELSRU
1854 rvm_op_eand, // RVM_EAND
1855 rvm_op_eorr, // RVM_EORR
1856 rvm_op_exor, // RVM_EXOR
1857 rvm_op_enot, // RVM_ENOT
1859 rvm_op_eland, // RVM_ELAND
1860 rvm_op_elor, // RVM_ELOR
1861 rvm_op_elnot, // RVM_ELNOT
1862 rvm_op_eeq, // RVM_EEQ
1863 rvm_op_enoteq, // RVM_ENOTEQ
1864 rvm_op_egreat, // RVM_EGREAT
1865 rvm_op_egreateq, // RVM_EGREATEQ
1866 rvm_op_eless, // RVM_ELESS
1867 rvm_op_elesseq, // RVM_ELESSEQ
1868 rvm_op_ecmp, // RVM_ECMP
1869 rvm_op_ecmn, // RVM_ECMN
1870 rvm_op_allocstr, // RVM_ALLOCSTR
1871 rvm_op_allocarr, // RVM_ALLOCARR
1872 rvm_op_addra, // RVM_ADDRA
1873 rvm_op_lda, // RVM_LDA
1874 rvm_op_sta, // RVM_STA
1875 rvm_op_mapalloc, // RVM_MAPALLOC
1876 rvm_op_mapaddr, // RVM_MAPADDR,
1877 rvm_op_mapldr, // RVM_MAPLDR,
1878 rvm_op_mapstr, // RVM_MAPSTR,
1879 rvm_op_maplookup, // RVM_MAPLKUP,
1880 rvm_op_mapadd, // RVM_MAPADD,
1881 rvm_op_maplookupadd,// RVM_MAPLKUPADD,
1894 rvmcpu_t *rvm_cpu_create(unsigned long stacksize)
1898 cpu = (rvmcpu_t *)r_malloc(sizeof(*cpu));
1901 r_memset(cpu, 0, sizeof(*cpu));
1902 cpu->stacksize = stacksize;
1903 cpu->switables = r_harray_create(sizeof(rvm_switable_t*));
1904 cpu->stack = r_malloc(stacksize * sizeof(rvmreg_t));
1905 cpu->data = r_carray_create(sizeof(rvmreg_t));
1906 cpu->opmap = rvm_opmap_create();
1907 cpu->gc = r_gc_create();
1908 rvm_op_binary_init(cpu->opmap);
1909 rvm_op_cast_init(cpu->opmap);
1910 rvm_op_not_init(cpu->opmap);
1911 rvm_op_logicnot_init(cpu->opmap);
1917 rvmcpu_t *rvm_cpu_create_default()
1919 return rvm_cpu_create(RVM_DEFAULT_STACKSIZE);
1923 void rvm_cpu_destroy(rvmcpu_t *cpu)
1925 r_gc_deallocateall(cpu->gc);
1926 r_gc_destroy(cpu->gc);
1927 r_object_destroy((robject_t*)cpu->switables);
1929 r_object_destroy((robject_t*)cpu->data);
1930 rvm_opmap_destroy(cpu->opmap);
1935 int rvm_cpu_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, ruword off)
1938 rvmreg_t *regda = RVM_CPUREG_PTR(cpu, DA);
1939 rvmreg_t *regpc = RVM_CPUREG_PTR(cpu, PC);
1941 RVM_CPUREG_SETIP(cpu, PC, prog + off);
1945 pi = RVM_REG_GETIP(regpc);
1949 #if RVM_CONDITIONAL_INSTRUCTIONS
1953 if (!((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0))
1957 if (!((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1))
1961 if (!((cpu->status & RVM_STATUS_Z)))
1965 if (!((cpu->status & RVM_STATUS_Z) == 0))
1969 if (!((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z)))
1973 if (!((cpu->status & RVM_STATUS_N)))
1981 ops[pi->opcode](cpu, pi);
1982 #if RVM_CONDITIONAL_INSTRUCTIONS
1985 RVM_REG_INCIP(regpc, 1);
1986 } while (!cpu->abort);
1993 int rvm_cpu_exec_debug(rvmcpu_t *cpu, rvm_asmins_t *prog, ruword off)
1997 rvmreg_t *regda = RVM_CPUREG_PTR(cpu, DA);
1998 rvmreg_t *regpc = RVM_CPUREG_PTR(cpu, PC);
2000 RVM_CPUREG_SETIP(cpu, PC, prog + off);
2004 pi = RVM_REG_GETIP(regpc);
2008 #if RVM_CONDITIONAL_INSTRUCTIONS
2012 if (!((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0))
2016 if (!((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1))
2020 if (!((cpu->status & RVM_STATUS_Z)))
2024 if (!((cpu->status & RVM_STATUS_Z) == 0))
2028 if (!((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z)))
2032 if (!((cpu->status & RVM_STATUS_N)))
2040 ops[pi->opcode](cpu, pi);
2041 r_printf("%7ld :", ++line);
2042 rvm_cpu_dumpregs(cpu, pi);
2043 #if RVM_CONDITIONAL_INSTRUCTIONS
2046 RVM_REG_INCIP(regpc, 1);
2047 } while (!cpu->abort);
2054 int rvm_cpu_global_swilookup(rvmcpu_t *cpu, const char *swiname, unsigned long size)
2057 rvm_switable_t *swientry;
2058 unsigned long ntable;
2060 for (ntable = 0; ntable < r_harray_length(cpu->switables); ntable++) {
2061 swientry = r_harray_index(cpu->switables, ntable, rvm_switable_t*);
2064 for (nswi = 0; swientry[nswi].name; nswi++) {
2065 if (r_strncmp(swientry[nswi].name, swiname, size) == 0 && r_strlen(swientry[nswi].name) == size)
2066 return (int)RVM_SWI_ID(ntable, nswi);
2073 int rvm_cpu_table_swilookup(rvmcpu_t *cpu, const char *tabname, const char *swiname, unsigned long size)
2076 rvm_switable_t *swientry;
2077 long ntable = r_harray_lookup_s(cpu->switables, tabname);
2081 swientry = r_harray_index(cpu->switables, ntable, rvm_switable_t*);
2084 for (nswi = 0; swientry[nswi].name; nswi++) {
2085 if (r_strncmp(swientry[nswi].name, swiname, size) == 0 && r_strlen(swientry[nswi].name) == size)
2086 return (int)RVM_SWI_ID(ntable, nswi);
2092 int rvm_cpu_swilookup(rvmcpu_t *cpu, const char *tabname, const char *swiname, unsigned long size)
2094 return tabname ? rvm_cpu_table_swilookup(cpu, tabname, swiname, size) : rvm_cpu_global_swilookup(cpu, swiname, size);
2098 int rvm_cpu_swilookup_s(rvmcpu_t *cpu, const char *tabname, const char *swiname)
2100 return rvm_cpu_swilookup(cpu, tabname, swiname, r_strlen(swiname));
2104 int rvm_cpu_addswitable(rvmcpu_t *cpu, const char *tabname, rvm_switable_t *switable)
2106 return r_harray_replace_s(cpu->switables, tabname, &switable);
2110 int rvm_cpu_abort(rvmcpu_t *cpu)
2114 cpu->error = RVM_E_USERABORT;
2120 rvm_asmins_t rvm_cond_asma(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, char *data, unsigned long size)
2124 r_memset(&a, 0, sizeof(a));
2125 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2126 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2127 a.op1 = (ruint8)op1;
2128 a.op2 = (ruint8)op2;
2129 a.op3 = (ruint8)op3;
2130 a.cond = (ruint8)cond;
2131 rvm_reg_setstrptr(&a.data, data, size);
2132 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2138 rvm_asmins_t rvm_asma(ruword opcode, ruword op1, ruword op2, ruword op3, char *data, unsigned long size)
2140 return rvm_cond_asma(0, opcode, op1, op2, op3, data, size);
2144 rvm_asmins_t rvm_cond_asmp(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, rpointer data)
2148 r_memset(&a, 0, sizeof(a));
2149 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2150 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2151 a.op1 = (ruint8)op1;
2152 a.op2 = (ruint8)op2;
2153 a.op3 = (ruint8)op3;
2154 a.cond = (ruint8)cond;
2155 rvm_reg_setpointer(&a.data, data);
2156 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2162 rvm_asmins_t rvm_asmp(ruword opcode, ruword op1, ruword op2, ruword op3, rpointer data)
2164 return rvm_cond_asmp(0, opcode, op1, op2, op3, data);
2168 rvm_asmins_t rvm_cond_asms(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, ruword data)
2172 r_memset(&a, 0, sizeof(a));
2173 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2174 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2175 a.op1 = (ruint8)op1;
2176 a.op2 = (ruint8)op2;
2177 a.op3 = (ruint8)op3;
2178 a.cond = (ruint8)cond;
2179 rvm_reg_setunsigned(&a.data, data);
2180 RVM_REG_SETTYPE(&a.data, RVM_DTYPE_SWIID)
2181 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2187 rvm_asmins_t rvm_asms(ruword opcode, ruword op1, ruword op2, ruword op3, ruword data)
2189 return rvm_cond_asms(0, opcode, op1, op2, op3, data);
2193 rvm_asmins_t rvm_cond_asmf(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, ruword data)
2197 r_memset(&a, 0, sizeof(a));
2198 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2199 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2200 a.op1 = (ruint8)op1;
2201 a.op2 = (ruint8)op2;
2202 a.op3 = (ruint8)op3;
2203 a.cond = (ruint8)cond;
2204 rvm_reg_setunsigned(&a.data, data);
2205 RVM_REG_SETTYPE(&a.data, RVM_DTYPE_FUNCTION)
2206 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2211 rvm_asmins_t rvm_asmf(ruword opcode, ruword op1, ruword op2, ruword op3, ruword data)
2213 return rvm_cond_asmf(0, opcode, op1, op2, op3, data);
2217 rvm_asmins_t rvm_cond_asm(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, ruword data)
2221 r_memset(&a, 0, sizeof(a));
2222 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2223 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2224 a.op1 = (ruint8)op1;
2225 a.op2 = (ruint8)op2;
2226 a.op3 = (ruint8)op3;
2227 a.cond = (ruint8)cond;
2228 rvm_reg_setunsigned(&a.data, data);
2229 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2235 rvm_asmins_t rvm_asm(ruword opcode, ruword op1, ruword op2, ruword op3, ruword data)
2237 return rvm_cond_asm(0, opcode, op1, op2, op3, data);
2242 rvm_asmins_t rvm_cond_asml(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, long data)
2246 r_memset(&a, 0, sizeof(a));
2247 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2248 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2249 a.op1 = (ruint8)op1;
2250 a.op2 = (ruint8)op2;
2251 a.op3 = (ruint8)op3;
2252 a.cond = (ruint8)cond;
2253 rvm_reg_setsigned(&a.data, data);
2254 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2260 rvm_asmins_t rvm_asml(ruword opcode, ruword op1, ruword op2, ruword op3, long data)
2262 return rvm_cond_asml(0, opcode, op1, op2, op3, data);
2266 rvm_asmins_t rvm_cond_asmb(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, unsigned int data)
2270 r_memset(&a, 0, sizeof(a));
2271 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2272 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2273 a.op1 = (ruint8)op1;
2274 a.op2 = (ruint8)op2;
2275 a.op3 = (ruint8)op3;
2276 a.cond = (ruint8)cond;
2277 rvm_reg_setboolean(&a.data, data);
2278 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2284 rvm_asmins_t rvm_asmb(ruword opcode, ruword op1, ruword op2, ruword op3, unsigned int data)
2286 return rvm_cond_asmb(0, opcode, op1, op2, op3, data);
2290 rvm_asmins_t rvm_cond_asmd(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, double data)
2294 r_memset(&a, 0, sizeof(a));
2295 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2296 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2297 a.op1 = (ruint8)op1;
2298 a.op2 = (ruint8)op2;
2299 a.op3 = (ruint8)op3;
2300 a.cond = (ruint8)cond;
2301 rvm_reg_setdouble(&a.data, data);
2302 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2307 rvm_asmins_t rvm_asmd(ruword opcode, ruword op1, ruword op2, ruword op3, double data)
2309 return rvm_cond_asmd(0, opcode, op1, op2, op3, data);
2313 rvm_asmins_t rvm_cond_asm2(ruword cond, ruword opcode, ruword op1, ruword op2, ruword op3, ruint32 p1, ruint32 p2)
2317 r_memset(&a, 0, sizeof(a));
2318 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2319 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2320 a.op1 = (ruint8)op1;
2321 a.op2 = (ruint8)op2;
2322 a.op3 = (ruint8)op3;
2323 a.cond = (ruint8)cond;
2324 rvm_reg_setpair(&a.data, p1, p2);
2325 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2331 rvm_asmins_t rvm_asm2(ruword opcode, ruword op1, ruword op2, ruword op3, ruint32 p1, ruint32 p2)
2333 return rvm_cond_asm2(0, opcode, op1, op2, op3, p1, p2);
2336 rvmreg_t *rvm_cpu_alloc_global(rvmcpu_t *cpu)
2339 int index = r_carray_add(cpu->data, NULL);
2341 global = (rvmreg_t*)r_carray_slot(cpu->data, index);
2342 RVM_REG_CLEAR(global);
2343 RVM_REG_SETTYPE(global, RVM_DTYPE_UNDEF);
2348 int rvm_cpu_setreg(rvmcpu_t *cpu, ruword regnum, const rvmreg_t *src)
2352 RVM_CPUREG_SET(cpu, regnum, *src);
2357 rvmreg_t *rvm_cpu_getreg(rvmcpu_t *cpu, ruword regnum)
2361 return RVM_CPUREG_PTR(cpu, regnum);