RPA Toolkit
redefined the RVM branch instructions and add RVM_BXL
authorMartin Stoilov <martin@rpasearch.com>
Sat, 12 Feb 2011 06:35:32 +0000 (22:35 -0800)
committerMartin Stoilov <martin@rpasearch.com>
Sat, 12 Feb 2011 06:35:32 +0000 (22:35 -0800)
rvm/rvmcpu.c
rvm/rvmcpu.h
tests/rpagen-test.c

index 4905d63..8d52f7c 100644 (file)
@@ -65,6 +65,7 @@ static const char *stropcalls[] = {
        "RVM_MOD",
        "RVM_MODS",
        "RVM_BX",
+       "RVM_BXL",
        "RVM_BL",
        "RVM_B",
        "RVM_STR",
@@ -167,12 +168,13 @@ static void rvm_op_b(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rword pc = 0;
 
-       if (ins->op1 != XX)
-               pc += RVM_CPUREG_GETU(cpu, ins->op1);
-       if (ins->op2 != XX)
-               pc += RVM_CPUREG_GETU(cpu, ins->op2);
-       if (ins->op3 != XX)
-               pc += RVM_CPUREG_GETU(cpu, ins->op3);
+//     if (ins->op1 != XX)
+//             pc += RVM_CPUREG_GETU(cpu, ins->op1);
+//     if (ins->op2 != XX)
+//             pc += RVM_CPUREG_GETU(cpu, ins->op2);
+//     if (ins->op3 != XX)
+//             pc += RVM_CPUREG_GETU(cpu, ins->op3);
+       pc += RVM_CPUREG_GETU(cpu, ins->op1);
        RVM_CPUREG_INCIP(cpu, PC, pc - 1);
 }
 
@@ -182,12 +184,13 @@ static void rvm_op_beq(rvmcpu_t *cpu, rvm_asmins_t *ins)
        rword pc = 0;
 
        if ((cpu->status & RVM_STATUS_Z)) {
-               if (ins->op1 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op1);
-               if (ins->op2 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op2);
-               if (ins->op3 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op3);
+//             if (ins->op1 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op1);
+//             if (ins->op2 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op2);
+//             if (ins->op3 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op3);
+               pc += RVM_CPUREG_GETU(cpu, ins->op1);
                RVM_CPUREG_INCIP(cpu, PC, pc - 1);
        }
 }
@@ -198,12 +201,13 @@ static void rvm_op_bneq(rvmcpu_t *cpu, rvm_asmins_t *ins)
        rword pc = 0;
 
        if ((cpu->status & RVM_STATUS_Z) == 0) {
-               if (ins->op1 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op1);
-               if (ins->op2 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op2);
-               if (ins->op3 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op3);
+//             if (ins->op1 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op1);
+//             if (ins->op2 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op2);
+//             if (ins->op3 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op3);
+               pc += RVM_CPUREG_GETU(cpu, ins->op1);
                RVM_CPUREG_INCIP(cpu, PC, pc - 1);
        }
 }
@@ -214,12 +218,13 @@ static void rvm_op_bleq(rvmcpu_t *cpu, rvm_asmins_t *ins)
        rword pc = 0;
 
        if ((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z)) {
-               if (ins->op1 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op1);
-               if (ins->op2 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op2);
-               if (ins->op3 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op3);
+//             if (ins->op1 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op1);
+//             if (ins->op2 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op2);
+//             if (ins->op3 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op3);
+               pc += RVM_CPUREG_GETU(cpu, ins->op1);
                RVM_CPUREG_INCIP(cpu, PC, pc - 1);
        }
 }
@@ -229,12 +234,13 @@ static void rvm_op_bgeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
        rword pc = 0;
 
        if ((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1){
-               if (ins->op1 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op1);
-               if (ins->op2 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op2);
-               if (ins->op3 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op3);
+//             if (ins->op1 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op1);
+//             if (ins->op2 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op2);
+//             if (ins->op3 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op3);
+               pc += RVM_CPUREG_GETU(cpu, ins->op1);
                RVM_CPUREG_INCIP(cpu, PC, pc - 1);
        }
 }
@@ -245,13 +251,14 @@ static void rvm_op_bles(rvmcpu_t *cpu, rvm_asmins_t *ins)
        rword pc = 0;
 
 
-       if ((cpu->status & RVM_STATUS_N)){
-               if (ins->op1 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op1);
-               if (ins->op2 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op2);
-               if (ins->op3 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op3);
+       if ((cpu->status & RVM_STATUS_N)) {
+//             if (ins->op1 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op1);
+//             if (ins->op2 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op2);
+//             if (ins->op3 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op3);
+               pc += RVM_CPUREG_GETU(cpu, ins->op1);
                RVM_CPUREG_INCIP(cpu, PC, pc - 1);
        }
 }
@@ -262,12 +269,13 @@ static void rvm_op_bgre(rvmcpu_t *cpu, rvm_asmins_t *ins)
        rword pc = 0;
 
        if ((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0) {
-               if (ins->op1 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op1);
-               if (ins->op2 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op2);
-               if (ins->op3 != XX)
-                       pc += RVM_CPUREG_GETU(cpu, ins->op3);
+//             if (ins->op1 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op1);
+//             if (ins->op2 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op2);
+//             if (ins->op3 != XX)
+//                     pc += RVM_CPUREG_GETU(cpu, ins->op3);
+               pc += RVM_CPUREG_GETU(cpu, ins->op1);
                RVM_CPUREG_INCIP(cpu, PC, pc - 1);
        }
 }
