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>
24 #include "rvmoperator.h"
25 #include "rvmoperatorbin.h"
26 #include "rvmoperatorcast.h"
27 #include "rvmoperatornot.h"
28 #include "rvmoperatorlogicnot.h"
29 #include "rvmcodemap.h"
34 #include "rjsobject.h"
36 #define RVM_DEFAULT_STACKSIZE (4 * 1024)
38 static const char *stropcalls[] = {
122 "RVM_CAST", /* Cast: op1 = (op3)op2 */
123 "RVM_TYPE", /* Type: op1 = typeof(op2) */
124 "RVM_SETTYPE", /* Type: op1.type = op2 */
176 static void rvm_op_b(rvmcpu_t *cpu, rvm_asmins_t *ins)
180 // if (ins->op1 != XX)
181 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
182 // if (ins->op2 != XX)
183 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
184 // if (ins->op3 != XX)
185 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
186 pc += RVM_CPUREG_GETU(cpu, ins->op1);
187 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
191 static void rvm_op_beq(rvmcpu_t *cpu, rvm_asmins_t *ins)
195 if ((cpu->status & RVM_STATUS_Z)) {
196 // if (ins->op1 != XX)
197 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
198 // if (ins->op2 != XX)
199 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
200 // if (ins->op3 != XX)
201 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
202 pc += RVM_CPUREG_GETU(cpu, ins->op1);
203 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
208 static void rvm_op_bneq(rvmcpu_t *cpu, rvm_asmins_t *ins)
212 if ((cpu->status & RVM_STATUS_Z) == 0) {
213 // if (ins->op1 != XX)
214 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
215 // if (ins->op2 != XX)
216 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
217 // if (ins->op3 != XX)
218 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
219 pc += RVM_CPUREG_GETU(cpu, ins->op1);
220 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
225 static void rvm_op_bleq(rvmcpu_t *cpu, rvm_asmins_t *ins)
229 if ((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z)) {
230 // if (ins->op1 != XX)
231 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
232 // if (ins->op2 != XX)
233 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
234 // if (ins->op3 != XX)
235 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
236 pc += RVM_CPUREG_GETU(cpu, ins->op1);
237 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
241 static void rvm_op_bgeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
245 if ((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1) {
246 // if (ins->op1 != XX)
247 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
248 // if (ins->op2 != XX)
249 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
250 // if (ins->op3 != XX)
251 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
252 pc += RVM_CPUREG_GETU(cpu, ins->op1);
253 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
258 static void rvm_op_bles(rvmcpu_t *cpu, rvm_asmins_t *ins)
263 if ((cpu->status & RVM_STATUS_N)) {
264 // if (ins->op1 != XX)
265 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
266 // if (ins->op2 != XX)
267 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
268 // if (ins->op3 != XX)
269 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
270 pc += RVM_CPUREG_GETU(cpu, ins->op1);
271 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
276 static void rvm_op_bgre(rvmcpu_t *cpu, rvm_asmins_t *ins)
280 if ((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0) {
281 // if (ins->op1 != XX)
282 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
283 // if (ins->op2 != XX)
284 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
285 // if (ins->op3 != XX)
286 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
287 pc += RVM_CPUREG_GETU(cpu, ins->op1);
288 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
293 static void rvm_op_bx(rvmcpu_t *cpu, rvm_asmins_t *ins)
295 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
299 static void rvm_op_bxleq(rvmcpu_t *cpu, rvm_asmins_t *ins)
301 if ((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z)) {
302 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
307 static void rvm_op_bxgeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
309 if ((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1){
310 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
315 static void rvm_op_bxles(rvmcpu_t *cpu, rvm_asmins_t *ins)
317 if ((cpu->status & RVM_STATUS_N)) {
318 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
323 static void rvm_op_bxgre(rvmcpu_t *cpu, rvm_asmins_t *ins)
325 if ((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0) {
326 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
331 static void rvm_op_bxeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
333 if ((cpu->status & RVM_STATUS_Z)) {
334 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
339 static void rvm_op_bxneq(rvmcpu_t *cpu, rvm_asmins_t *ins)
341 if (!(cpu->status & RVM_STATUS_Z)) {
342 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
347 static void rvm_op_bxl(rvmcpu_t *cpu, rvm_asmins_t *ins)
349 RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
350 RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
354 static void rvm_op_bl(rvmcpu_t *cpu, rvm_asmins_t *ins)
358 // if (ins->op1 != XX)
359 // pc += RVM_CPUREG_GETU(cpu, ins->op1);
360 // if (ins->op2 != XX)
361 // pc += RVM_CPUREG_GETU(cpu, ins->op2);
362 // if (ins->op3 != XX)
363 // pc += RVM_CPUREG_GETU(cpu, ins->op3);
364 pc += RVM_CPUREG_GETU(cpu, ins->op1);
365 RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
366 RVM_CPUREG_INCIP(cpu, PC, pc - 1);
370 static void rvm_op_exit(rvmcpu_t *cpu, rvm_asmins_t *ins)
376 static void rvm_op_mov(rvmcpu_t *cpu, rvm_asmins_t *ins)
378 RVM_CPUREG_SET(cpu, ins->op1, RVM_CPUREG_GET(cpu, ins->op2));
382 static void rvm_op_movs(rvmcpu_t *cpu, rvm_asmins_t *ins)
384 rword op2 = RVM_CPUREG_GETU(cpu, ins->op2);;
386 RVM_CPUREG_SETU(cpu, ins->op1, op2);
387 RVM_STATUS_CLRALL(cpu);
388 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !op2);
389 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, op2 & RVM_SIGN_BIT);
393 static void rvm_op_swp(rvmcpu_t *cpu, rvm_asmins_t *ins)
395 rvmreg_t tmp = RVM_CPUREG_GET(cpu, ins->op1);
396 RVM_CPUREG_SET(cpu, ins->op1, RVM_CPUREG_GET(cpu, ins->op2));
397 RVM_CPUREG_SET(cpu, ins->op2, tmp);
401 static void rvm_op_ldr(rvmcpu_t *cpu, rvm_asmins_t *ins)
403 RVM_CPUREG_SETU(cpu, ins->op1, *((rword*)RVM_CPUREG_GETU(cpu, ins->op2)));
408 static void rvm_op_ldrp(rvmcpu_t *cpu, rvm_asmins_t *ins)
410 RVM_CPUREG_SETU(cpu, ins->op1, *((rpointer*)RVM_CPUREG_GETU(cpu, ins->op2)));
414 static void rvm_op_ldrb(rvmcpu_t *cpu, rvm_asmins_t *ins)
416 RVM_CPUREG_SETU(cpu, ins->op1, *((ruint8*)RVM_CPUREG_GETU(cpu, ins->op2)));
420 static void rvm_op_ldrh(rvmcpu_t *cpu, rvm_asmins_t *ins)
422 RVM_CPUREG_SETU(cpu, ins->op1, *((ruint16*)RVM_CPUREG_GETU(cpu, ins->op2)));
426 static void rvm_op_ldrw(rvmcpu_t *cpu, rvm_asmins_t *ins)
428 RVM_CPUREG_SETU(cpu, ins->op1, *((ruint32*)RVM_CPUREG_GETU(cpu, ins->op2)));
432 static void rvm_op_ldrr(rvmcpu_t *cpu, rvm_asmins_t *ins)
434 RVM_CPUREG_SET(cpu, ins->op1, *((rvmreg_t*)RVM_CPUREG_GETU(cpu, ins->op2)));
438 static void rvm_op_clr(rvmcpu_t *cpu, rvm_asmins_t *ins)
440 RVM_REG_CLEAR(((rvmreg_t*)RVM_CPUREG_PTR(cpu, ins->op1)));
441 RVM_REG_SETTYPE(((rvmreg_t*)RVM_CPUREG_PTR(cpu, ins->op1)), RVM_DTYPE_UNDEF);
445 static void rvm_op_cflag(rvmcpu_t *cpu, rvm_asmins_t *ins)
447 rword op1 = RVM_CPUREG_GETU(cpu, ins->op1);
448 RVM_STATUS_CLRBIT(cpu, op1);
452 static void rvm_op_clrr(rvmcpu_t *cpu, rvm_asmins_t *ins)
454 RVM_REG_CLEAR(((rvmreg_t*)RVM_CPUREG_GETP(cpu, ins->op1)));
455 RVM_REG_SETTYPE(((rvmreg_t*)RVM_CPUREG_GETP(cpu, ins->op1)), RVM_DTYPE_UNDEF);
459 static void rvm_op_str(rvmcpu_t *cpu, rvm_asmins_t *ins)
461 *((rword*)RVM_CPUREG_GETP(cpu, ins->op2)) = RVM_CPUREG_GETU(cpu, ins->op1);
465 static void rvm_op_strp(rvmcpu_t *cpu, rvm_asmins_t *ins)
467 *((rpointer*)RVM_CPUREG_GETP(cpu, ins->op2)) = (rpointer)RVM_CPUREG_GETP(cpu, ins->op1);
471 static void rvm_op_strb(rvmcpu_t *cpu, rvm_asmins_t *ins)
473 *((ruint8*)RVM_CPUREG_GETP(cpu, ins->op2)) = (ruint8)RVM_CPUREG_GETU(cpu, ins->op1);
477 static void rvm_op_strh(rvmcpu_t *cpu, rvm_asmins_t *ins)
479 *((ruint16*)RVM_CPUREG_GETP(cpu, ins->op2)) = (ruint16)RVM_CPUREG_GETU(cpu, ins->op1);
484 static void rvm_op_strw(rvmcpu_t *cpu, rvm_asmins_t *ins)
486 *((ruint32*)RVM_CPUREG_GETP(cpu, ins->op2)) = (ruint32)RVM_CPUREG_GETU(cpu, ins->op1);
491 static void rvm_op_strr(rvmcpu_t *cpu, rvm_asmins_t *ins)
493 rvmreg_t *dest = RVM_CPUREG_PTR(cpu, ins->op2);
494 if (RVM_REG_GETTYPE(dest) != RVM_DTYPE_POINTER)
495 RVM_ABORT(cpu, RVM_E_LVALUE);
497 *((rvmreg_t*)RVM_REG_GETP(dest)) = RVM_CPUREG_GET(cpu, ins->op1);
501 static void rvm_op_adds(rvmcpu_t *cpu, rvm_asmins_t *ins)
503 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
506 RVM_CPUREG_SETU(cpu, ins->op1, res);
507 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, res < op2 || res < op3);
508 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
509 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
510 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op2 & RVM_SIGN_BIT) == (op3 & RVM_SIGN_BIT) &&
511 (res & RVM_SIGN_BIT) != (op2 & RVM_SIGN_BIT));
515 static void rvm_op_adc(rvmcpu_t *cpu, rvm_asmins_t *ins)
517 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
519 res = op2 + op3 + (RVM_STATUS_GETBIT(cpu, RVM_STATUS_C) ? 1 : 0);
520 RVM_CPUREG_SETU(cpu, ins->op1, res);
521 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, res < op2 || res < op3);
522 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
523 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
524 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op2 & RVM_SIGN_BIT) == (op3 & RVM_SIGN_BIT) &&
525 (res & RVM_SIGN_BIT) != (op2 & RVM_SIGN_BIT));
529 static void rvm_op_and(rvmcpu_t *cpu, rvm_asmins_t *ins)
531 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
534 RVM_CPUREG_SETU(cpu, ins->op1, res);
535 RVM_STATUS_CLRALL(cpu);
536 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
537 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
541 static void rvm_op_orr(rvmcpu_t *cpu, rvm_asmins_t *ins)
543 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
546 RVM_CPUREG_SETU(cpu, ins->op1, res);
547 RVM_STATUS_CLRALL(cpu);
548 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
549 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
553 static void rvm_op_lsl(rvmcpu_t *cpu, rvm_asmins_t *ins)
555 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
558 RVM_CPUREG_SETU(cpu, ins->op1, res);
559 RVM_STATUS_CLRALL(cpu);
560 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
561 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
565 static void rvm_op_lsr(rvmcpu_t *cpu, rvm_asmins_t *ins)
567 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
570 RVM_CPUREG_SETU(cpu, ins->op1, res);
571 RVM_STATUS_CLRALL(cpu);
572 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
576 static void rvm_op_lsrs(rvmcpu_t *cpu, rvm_asmins_t *ins)
578 rsword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
580 res = ((rsword)op2) >> op3;
581 RVM_CPUREG_SETU(cpu, ins->op1, res);
582 RVM_STATUS_CLRALL(cpu);
583 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
587 static void rvm_op_asr(rvmcpu_t *cpu, rvm_asmins_t *ins)
589 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
592 res |= op2 & RVM_SIGN_BIT;
593 RVM_CPUREG_SETU(cpu, ins->op1, res);
594 RVM_STATUS_CLRALL(cpu);
595 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
596 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
600 static void rvm_op_ror(rvmcpu_t *cpu, rvm_asmins_t *ins)
603 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
606 for (i = 0; i < op3; i++) {
614 RVM_CPUREG_SETU(cpu, ins->op1, res);
615 RVM_STATUS_CLRALL(cpu);
616 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
617 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
618 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, res & RVM_SIGN_BIT);
622 static void rvm_op_tst(rvmcpu_t *cpu, rvm_asmins_t *ins)
624 rword res, op1 = RVM_CPUREG_GETU(cpu, ins->op1), op2 = RVM_CPUREG_GETU(cpu, ins->op2);
627 RVM_STATUS_CLRALL(cpu);
628 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
629 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
633 static void rvm_op_xor(rvmcpu_t *cpu, rvm_asmins_t *ins)
635 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
638 RVM_CPUREG_SETU(cpu, ins->op1, res);
639 RVM_STATUS_CLRALL(cpu);
640 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
641 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
645 static void rvm_op_not(rvmcpu_t *cpu, rvm_asmins_t *ins)
647 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2);
650 RVM_CPUREG_SETU(cpu, ins->op1, res);
651 RVM_STATUS_CLRALL(cpu);
652 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
653 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
657 static void rvm_op_teq(rvmcpu_t *cpu, rvm_asmins_t *ins)
659 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
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_bic(rvmcpu_t *cpu, rvm_asmins_t *ins)
670 rword 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_Z, !res);
676 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
680 static void rvm_op_clz(rvmcpu_t *cpu, rvm_asmins_t *ins)
682 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2);
684 for (res = RVM_REGISTER_BITS; op2; ) {
688 RVM_CPUREG_SETU(cpu, ins->op1, res);
692 static void rvm_op_add(rvmcpu_t *cpu, rvm_asmins_t *ins)
694 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) + RVM_CPUREG_GETU(cpu, ins->op3));
698 static void rvm_op_inc(rvmcpu_t *cpu, rvm_asmins_t *ins)
700 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op1) + 1);
704 static void rvm_op_dec(rvmcpu_t *cpu, rvm_asmins_t *ins)
706 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op1) - 1);
710 static void rvm_op_swi(rvmcpu_t *cpu, rvm_asmins_t *ins)
713 rvm_switable_t *switable;
714 ruint ntable = (ruint) RVM_SWI_TABLE(ins->swi);
715 ruint nswi = (ruint) RVM_SWI_NUM(ins->swi);
717 if (r_harray_length(cpu->switables) <= ntable)
718 RVM_ABORT(cpu, RVM_E_SWITABLE);
719 switable = r_harray_index(cpu->switables, ntable, rvm_switable_t*);
720 swi = switable[nswi].op;
725 static void rvm_op_swiid(rvmcpu_t *cpu, rvm_asmins_t *ins)
728 rvm_switable_t *switable;
729 ruint ntable = (ruint) RVM_SWI_TABLE(RVM_CPUREG_GETU(cpu, ins->op1));
730 ruint nswi = (ruint) RVM_SWI_NUM(RVM_CPUREG_GETU(cpu, ins->op1));
732 if (r_harray_length(cpu->switables) <= ntable)
733 RVM_ABORT(cpu, RVM_E_SWITABLE);
734 switable = r_harray_index(cpu->switables, ntable, rvm_switable_t*);
735 swi = switable[nswi].op;
740 static void rvm_op_call(rvmcpu_t *cpu, rvm_asmins_t *ins)
742 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
744 if (RVM_REG_GETTYPE(arg1) == RVM_DTYPE_SWIID) {
745 RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
746 rvm_op_swiid(cpu, ins);
747 } else if (RVM_REG_GETTYPE(arg1) == RVM_DTYPE_FUNCTION) {
748 rvm_op_bxl(cpu, ins);
750 RVM_ABORT(cpu, RVM_E_NOTFUNCTION);
755 static void rvm_op_sub(rvmcpu_t *cpu, rvm_asmins_t *ins)
757 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) - RVM_CPUREG_GETU(cpu, ins->op3));
761 static void rvm_op_subs(rvmcpu_t *cpu, rvm_asmins_t *ins)
763 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
766 RVM_CPUREG_SETU(cpu, ins->op1, res);
767 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, !(res > op2)); /* borrow = !carry */
768 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
769 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
770 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op2 & RVM_SIGN_BIT) != (op3 & RVM_SIGN_BIT) &&
771 (res & RVM_SIGN_BIT) == (op2 & RVM_SIGN_BIT));
775 static void rvm_op_sbc(rvmcpu_t *cpu, rvm_asmins_t *ins)
777 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
779 res = op2 - op3 + (RVM_STATUS_GETBIT(cpu, RVM_STATUS_C) ? 0 : -1);
780 RVM_CPUREG_SETU(cpu, ins->op1, res);
781 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, !(res > op2)); /* borrow = !carry */
782 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
783 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
784 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op2 & RVM_SIGN_BIT) != (op3 & RVM_SIGN_BIT) &&
785 (res & RVM_SIGN_BIT) == (op2 & RVM_SIGN_BIT));
789 static void rvm_op_mul(rvmcpu_t *cpu, rvm_asmins_t *ins)
791 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) * RVM_CPUREG_GETU(cpu, ins->op3));
795 static void rvm_op_mls(rvmcpu_t *cpu, rvm_asmins_t *ins)
798 rsword op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
800 res = (rsword)(op2 * op3);
801 RVM_CPUREG_SETU(cpu, ins->op1, res);
802 /* TBD: Not sure how to update the RVM_STATUS_C */
803 RVM_STATUS_CLRALL(cpu);
804 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
805 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
809 static void rvm_op_muls(rvmcpu_t *cpu, rvm_asmins_t *ins)
811 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
814 RVM_CPUREG_SETU(cpu, ins->op1, res);
815 RVM_STATUS_CLRALL(cpu);
816 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, op2 && (res / op2) != op3);
817 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
818 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
822 static void rvm_op_div(rvmcpu_t *cpu, rvm_asmins_t *ins)
824 if (!RVM_CPUREG_GETU(cpu, ins->op3))
825 RVM_ABORT(cpu, RVM_E_DIVZERO);
827 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) / RVM_CPUREG_GETU(cpu, ins->op3));
831 static void rvm_op_divs(rvmcpu_t *cpu, rvm_asmins_t *ins)
833 rword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
836 RVM_ABORT(cpu, RVM_E_DIVZERO);
838 RVM_CPUREG_SETU(cpu, ins->op1, res);
839 RVM_STATUS_CLRALL(cpu);
840 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
841 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
845 static void rvm_op_mod(rvmcpu_t *cpu, rvm_asmins_t *ins)
847 if (!RVM_CPUREG_GETU(cpu, ins->op3))
848 RVM_ABORT(cpu, RVM_E_DIVZERO);
850 RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) % RVM_CPUREG_GETU(cpu, ins->op3));
854 static void rvm_op_mods(rvmcpu_t *cpu, rvm_asmins_t *ins)
856 rsword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
859 RVM_ABORT(cpu, RVM_E_DIVZERO);
861 r_printf("mod RES: %ld\n", res);
862 RVM_CPUREG_SETU(cpu, ins->op1, res);
863 RVM_STATUS_CLRALL(cpu);
864 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
865 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
869 static void rvm_op_dvs(rvmcpu_t *cpu, rvm_asmins_t *ins)
872 rsword op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
875 RVM_ABORT(cpu, RVM_E_DIVZERO);
876 res = (rsword)(op2 / op3);
877 RVM_CPUREG_SETU(cpu, ins->op1, res);
878 RVM_STATUS_CLRALL(cpu);
879 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
880 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
884 static void rvm_op_push(rvmcpu_t *cpu, rvm_asmins_t *ins)
886 rword sp = RVM_CPUREG_GETU(cpu, SP) + 1;
888 if (!RVM_STACK_CHECKSIZE(cpu, cpu->stack, sp))
889 RVM_ABORT(cpu, RVM_E_NOMEM);
890 RVM_STACK_WRITE(cpu->stack, sp, &RVM_CPUREG_GET(cpu, ins->op1));
891 RVM_CPUREG_SETU(cpu, SP, sp);
895 static void rvm_op_lds(rvmcpu_t *cpu, rvm_asmins_t *ins)
897 rword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
899 RVM_CPUREG_SET(cpu, ins->op1, RVM_STACK_READ(cpu->stack, sp));
903 static void rvm_op_sts(rvmcpu_t *cpu, rvm_asmins_t *ins)
905 rword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
907 if (!RVM_STACK_CHECKSIZE(cpu, cpu->stack, sp))
908 RVM_ABORT(cpu, RVM_E_NOMEM);
909 RVM_STACK_WRITE(cpu->stack, sp, &RVM_CPUREG_GET(cpu, ins->op1));
913 static void rvm_op_pushm(rvmcpu_t *cpu, rvm_asmins_t *ins)
916 rword bits = RVM_CPUREG_GETU(cpu, ins->op1);
917 rword sp = RVM_CPUREG_GETU(cpu, SP);
919 if (!RVM_STACK_CHECKSIZE(cpu, cpu->stack, sp + RVM_REGS_NUM))
920 RVM_ABORT(cpu, RVM_E_NOMEM);
922 if (!(bits & ((1<<(RVM_REGS_NUM / 2)) - 1)))
923 i = RVM_REGS_NUM / 2;
924 for (;bits && i < RLST; i++) {
928 RVM_STACK_WRITE(cpu->stack, sp, &RVM_CPUREG_GET(cpu, i));
932 RVM_CPUREG_SETU(cpu, SP, sp);
936 static void rvm_op_popm(rvmcpu_t *cpu, rvm_asmins_t *ins)
939 rword bits = RVM_CPUREG_GETU(cpu, ins->op1);
940 rword savedbits = bits;
941 rword sp = RVM_CPUREG_GETU(cpu, SP);
943 if (!(bits & ~((1 << (RVM_REGS_NUM / 2)) - 1)))
944 i = RVM_REGS_NUM / 2 - 1;
945 for (; bits && i >= 0; i--) {
948 RVM_CPUREG_SET(cpu, i, RVM_STACK_READ(cpu->stack, sp));
953 if (!(((rword)(1 << SP)) & savedbits))
954 RVM_CPUREG_SETU(cpu, SP, sp);
958 static void rvm_op_pop(rvmcpu_t *cpu, rvm_asmins_t *ins)
960 rword sp = RVM_CPUREG_GETU(cpu, SP);
962 RVM_CPUREG_SET(cpu, ins->op1, RVM_STACK_READ(cpu->stack, sp));
964 RVM_CPUREG_SETU(cpu, SP, sp - 1);
968 static void rvm_op_addrs(rvmcpu_t *cpu, rvm_asmins_t *ins)
970 rword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
972 if (!RVM_STACK_CHECKSIZE(cpu, cpu->stack, sp))
973 RVM_ABORT(cpu, RVM_E_NOMEM);
975 RVM_CPUREG_CLEAR(cpu, ins->op1);
976 RVM_CPUREG_SETTYPE(cpu, ins->op1, RVM_DTYPE_POINTER);
977 RVM_CPUREG_SETP(cpu, ins->op1, RVM_STACK_ADDR(cpu->stack, sp));
981 static void rvm_op_stm(rvmcpu_t *cpu, rvm_asmins_t *ins)
984 rword *dst = (rword*) RVM_CPUREG_GETU(cpu, ins->op1);
985 rword bits = RVM_CPUREG_GETU(cpu, ins->op2);
987 for (n = 0; bits && n < RLST; n++) {
988 if (((rword)(1 << n)) & bits) {
989 *dst = RVM_CPUREG_GETU(cpu, n);
997 static void rvm_op_ldm(rvmcpu_t *cpu, rvm_asmins_t *ins)
1000 rword *src = (rword*)RVM_CPUREG_GETU(cpu, ins->op1);
1001 rword bits = RVM_CPUREG_GETU(cpu, ins->op2);
1003 for (n = 0; bits && n < RLST; n++) {
1004 if (((rword)(1 << n)) & bits) {
1005 RVM_CPUREG_CLEAR(cpu, n);
1006 RVM_CPUREG_SETU(cpu, n, *src);
1014 static void rvm_op_cmp(rvmcpu_t *cpu, rvm_asmins_t *ins)
1016 rword op1 = RVM_CPUREG_GETU(cpu, ins->op1), op2 = RVM_CPUREG_GETU(cpu, ins->op2);
1017 rword res = (rword)(op1 - op2);
1019 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, op1 < op2);
1020 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
1021 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
1022 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op1 & RVM_SIGN_BIT) != (op2 & RVM_SIGN_BIT) &&
1023 (res & RVM_SIGN_BIT) == (op1 & RVM_SIGN_BIT));
1027 static void rvm_op_cmn(rvmcpu_t *cpu, rvm_asmins_t *ins)
1029 rword op1 = RVM_CPUREG_GETU(cpu, ins->op1), op2 = RVM_CPUREG_GETU(cpu, ins->op2);
1030 rword res = (rword)(op1 + op2);
1032 RVM_STATUS_UPDATE(cpu, RVM_STATUS_C, res < op1 || res < op2);
1033 RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
1034 RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
1035 RVM_STATUS_UPDATE(cpu, RVM_STATUS_V, (op1 & RVM_SIGN_BIT) == (op2 & RVM_SIGN_BIT) &&
1036 (res & RVM_SIGN_BIT) != (op1 & RVM_SIGN_BIT));
1041 static void rvm_op_nop(rvmcpu_t *cpu, rvm_asmins_t *ins)
1043 // fprintf(stdout, "nop\n");
1047 static void rvm_op_ret(rvmcpu_t *cpu, rvm_asmins_t *ins)
1049 RVM_CPUREG_SETU(cpu, PC, RVM_CPUREG_GETU(cpu, LR));
1053 static int rvm_vsnprintf(char *str, ruint size, const char *format, va_list ap)
1055 return vsnprintf(str, size, format, ap);
1059 static int rvm_snprintf(char *str, ruint size, const char *format, ...)
1064 va_start(ap, format);
1065 ret = rvm_vsnprintf(str, size, format, ap);
1071 static int rvm_printf(const char *format, ...)
1076 va_start(ap, format);
1077 ret = vfprintf(stdout, format, ap);
1083 int rvm_asm_dump_reg_to_str(unsigned char reg, char *str, ruint size)
1088 ret = rvm_snprintf(str, size, "XX ");
1090 ret = rvm_snprintf(str, size, "IP ");
1092 ret = rvm_snprintf(str, size, "TP ");
1094 ret = rvm_snprintf(str, size, "FP ");
1096 ret = rvm_snprintf(str, size, "SP ");
1098 ret = rvm_snprintf(str, size, "LR ");
1100 ret = rvm_snprintf(str, size, "PC ");
1102 ret = rvm_snprintf(str, size, "DA ");
1104 ret = rvm_snprintf(str, size, "R%d ", reg);
1110 static void rvm_op_prn(rvmcpu_t *cpu, rvm_asmins_t *ins)
1112 rvmreg_t *r = RVM_CPUREG_PTR(cpu, ins->op1);
1114 if (rvm_reg_gettype(r) == RVM_DTYPE_UNSIGNED)
1115 rvm_printf("(UNSIGNED) R%d = %lu(0x%lx)\n", ins->op1, RVM_REG_GETU(r), RVM_REG_GETU(r));
1116 else if (rvm_reg_gettype(r) == RVM_DTYPE_BOOLEAN)
1117 rvm_printf("(UNSIGNED) R%d = %lu(0x%lx)\n", ins->op1, RVM_REG_GETU(r), RVM_REG_GETU(r));
1118 else if (rvm_reg_gettype(r) == RVM_DTYPE_POINTER)
1119 rvm_printf("(POINTER) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
1120 else if (rvm_reg_gettype(r) == RVM_DTYPE_LONG)
1121 rvm_printf("(LONG) R%d = %ld\n", ins->op1, RVM_REG_GETL(r));
1122 else if (rvm_reg_gettype(r) == RVM_DTYPE_DOUBLE)
1123 rvm_printf("(DOUBLE) R%d = %0.2f\n", ins->op1, RVM_REG_GETD(r));
1124 else if (rvm_reg_gettype(r) == RVM_DTYPE_STRING)
1125 rvm_printf("(STRING) R%d = %s\n", ins->op1, ((rstring_t*) RVM_REG_GETP(r))->s.str);
1126 else if (rvm_reg_gettype(r) == RVM_DTYPE_ARRAY)
1127 rvm_printf("(ARRAY) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
1128 else if (rvm_reg_gettype(r) == RVM_DTYPE_JSOBJECT)
1129 rvm_printf("(Object) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
1130 else if (rvm_reg_gettype(r) == RVM_DTYPE_SWIID)
1131 rvm_printf("(SWI) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
1132 else if (rvm_reg_gettype(r) == RVM_DTYPE_FUNCTION)
1133 rvm_printf("(FUNCTION) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
1135 rvm_printf("(UNKNOWN) R%d = ?\n", ins->op1);
1139 int rvm_asm_dump_pi_to_str(rvmcpu_t *vm, rvm_asmins_t *pi, char *str, ruint size)
1141 int ret = 0, sz = size;
1143 if (pi->opcode == RVM_SWI) {
1145 r_memset(szSwi, 0, sizeof(szSwi));
1147 rvm_snprintf(szSwi, sizeof(szSwi) - 1, "%s(%x)", stropcalls[pi->opcode], (ruint32)pi->swi);
1149 rvm_switable_t *switable;
1150 ruint ntable = (ruint) RVM_SWI_TABLE(pi->swi);
1151 ruint nswi = (ruint) RVM_SWI_NUM(pi->swi);
1153 if (ntable < r_harray_length(vm->switables)) {
1154 switable = r_harray_index(vm->switables, ntable, rvm_switable_t*);
1155 rvm_snprintf(szSwi, sizeof(szSwi) - 1, "(%s)", switable[nswi].name ? switable[nswi].name : "unknown");
1158 if ((ret = rvm_snprintf(str, sz, "%16s ", szSwi)) < 0)
1161 if ((ret = rvm_snprintf(str, sz, "%16s ", stropcalls[pi->opcode])) < 0)
1167 if ((ret = rvm_asm_dump_reg_to_str(pi->op1, str, sz)) < 0)
1172 if ((ret = rvm_snprintf(str, sz, " ")) < 0)
1177 if ((ret = rvm_asm_dump_reg_to_str(pi->op2, str, sz)) < 0)
1182 if ((ret = rvm_snprintf(str, sz, " ")) < 0)
1187 if ((ret = rvm_asm_dump_reg_to_str(pi->op3, str, sz)) < 0)
1192 if ((ret = rvm_snprintf(str, sz, " ")) < 0)
1198 if (RVM_REG_GETTYPE(&pi->data) == RVM_DTYPE_DOUBLE) {
1199 if ((ret = rvm_snprintf(str, sz, "%f ", RVM_REG_GETD(&pi->data))) < 0)
1201 } else if (RVM_REG_GETTYPE(&pi->data) == RVM_DTYPE_LONG) {
1202 if ((ret = rvm_snprintf(str, sz, "%ld ", RVM_REG_GETL(&pi->data))) < 0)
1205 if ((ret = rvm_snprintf(str, sz, "0x%lx ", (unsigned long)RVM_REG_GETU(&pi->data))) < 0)
1216 void rvm_asm_dump(rvm_asmins_t *pi, ruint count)
1220 rvm_asm_dump_pi_to_str(NULL, pi, buffer, sizeof(buffer));
1221 rvm_printf("%s\n", buffer);
1228 void rvm_cpu_dumpregs(rvmcpu_t *vm, rvm_asmins_t *pi)
1233 ret = rvm_asm_dump_pi_to_str(vm, pi, buffer, sizeof(buffer));
1236 ret = rvm_snprintf(buffer + ret, sizeof(buffer) - ret, " ");
1238 rvm_printf("%s", buffer);
1240 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 )",
1241 RVM_CPUREG_GETU(vm, 0), RVM_CPUREG_GETU(vm, 1), RVM_CPUREG_GETU(vm, 2), RVM_CPUREG_GETU(vm, 3),
1242 RVM_CPUREG_GETU(vm, 4), RVM_CPUREG_GETU(vm, 5), RVM_CPUREG_GETU(vm, 6), RVM_CPUREG_GETU(vm, 7),
1243 RVM_CPUREG_GETU(vm, 8), RVM_CPUREG_GETP(vm, TP), (long int)RVM_CPUREG_GETU(vm, FP), (long int)RVM_CPUREG_GETU(vm, SP),
1244 (long int)RVM_CPUREG_GETU(vm, LR), (long int)RVM_CPUREG_GETU(vm, PC), RVM_CPUREG_GETU(vm, DA),
1245 vm->status & RVM_STATUS_E ? 'E' : '_',
1246 vm->status & RVM_STATUS_V ? 'V' : '_',
1247 vm->status & RVM_STATUS_C ? 'C' : '_',
1248 vm->status & RVM_STATUS_N ? 'N' : '_',
1249 vm->status & RVM_STATUS_Z ? 'Z' : '_');
1254 static void rvm_op_cast(rvmcpu_t *cpu, rvm_asmins_t *ins)
1256 rvmreg_type_t type = (rvmreg_type_t)RVM_CPUREG_GETU(cpu, ins->op3);
1259 RVM_REG_CLEAR(&tmp);
1260 RVM_REG_SETTYPE(&tmp, type);
1261 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, RVM_CPUREG_PTR(cpu, ins->op1), RVM_CPUREG_PTR(cpu, ins->op2), &tmp);
1265 static void rvm_op_type(rvmcpu_t *cpu, rvm_asmins_t *ins)
1267 rvmreg_type_t type = (rvmreg_type_t)RVM_CPUREG_GETTYPE(cpu, ins->op2);
1269 RVM_CPUREG_SETU(cpu, ins->op1, type);
1273 static void rvm_op_settype(rvmcpu_t *cpu, rvm_asmins_t *ins)
1275 rvmreg_type_t type = (rvmreg_type_t)RVM_CPUREG_GETU(cpu, ins->op2);
1277 RVM_CPUREG_SETTYPE(cpu, ins->op1, type);
1281 static void rvm_op_emov(rvmcpu_t *cpu, rvm_asmins_t *ins)
1283 rvm_op_mov(cpu, ins);
1287 static void rvm_op_eadd(rvmcpu_t *cpu, rvm_asmins_t *ins)
1289 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1290 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1292 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_ADD, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1296 static void rvm_op_esub(rvmcpu_t *cpu, rvm_asmins_t *ins)
1298 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1299 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1301 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_SUB, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1305 static void rvm_op_eneg(rvmcpu_t *cpu, rvm_asmins_t *ins)
1307 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1310 rvm_reg_setunsigned(&zero, 0);
1311 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_SUB, cpu, RVM_CPUREG_PTR(cpu, ins->op1), &zero, arg2);
1316 static void rvm_op_emul(rvmcpu_t *cpu, rvm_asmins_t *ins)
1318 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1319 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1321 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_MUL, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1325 static void rvm_op_ediv(rvmcpu_t *cpu, rvm_asmins_t *ins)
1327 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1328 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1330 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_DIV, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1334 static void rvm_op_emod(rvmcpu_t *cpu, rvm_asmins_t *ins)
1336 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1337 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1339 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_MOD, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1343 static void rvm_op_elsl(rvmcpu_t *cpu, rvm_asmins_t *ins)
1345 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1346 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1348 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LSL, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1352 static void rvm_op_elsr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1354 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1355 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1357 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LSR, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1361 static void rvm_op_elsru(rvmcpu_t *cpu, rvm_asmins_t *ins)
1363 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1364 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1366 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LSRU, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1370 static void rvm_op_eand(rvmcpu_t *cpu, rvm_asmins_t *ins)
1372 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1373 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1375 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_AND, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1379 static void rvm_op_eorr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1381 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1382 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1384 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_OR, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1388 static void rvm_op_exor(rvmcpu_t *cpu, rvm_asmins_t *ins)
1390 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1391 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1393 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_XOR, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1397 static void rvm_op_enot(rvmcpu_t *cpu, rvm_asmins_t *ins)
1399 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1401 rvm_opmap_invoke_unary_handler(cpu->opmap, RVM_OPID_NOT, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2);
1405 static void rvm_op_eland(rvmcpu_t *cpu, rvm_asmins_t *ins)
1407 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1408 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1410 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LOGICAND, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1414 static void rvm_op_elor(rvmcpu_t *cpu, rvm_asmins_t *ins)
1416 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1417 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1419 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LOGICOR, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1423 static void rvm_op_elnot(rvmcpu_t *cpu, rvm_asmins_t *ins)
1425 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1427 rvm_opmap_invoke_unary_handler(cpu->opmap, RVM_OPID_LOGICNOT, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2);
1431 static void rvm_op_eeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
1433 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1434 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1436 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_EQ, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1440 static void rvm_op_enoteq(rvmcpu_t *cpu, rvm_asmins_t *ins)
1442 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1443 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1445 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_NOTEQ, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1449 static void rvm_op_egreat(rvmcpu_t *cpu, rvm_asmins_t *ins)
1451 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1452 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1454 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_GREATER, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1458 static void rvm_op_egreateq(rvmcpu_t *cpu, rvm_asmins_t *ins)
1460 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1461 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1463 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_GREATEREQ, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1467 static void rvm_op_elesseq(rvmcpu_t *cpu, rvm_asmins_t *ins)
1469 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1470 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1472 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LESSEQ, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1476 static void rvm_op_eless(rvmcpu_t *cpu, rvm_asmins_t *ins)
1478 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1479 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1481 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LESS, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
1485 static void rvm_op_ecmp(rvmcpu_t *cpu, rvm_asmins_t *ins)
1487 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1488 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1490 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CMP, cpu, NULL, arg1, arg2);
1494 static void rvm_op_ecmn(rvmcpu_t *cpu, rvm_asmins_t *ins)
1496 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1497 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1499 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CMN, cpu, NULL, arg1, arg2);
1503 static void rvm_op_allocstr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1506 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1507 rstring_t *s = r_string_create_strsize((const rchar*)RVM_CPUREG_GETP(cpu, ins->op2), RVM_CPUREG_GETU(cpu, ins->op3));
1509 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1511 rvm_gc_add(cpu->gc, (robject_t*)s);
1512 rvm_reg_setstring(arg1, s);
1516 static void rvm_op_mapalloc(rvmcpu_t *cpu, rvm_asmins_t *ins)
1518 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1519 rmap_t *a = r_map_create(sizeof(rvmreg_t), 7);
1521 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1523 // r_carray_setlength(a, RVM_CPUREG_GETU(cpu, ins->op2));
1524 rvm_gc_add(cpu->gc, (robject_t*)a);
1525 rvm_reg_setjsobject(arg1, (robject_t*)a);
1529 static void rvm_op_allocarr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1531 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1532 ruint size = RVM_CPUREG_GETU(cpu, ins->op2);
1533 rcarray_t *a = r_carray_create_rvmreg();
1535 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1537 r_carray_setlength(a, size);
1538 rvm_gc_add(cpu->gc, (robject_t*)a);
1539 rvm_reg_setarray(arg1, (robject_t*)a);
1543 static void rvm_op_maplookup(rvmcpu_t *cpu, rvm_asmins_t *ins)
1547 rchar key[256], *pkey = key;
1548 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1549 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1550 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1551 rmap_t *a = (rmap_t*)RVM_REG_GETP(arg2);
1553 if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT) {
1554 RVM_ABORT(cpu, RVM_E_NOTOBJECT);
1556 if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_LONG || RVM_REG_GETTYPE(arg3) == RVM_DTYPE_UNSIGNED) {
1557 keysize = r_snprintf(key, sizeof(key) - 1, "%ld", RVM_REG_GETL(arg3));
1558 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_DOUBLE) {
1559 keysize = r_snprintf(key, sizeof(key) - 1, "%f", RVM_REG_GETD(arg3));
1560 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_STRING) {
1561 pkey = ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.str;
1562 keysize = ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.size;
1563 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_POINTER) {
1564 pkey = (rchar*)RVM_CPUREG_GETP(cpu, ins->op3);
1565 keysize = RVM_CPUREG_GETL(cpu, ins->op1);
1567 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1569 index = r_map_lookup(a, -1, pkey, keysize);
1571 RVM_REG_CLEAR(arg1);
1572 RVM_REG_SETTYPE(arg1, RVM_DTYPE_LONG);
1573 RVM_REG_SETL(arg1, index);
1577 static void rvm_op_mapadd(rvmcpu_t *cpu, rvm_asmins_t *ins)
1581 rchar key[256], *pkey = key;
1582 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1583 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1584 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1585 rmap_t *a = (rmap_t*)RVM_REG_GETP(arg2);
1587 if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT) {
1588 RVM_ABORT(cpu, RVM_E_NOTOBJECT);
1590 if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_LONG || RVM_REG_GETTYPE(arg3) == RVM_DTYPE_UNSIGNED) {
1591 keysize = r_snprintf(key, sizeof(key) - 1, "%ld", RVM_REG_GETL(arg3));
1592 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_DOUBLE) {
1593 keysize = r_snprintf(key, sizeof(key) - 1, "%f", RVM_REG_GETD(arg3));
1594 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_STRING) {
1595 pkey = ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.str;
1596 keysize = ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.size;
1597 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_POINTER) {
1598 pkey = (rchar*)RVM_CPUREG_GETP(cpu, ins->op3);
1599 keysize = RVM_CPUREG_GETL(cpu, ins->op1);
1601 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1603 index = r_map_add(a, pkey, keysize, NULL);
1605 RVM_REG_CLEAR(arg1);
1606 RVM_REG_SETTYPE(arg1, RVM_DTYPE_LONG);
1607 RVM_REG_SETL(arg1, index);
1611 static void rvm_op_maplookupadd(rvmcpu_t *cpu, rvm_asmins_t *ins)
1615 rchar key[256], *pkey = key;
1616 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1617 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1618 rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
1619 rmap_t *a = (rmap_t*)RVM_REG_GETP(arg2);
1621 if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT) {
1622 RVM_ABORT(cpu, RVM_E_NOTOBJECT);
1625 if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_LONG || RVM_REG_GETTYPE(arg3) == RVM_DTYPE_UNSIGNED) {
1626 keysize = r_snprintf(key, sizeof(key) - 1, "%ld", RVM_REG_GETL(arg3));
1627 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_DOUBLE) {
1628 keysize = r_snprintf(key, sizeof(key) - 1, "%f", RVM_REG_GETD(arg3));
1629 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_STRING) {
1630 pkey = ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.str;
1631 keysize = ((rstring_t *)RVM_CPUREG_GETP(cpu, ins->op3))->s.size;
1632 } else if (RVM_REG_GETTYPE(arg3) == RVM_DTYPE_POINTER) {
1633 pkey = (rchar*)RVM_CPUREG_GETP(cpu, ins->op3);
1634 keysize = RVM_CPUREG_GETL(cpu, ins->op1);
1636 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1638 index = r_map_lookup(a, -1, pkey, keysize);
1640 index = r_map_add(a, pkey, keysize, NULL);
1641 RVM_REG_CLEAR(arg1);
1642 RVM_REG_SETTYPE(arg1, RVM_DTYPE_LONG);
1643 RVM_REG_SETL(arg1, index);
1647 static void rvm_op_mapaddr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1649 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1650 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1651 rvmreg_t tmp = rvm_reg_create_long(0);
1656 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, &tmp, RVM_CPUREG_PTR(cpu, ins->op3), &tmp);
1657 index = RVM_REG_GETL(&tmp);
1658 if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT)
1659 RVM_ABORT(cpu, RVM_E_NOTOBJECT);
1660 a = (rmap_t*)RVM_REG_GETP(arg2);
1661 value = r_map_value(a, index);
1663 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1664 RVM_REG_CLEAR(arg1);
1665 RVM_REG_SETTYPE(arg1, RVM_DTYPE_POINTER);
1666 RVM_REG_SETP(arg1, value);
1670 static void rvm_op_mapldr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1672 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1673 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1674 rvmreg_t tmp = rvm_reg_create_long(0);
1679 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, &tmp, RVM_CPUREG_PTR(cpu, ins->op3), &tmp);
1680 index = RVM_REG_GETL(&tmp);
1681 if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT)
1682 RVM_ABORT(cpu, RVM_E_NOTOBJECT);
1683 a = (rmap_t*)RVM_REG_GETP(arg2);
1684 value = r_map_value(a, index);
1686 RVM_REG_CLEAR(arg1);
1687 RVM_REG_SETTYPE(arg1, RVM_DTYPE_UNDEF);
1689 *arg1 = *((rvmreg_t*)value);
1694 static void rvm_op_mapstr(rvmcpu_t *cpu, rvm_asmins_t *ins)
1696 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1697 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1698 rvmreg_t tmp = rvm_reg_create_long(0);
1703 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, &tmp, RVM_CPUREG_PTR(cpu, ins->op3), &tmp);
1704 index = RVM_REG_GETL(&tmp);
1705 if (rvm_reg_gettype(arg2) != RVM_DTYPE_JSOBJECT)
1706 RVM_ABORT(cpu, RVM_E_NOTOBJECT);
1707 a = (rmap_t*)RVM_REG_GETP(arg2);
1708 value = r_map_value(a, index);
1710 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1711 r_map_setvalue(a, index, arg1);
1715 static void rvm_op_addra(rvmcpu_t *cpu, rvm_asmins_t *ins)
1717 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1718 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1719 rvmreg_t tmp = rvm_reg_create_long(0);
1720 rcarray_t *a = RVM_REG_GETP(arg2);
1723 rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, &tmp, RVM_CPUREG_PTR(cpu, ins->op3), &tmp);
1724 index = RVM_REG_GETL(&tmp);
1726 if (rvm_reg_gettype(arg2) != RVM_DTYPE_ARRAY || index < 0) {
1727 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1729 RVM_REG_CLEAR(arg1);
1730 RVM_REG_SETTYPE(arg1, RVM_DTYPE_POINTER);
1731 RVM_REG_SETP(arg1, r_carray_slot_expand(a, index));
1735 static void rvm_op_lda(rvmcpu_t *cpu, rvm_asmins_t *ins)
1737 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1738 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1739 ruint index = RVM_CPUREG_GETU(cpu, ins->op3);
1740 rcarray_t *a = RVM_REG_GETP(arg2);
1742 if (rvm_reg_gettype(arg2) != RVM_DTYPE_ARRAY) {
1743 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1745 *arg1 = *((rvmreg_t*)r_carray_slot_expand(a, index));
1749 static void rvm_op_sta(rvmcpu_t *cpu, rvm_asmins_t *ins)
1751 rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
1752 rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
1753 ruint index = RVM_CPUREG_GETU(cpu, ins->op3);
1754 rcarray_t *a = RVM_REG_GETP(arg2);
1756 if (rvm_reg_gettype(arg2) != RVM_DTYPE_ARRAY) {
1757 RVM_ABORT(cpu, RVM_E_ILLEGAL);
1759 r_carray_replace(a, index, arg1);
1763 static void rvm_op_abort(rvmcpu_t *cpu, rvm_asmins_t *ins)
1765 RVM_ABORT(cpu, RVM_CPUREG_GETU(cpu, ins->op1));
1769 static rvm_cpu_op ops[] = {
1770 rvm_op_exit, // RVM_EXT
1771 rvm_op_abort, // RVM_ABORT
1772 rvm_op_prn, // RVM_PRN
1773 rvm_op_asr, // RVM_ASR
1774 rvm_op_swi, // RVM_SWI
1775 rvm_op_swiid, // RVM_SWIID
1776 rvm_op_call, // RVM_CALL
1777 rvm_op_mov, // RVM_MOV
1778 rvm_op_movs, // RVM_MOVS
1779 rvm_op_swp, // RVM_SWP
1780 rvm_op_inc, // RVM_INC
1781 rvm_op_dec, // RVM_DEC
1782 rvm_op_add, // RVM_ADD
1783 rvm_op_adds, // RVM_ADDS
1784 rvm_op_adc, // RVM_ADC
1785 rvm_op_and, // RVM_AND
1786 rvm_op_bic, // RVM_BIC
1787 rvm_op_clz, // RVM_CLZ
1788 rvm_op_cmn, // RVM_CMN
1789 rvm_op_xor, // RVM_XOR
1790 rvm_op_sub, // RVM_SUB
1791 rvm_op_subs, // RVM_SUBS
1792 rvm_op_sbc, // RVM_SBC
1793 rvm_op_mul, // RVM_MUL
1794 rvm_op_mls, // RVM_MLS
1795 rvm_op_muls, // RVM_MULS
1796 rvm_op_not, // RVM_NOT
1797 rvm_op_div, // RVM_DIV
1798 rvm_op_dvs, // RVM_DVS
1799 rvm_op_divs, // RVM_DIVS
1800 rvm_op_mod, // RVM_MOD
1801 rvm_op_mods, // RVM_MODS
1802 rvm_op_bx, // RVM_BX
1803 rvm_op_bxeq, // RVM_BXEQ
1804 rvm_op_bxneq, // RVM_BXNEQ
1805 rvm_op_bxleq, // RVM_BXLEQ
1806 rvm_op_bxgeq, // RVM_BXGEQ
1807 rvm_op_bxles, // RVM_BXLES
1808 rvm_op_bxgre, // RVM_BXGRE
1809 rvm_op_bxl, // RVM_BXL
1810 rvm_op_bl, // RVM_BL
1812 rvm_op_str, // RVM_STR
1813 rvm_op_strp, // RVM_STRP
1814 rvm_op_strb, // RVM_STRB
1815 rvm_op_strh, // RVM_STRH
1816 rvm_op_strw, // RVM_STRW
1817 rvm_op_strr, // RVM_STRR
1818 rvm_op_ldr, // RVM_LDR
1819 rvm_op_ldrp, // RVM_LDRP
1820 rvm_op_ldrb, // RVM_LDRB
1821 rvm_op_ldrh, // RVM_LDRH
1822 rvm_op_ldrw, // RVM_LDRW
1823 rvm_op_ldrr, // RVM_LDRR
1824 rvm_op_cflag, // RVM_CFLAG
1825 rvm_op_clr, // RVM_CLR
1826 rvm_op_clrr, // RVM_CLRR
1827 rvm_op_lsl, // RVM_LSL
1828 rvm_op_lsr, // RVM_LSR
1829 rvm_op_lsrs, // RVM_LSRS
1830 rvm_op_stm, // RVM_STM
1831 rvm_op_ldm, // RVM_LDM
1832 rvm_op_sts, // RVM_STS
1833 rvm_op_lds, // RVM_LDS
1834 rvm_op_orr, // RVM_ORR
1835 rvm_op_push, // RVM_PUSH
1836 rvm_op_pop, // RVM_POP
1837 rvm_op_cmp, // RVM_CMP
1838 rvm_op_nop, // RVM_NOP
1839 rvm_op_beq, // RVM_BEQ
1840 rvm_op_bneq, // RVM_BNEQ
1841 rvm_op_bleq, // RVM_BLEQ
1842 rvm_op_bgeq, // RVM_BGEQ
1843 rvm_op_bles, // RVM_BLES
1844 rvm_op_bgre, // RVM_BGRE
1845 rvm_op_ret, // RVM_RET
1846 rvm_op_ror, // RVM_ROR
1847 rvm_op_pushm, // RVM_PUSHM
1848 rvm_op_popm, // RVM_POPM
1849 rvm_op_tst, // RVM_TST
1850 rvm_op_teq, // RVM_TEQ
1851 rvm_op_addrs, // RVM_ADDRS
1853 /* Extended VM instructions */
1854 rvm_op_cast, // RVM_CAST
1855 rvm_op_type, // RVM_TYPE
1856 rvm_op_settype, // RVM_SETTYPE
1857 rvm_op_emov, // RVM_EMOV
1858 rvm_op_eneg, // RVM_ENEG
1859 rvm_op_eadd, // RVM_EADD
1860 rvm_op_esub, // RVM_ESUB
1861 rvm_op_emul, // RVM_EMUL
1862 rvm_op_ediv, // RVM_EDIV
1863 rvm_op_emod, // RVM_MOD
1864 rvm_op_elsl, // RVM_ELSL
1865 rvm_op_elsr, // RVM_ELSR
1866 rvm_op_elsru, // RVM_ELSRU
1867 rvm_op_eand, // RVM_EAND
1868 rvm_op_eorr, // RVM_EORR
1869 rvm_op_exor, // RVM_EXOR
1870 rvm_op_enot, // RVM_ENOT
1872 rvm_op_eland, // RVM_ELAND
1873 rvm_op_elor, // RVM_ELOR
1874 rvm_op_elnot, // RVM_ELNOT
1875 rvm_op_eeq, // RVM_EEQ
1876 rvm_op_enoteq, // RVM_ENOTEQ
1877 rvm_op_egreat, // RVM_EGREAT
1878 rvm_op_egreateq, // RVM_EGREATEQ
1879 rvm_op_eless, // RVM_ELESS
1880 rvm_op_elesseq, // RVM_ELESSEQ
1881 rvm_op_ecmp, // RVM_ECMP
1882 rvm_op_ecmn, // RVM_ECMN
1883 rvm_op_allocstr, // RVM_ALLOCSTR
1884 rvm_op_allocarr, // RVM_ALLOCARR
1885 rvm_op_addra, // RVM_ADDRA
1886 rvm_op_lda, // RVM_LDA
1887 rvm_op_sta, // RVM_STA
1888 rvm_op_mapalloc, // RVM_MAPALLOC
1889 rvm_op_mapaddr, // RVM_MAPADDR,
1890 rvm_op_mapldr, // RVM_MAPLDR,
1891 rvm_op_mapstr, // RVM_MAPSTR,
1892 rvm_op_maplookup, // RVM_MAPLKUP,
1893 rvm_op_mapadd, // RVM_MAPADD,
1894 rvm_op_maplookupadd,// RVM_MAPLKUPADD,
1907 rvmcpu_t *rvm_cpu_create(rulong stacksize)
1911 cpu = (rvmcpu_t *)r_malloc(sizeof(*cpu));
1914 r_memset(cpu, 0, sizeof(*cpu));
1915 cpu->stacksize = stacksize;
1916 cpu->switables = r_harray_create(sizeof(rvm_switable_t*));
1917 cpu->stack = r_malloc(stacksize * sizeof(rvmreg_t));
1918 cpu->data = r_carray_create(sizeof(rvmreg_t));
1919 cpu->opmap = rvm_opmap_create();
1920 cpu->gc = rvm_gc_create();
1921 rvm_op_binary_init(cpu->opmap);
1922 rvm_op_cast_init(cpu->opmap);
1923 rvm_op_not_init(cpu->opmap);
1924 rvm_op_logicnot_init(cpu->opmap);
1930 rvmcpu_t *rvm_cpu_create_default()
1932 return rvm_cpu_create(RVM_DEFAULT_STACKSIZE);
1936 void rvm_cpu_destroy(rvmcpu_t *cpu)
1938 rvm_gc_deallocate_all(cpu->gc);
1939 rvm_gc_destroy(cpu->gc);
1940 r_object_destroy((robject_t*)cpu->switables);
1942 r_object_destroy((robject_t*)cpu->data);
1943 rvm_opmap_destroy(cpu->opmap);
1948 rint rvm_cpu_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off)
1951 rvmreg_t *regda = RVM_CPUREG_PTR(cpu, DA);
1952 rvmreg_t *regpc = RVM_CPUREG_PTR(cpu, PC);
1954 RVM_CPUREG_SETIP(cpu, PC, prog + off);
1958 pi = RVM_REG_GETIP(regpc);
1962 #if RVM_CONDITIONAL_INSTRUCTIONS
1966 if (!((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0))
1970 if (!((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1))
1974 if (!((cpu->status & RVM_STATUS_Z)))
1978 if (!((cpu->status & RVM_STATUS_Z) == 0))
1982 if (!((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z)))
1986 if (!((cpu->status & RVM_STATUS_N)))
1994 ops[pi->opcode](cpu, pi);
1995 #if RVM_CONDITIONAL_INSTRUCTIONS
1998 RVM_REG_INCIP(regpc, 1);
1999 } while (!cpu->abort);
2006 rint rvm_cpu_exec_debug(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off)
2010 rvmreg_t *regda = RVM_CPUREG_PTR(cpu, DA);
2011 rvmreg_t *regpc = RVM_CPUREG_PTR(cpu, PC);
2013 RVM_CPUREG_SETIP(cpu, PC, prog + off);
2017 pi = RVM_REG_GETIP(regpc);
2021 #if RVM_CONDITIONAL_INSTRUCTIONS
2025 if (!((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0))
2029 if (!((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1))
2033 if (!((cpu->status & RVM_STATUS_Z)))
2037 if (!((cpu->status & RVM_STATUS_Z) == 0))
2041 if (!((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z)))
2045 if (!((cpu->status & RVM_STATUS_N)))
2053 ops[pi->opcode](cpu, pi);
2054 r_printf("%7ld :", ++line);
2055 rvm_cpu_dumpregs(cpu, pi);
2056 #if RVM_CONDITIONAL_INSTRUCTIONS
2059 RVM_REG_INCIP(regpc, 1);
2060 } while (!cpu->abort);
2067 rint rvm_cpu_global_swilookup(rvmcpu_t *cpu, const rchar *swiname, rsize_t size)
2070 rvm_switable_t *swientry;
2073 for (ntable = 0; ntable < r_harray_length(cpu->switables); ntable++) {
2074 swientry = r_harray_index(cpu->switables, ntable, rvm_switable_t*);
2077 for (nswi = 0; swientry[nswi].name; nswi++) {
2078 if (r_strncmp(swientry[nswi].name, swiname, size) == 0 && r_strlen(swientry[nswi].name) == size)
2079 return (rint)RVM_SWI_ID(ntable, nswi);
2086 rint rvm_cpu_table_swilookup(rvmcpu_t *cpu, const rchar *tabname, const rchar *swiname, rsize_t size)
2089 rvm_switable_t *swientry;
2090 rlong ntable = r_harray_lookup_s(cpu->switables, tabname);
2094 swientry = r_harray_index(cpu->switables, ntable, rvm_switable_t*);
2097 for (nswi = 0; swientry[nswi].name; nswi++) {
2098 if (r_strncmp(swientry[nswi].name, swiname, size) == 0 && r_strlen(swientry[nswi].name) == size)
2099 return (rint)RVM_SWI_ID(ntable, nswi);
2105 rint rvm_cpu_swilookup(rvmcpu_t *cpu, const rchar *tabname, const rchar *swiname, rsize_t size)
2107 return tabname ? rvm_cpu_table_swilookup(cpu, tabname, swiname, size) : rvm_cpu_global_swilookup(cpu, swiname, size);
2111 rint rvm_cpu_swilookup_s(rvmcpu_t *cpu, const rchar *tabname, const rchar *swiname)
2113 return rvm_cpu_swilookup(cpu, tabname, swiname, r_strlen(swiname));
2117 rint rvm_cpu_addswitable(rvmcpu_t *cpu, const rchar *tabname, rvm_switable_t *switable)
2119 return r_harray_replace_s(cpu->switables, tabname, &switable);
2123 rint rvm_cpu_abort(rvmcpu_t *cpu)
2127 cpu->error = RVM_E_USERABORT;
2133 rvm_asmins_t rvm_cond_asma(rword cond, rword opcode, rword op1, rword op2, rword op3, rchar *data, rulong size)
2137 r_memset(&a, 0, sizeof(a));
2138 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2139 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2140 a.op1 = (ruint8)op1;
2141 a.op2 = (ruint8)op2;
2142 a.op3 = (ruint8)op3;
2144 rvm_reg_setstrptr(&a.data, data, size);
2145 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2151 rvm_asmins_t rvm_asma(rword opcode, rword op1, rword op2, rword op3, rchar *data, rulong size)
2153 return rvm_cond_asma(0, opcode, op1, op2, op3, data, size);
2157 rvm_asmins_t rvm_cond_asmp(rword cond, rword opcode, rword op1, rword op2, rword op3, rpointer data)
2161 r_memset(&a, 0, sizeof(a));
2162 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2163 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2164 a.op1 = (ruint8)op1;
2165 a.op2 = (ruint8)op2;
2166 a.op3 = (ruint8)op3;
2168 rvm_reg_setpointer(&a.data, data);
2169 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2175 rvm_asmins_t rvm_asmp(rword opcode, rword op1, rword op2, rword op3, rpointer data)
2177 return rvm_cond_asmp(0, opcode, op1, op2, op3, data);
2181 rvm_asmins_t rvm_cond_asms(rword cond, rword opcode, rword op1, rword op2, rword op3, rword data)
2185 r_memset(&a, 0, sizeof(a));
2186 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2187 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2188 a.op1 = (ruint8)op1;
2189 a.op2 = (ruint8)op2;
2190 a.op3 = (ruint8)op3;
2192 rvm_reg_setunsigned(&a.data, data);
2193 RVM_REG_SETTYPE(&a.data, RVM_DTYPE_SWIID)
2194 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2200 rvm_asmins_t rvm_asms(rword opcode, rword op1, rword op2, rword op3, rword data)
2202 return rvm_cond_asms(0, opcode, op1, op2, op3, data);
2206 rvm_asmins_t rvm_cond_asmf(rword cond, rword opcode, rword op1, rword op2, rword op3, rword data)
2210 r_memset(&a, 0, sizeof(a));
2211 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2212 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2213 a.op1 = (ruint8)op1;
2214 a.op2 = (ruint8)op2;
2215 a.op3 = (ruint8)op3;
2217 rvm_reg_setunsigned(&a.data, data);
2218 RVM_REG_SETTYPE(&a.data, RVM_DTYPE_FUNCTION)
2219 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2224 rvm_asmins_t rvm_asmf(rword opcode, rword op1, rword op2, rword op3, rword data)
2226 return rvm_cond_asmf(0, opcode, op1, op2, op3, data);
2230 rvm_asmins_t rvm_cond_asm(rword cond, rword opcode, rword op1, rword op2, rword op3, rword data)
2234 r_memset(&a, 0, sizeof(a));
2235 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2236 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2237 a.op1 = (ruint8)op1;
2238 a.op2 = (ruint8)op2;
2239 a.op3 = (ruint8)op3;
2241 rvm_reg_setunsigned(&a.data, data);
2242 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2248 rvm_asmins_t rvm_asm(rword opcode, rword op1, rword op2, rword op3, rword data)
2250 return rvm_cond_asm(0, opcode, op1, op2, op3, data);
2255 rvm_asmins_t rvm_cond_asml(rword cond, rword opcode, rword op1, rword op2, rword op3, rlong data)
2259 r_memset(&a, 0, sizeof(a));
2260 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2261 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2262 a.op1 = (ruint8)op1;
2263 a.op2 = (ruint8)op2;
2264 a.op3 = (ruint8)op3;
2266 rvm_reg_setlong(&a.data, data);
2267 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2273 rvm_asmins_t rvm_asml(rword opcode, rword op1, rword op2, rword op3, rlong data)
2275 return rvm_cond_asml(0, opcode, op1, op2, op3, data);
2279 rvm_asmins_t rvm_cond_asmb(rword cond, rword opcode, rword op1, rword op2, rword op3, ruint data)
2283 r_memset(&a, 0, sizeof(a));
2284 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2285 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2286 a.op1 = (ruint8)op1;
2287 a.op2 = (ruint8)op2;
2288 a.op3 = (ruint8)op3;
2290 rvm_reg_setboolean(&a.data, data);
2291 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2297 rvm_asmins_t rvm_asmb(rword opcode, rword op1, rword op2, rword op3, ruint data)
2299 return rvm_cond_asmb(0, opcode, op1, op2, op3, data);
2303 rvm_asmins_t rvm_cond_asmd(rword cond, rword opcode, rword op1, rword op2, rword op3, rdouble data)
2307 r_memset(&a, 0, sizeof(a));
2308 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2309 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2310 a.op1 = (ruint8)op1;
2311 a.op2 = (ruint8)op2;
2312 a.op3 = (ruint8)op3;
2314 rvm_reg_setdouble(&a.data, data);
2315 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2320 rvm_asmins_t rvm_asmd(rword opcode, rword op1, rword op2, rword op3, rdouble data)
2322 return rvm_cond_asmd(0, opcode, op1, op2, op3, data);
2326 rvm_asmins_t rvm_cond_asm2(rword cond, rword opcode, rword op1, rword op2, rword op3, ruint32 p1, ruint32 p2)
2330 r_memset(&a, 0, sizeof(a));
2331 a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
2332 a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
2333 a.op1 = (ruint8)op1;
2334 a.op2 = (ruint8)op2;
2335 a.op3 = (ruint8)op3;
2337 rvm_reg_setpair(&a.data, p1, p2);
2338 if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
2344 rvm_asmins_t rvm_asm2(rword opcode, rword op1, rword op2, rword op3, ruint32 p1, ruint32 p2)
2346 return rvm_cond_asm2(0, opcode, op1, op2, op3, p1, p2);
2349 rvmreg_t *rvm_cpu_alloc_global(rvmcpu_t *cpu)
2352 rint index = r_carray_add(cpu->data, NULL);
2354 global = (rvmreg_t*)r_carray_slot(cpu->data, index);
2355 RVM_REG_CLEAR(global);
2356 RVM_REG_SETTYPE(global, RVM_DTYPE_UNDEF);
2361 int rvm_cpu_setreg(rvmcpu_t *cpu, rword regnum, const rvmreg_t *src)
2365 RVM_CPUREG_SET(cpu, regnum, *src);
2370 rvmreg_t *rvm_cpu_getreg(rvmcpu_t *cpu, rword regnum)
2374 return RVM_CPUREG_PTR(cpu, regnum);