@@ -279,16 +287,24 @@ static void rvm_op_bx(rvmcpu_t *cpu, rvm_asmins_t *ins)
 }
 
 
+static void rvm_op_bxl(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
+       RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
+}
+
+
 static void rvm_op_bl(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rword pc = 0;
-       if (ins->op1 != XX)
-               pc += RVM_CPUREG_GETU(cpu, ins->op1);
-       if (ins->op2 != XX)
-               pc += RVM_CPUREG_GETU(cpu, ins->op2);
-       if (ins->op3 != XX)
-               pc += RVM_CPUREG_GETU(cpu, ins->op3);
 
+//     if (ins->op1 != XX)
+//             pc += RVM_CPUREG_GETU(cpu, ins->op1);
+//     if (ins->op2 != XX)
+//             pc += RVM_CPUREG_GETU(cpu, ins->op2);
+//     if (ins->op3 != XX)
+//             pc += RVM_CPUREG_GETU(cpu, ins->op3);
+       pc += RVM_CPUREG_GETU(cpu, ins->op1);
        RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
        RVM_CPUREG_INCIP(cpu, PC, pc - 1);
 }
@@ -646,7 +662,7 @@ static void rvm_op_call(rvmcpu_t *cpu, rvm_asmins_t *ins)
                RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
                rvm_op_swiid(cpu, ins);
        } else if (RVM_REG_GETTYPE(arg1) == RVM_DTYPE_FUNCTION) {
-               rvm_op_bl(cpu, ins);
+               rvm_op_bxl(cpu, ins);
        } else {
                RVM_ABORT(cpu, RVM_E_NOTFUNCTION);
        }
@@ -1702,6 +1718,7 @@ static rvm_cpu_op ops[] = {
        rvm_op_mod,                     // RVM_MOD
        rvm_op_mods,            // RVM_MODS
        rvm_op_bx,                      // RVM_BX
+       rvm_op_bxl,                     // RVM_BXL
        rvm_op_bl,                      // RVM_BL
        rvm_op_b,                       // RVM_B
        rvm_op_str,                     // RVM_STR
index 72b6294..1953626 100644 (file)
@@ -65,6 +65,7 @@ enum {
        RVM_MOD,                /* Modulo: op1 = op2 % op3 */
        RVM_MODS,               /* Modulo: op1 = op2 % op3, Update the status register */
        RVM_BX,                 /* Jump to op1 */
+       RVM_BXL,                /* Jump to op1, link */
        RVM_BL,                 /* Branch Link */
        RVM_B,                  /* Branch */
        RVM_STR,                /* Save: val_at_location(op2) = op1 */
index 40ed677..b902e8d 100644 (file)
@@ -1115,7 +1115,7 @@ int codegen_funcallexpression_callback(rpa_stat_handle stat, const char *name, v
                rvm_funcall_t *funcall = r_array_empty(co->funcall) ? NULL : (rvm_funcall_t *) r_array_slot(co->funcall, r_array_length(co->funcall) - 1);
 
                rvm_codegen_addins(co->cg, rvm_asm(RVM_SUB, FP, SP, DA, funcall->params));
-               rvm_codegen_addins(co->cg, rvm_asm(RVM_CALL, R0, DA, XX, -rvm_codegen_getcodesize(co->cg)));
+               rvm_codegen_addins(co->cg, rvm_asm(RVM_CALL, R0, XX, XX, 0));
                rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, SP, FP, XX, 0));
                rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, DA, XX, XX, BITS(TP,LR)));
                r_array_removelast(co->funcall);
@@ -1188,8 +1188,6 @@ int codegen_fundeclname_callback(rpa_stat_handle stat, const char *name, void *u
        rvm_codegen_addins(co->cg, rvm_asm(RVM_B, DA, XX, XX, 0));              /* Will be re-written later */
        rvm_codegen_addins(co->cg, rvm_asm(RVM_ADD, SP, FP, DA, 0));    /* Will be re-written later */
        rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
-       rvm_codegen_addins(co->cg, rvm_asm(RVM_NOP, XX, XX, XX, 0xffffffff));
 
        r_array_push(co->fp, 0, rword);
        r_array_add(co->fundecl, &fundecl);
@@ -1227,7 +1225,7 @@ int codegen_fundecl_callback(rpa_stat_handle stat, const char *name, void *userd
        } else {
                rvm_codegen_replaceins(co->cg, fundecl->codestart + 0, rvm_asmp(RVM_MOV, R1, DA, XX, fname->data.ptr));
        }
-       rvm_codegen_replaceins(co->cg, fundecl->codestart + 1, rvm_asm(RVM_MOV, R0, DA, XX, fundecl->codestart + 5));
+       rvm_codegen_replaceins(co->cg, fundecl->codestart + 1, rvm_asm(RVM_ADD, R0, PC, DA, sizeof(rvm_asmins_t) * 3));
        rvm_codegen_replaceins(co->cg, fundecl->codestart + 2, rvm_asm(RVM_SETTYPE, R0, DA, XX, RVM_DTYPE_FUNCTION));
        rvm_codegen_replaceins(co->cg, fundecl->codestart + 3, rvm_asm(RVM_STRR, R0, R1, XX, 0));
        rvm_codegen_replaceins(co->cg, fundecl->codestart + 4, rvm_asm(RVM_B, DA, XX, XX, fundecl->codesize - 4));