RPA Toolkit
modified codemap lookup
authorMartin Stoilov <martin@rpasearch.com>
Mon, 14 Feb 2011 06:39:38 +0000 (22:39 -0800)
committerMartin Stoilov <martin@rpasearch.com>
Mon, 14 Feb 2011 06:39:38 +0000 (22:39 -0800)
rvm/rvmcodemap.c
rvm/rvmcodemap.h
rvm/rvmcpu.c
rvm/rvmcpu.h
tests/codegen-test.c
tests/funcarg-test.c
tests/regex-test.c

index a674c8d..3590af9 100644 (file)
@@ -72,11 +72,19 @@ void rvm_codemap_clear(rvm_codemap_t *codemap)
 }
 
 
-void rvm_codemap_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rulong index)
+static rvm_codelabel_t *rvm_codemap_dolookup(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
+{
+       rstr_t lookupstr = {(char*)name, namesize};
+       return (rvm_codelabel_t *)r_hash_lookup(codemap->hash, &lookupstr);
+}
+
+
+
+rvm_codelabel_t *rvm_codemap_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rulong index)
 {
        rvm_codelabel_t *label;
 
-       label = rvm_codemap_lookup(codemap, name, namesize);
+       label = rvm_codemap_dolookup(codemap, name, namesize);
        if (!label) {
                label = r_malloc(sizeof(*label));
                label->name = r_rstrdup(name, namesize);
@@ -84,24 +92,25 @@ void rvm_codemap_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize,
                r_array_add(codemap->labels, &label);
        }
        label->index = index;
+       return label;
 }
 
 
-void rvm_codemap_add_s(rvm_codemap_t *codemap, const rchar *name, rulong index)
+rvm_codelabel_t *rvm_codemap_add_s(rvm_codemap_t *codemap, const rchar *name, rulong index)
 {
-       rvm_codemap_add(codemap, name, r_strlen(name), index);
+       return rvm_codemap_add(codemap, name, r_strlen(name), index);
 }
 
 
-void rvm_codemap_invalid_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
+rvm_codelabel_t *rvm_codemap_invalid_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
 {
-       rvm_codemap_add(codemap, name, namesize, RVM_CODELABEL_INVALID);
+       return rvm_codemap_add(codemap, name, namesize, RVM_CODELABEL_INVALID);
 }
 
 
-void rvm_codemap_invalid_add_s(rvm_codemap_t *codemap, const rchar *name)
+rvm_codelabel_t *rvm_codemap_invalid_add_s(rvm_codemap_t *codemap, const rchar *name)
 {
-       rvm_codemap_invalid_add(codemap, name, r_strlen(name));
+       return rvm_codemap_invalid_add(codemap, name, r_strlen(name));
 }
 
 
@@ -113,10 +122,15 @@ rvm_codelabel_t *rvm_codemap_lastlabel(rvm_codemap_t *codemap)
        return NULL;
 }
 
+
 rvm_codelabel_t *rvm_codemap_lookup(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
 {
        rstr_t lookupstr = {(char*)name, namesize};
-       return (rvm_codelabel_t*) r_hash_lookup(codemap->hash, &lookupstr);
+       rvm_codelabel_t *label = (rvm_codelabel_t *)r_hash_lookup(codemap->hash, &lookupstr);
+
+       if (!label)
+               label = rvm_codemap_invalid_add(codemap, name, namesize);
+       return label;
 }
 
 
index a664fe5..58b19b0 100644 (file)
@@ -36,10 +36,10 @@ typedef struct rvm_codemap_s {
 rvm_codemap_t *rvm_codemap_create();
 void rvm_codemap_destroy(rvm_codemap_t *codemap);
 void rvm_codemap_clear(rvm_codemap_t *codemap);
-void rvm_codemap_invalid_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize);
-void rvm_codemap_invalid_add_s(rvm_codemap_t *codemap, const rchar *name);
-void rvm_codemap_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rulong index);
-void rvm_codemap_add_s(rvm_codemap_t *codemap, const rchar *name, rulong index);
+rvm_codelabel_t *rvm_codemap_invalid_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize);
+rvm_codelabel_t *rvm_codemap_invalid_add_s(rvm_codemap_t *codemap, const rchar *name);
+rvm_codelabel_t *rvm_codemap_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize, rulong index);
+rvm_codelabel_t *rvm_codemap_add_s(rvm_codemap_t *codemap, const rchar *name, rulong index);
 rvm_codelabel_t *rvm_codemap_lookup(rvm_codemap_t *codemap, const rchar *name, ruint namesize);
 rvm_codelabel_t *rvm_codemap_lookup_s(rvm_codemap_t *codemap, const rchar *name);
 rvm_codelabel_t *rvm_codemap_lastlabel(rvm_codemap_t *codemap);
index 8d52f7c..6ead029 100644 (file)
@@ -65,6 +65,8 @@ static const char *stropcalls[] = {
        "RVM_MOD",
        "RVM_MODS",
        "RVM_BX",
+       "RVM_BXEQ",
+       "RVM_BXNEQ",
        "RVM_BXL",
        "RVM_BL",
        "RVM_B",
@@ -287,6 +289,22 @@ static void rvm_op_bx(rvmcpu_t *cpu, rvm_asmins_t *ins)
 }
 
 
+static void rvm_op_bxeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       if ((cpu->status & RVM_STATUS_Z)) {
+               RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
+       }
+}
+
+
+static void rvm_op_bxneq(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       if (!(cpu->status & RVM_STATUS_Z)) {
+               RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, ins->op1));
+       }
+}
+
+
 static void rvm_op_bxl(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
@@ -1718,6 +1736,8 @@ static rvm_cpu_op ops[] = {
        rvm_op_mod,                     // RVM_MOD
        rvm_op_mods,            // RVM_MODS
        rvm_op_bx,                      // RVM_BX
+       rvm_op_bxeq,            // RVM_BXEQ
+       rvm_op_bxneq,           // RVM_BXNEQ
        rvm_op_bxl,                     // RVM_BXL
        rvm_op_bl,                      // RVM_BL
        rvm_op_b,                       // RVM_B
index 1953626..27e012c 100644 (file)
@@ -65,6 +65,8 @@ enum {
        RVM_MOD,                /* Modulo: op1 = op2 % op3 */
        RVM_MODS,               /* Modulo: op1 = op2 % op3, Update the status register */
        RVM_BX,                 /* Jump to op1 */
+       RVM_BXEQ,               /* Jump to op1, if equal */
+       RVM_BXNEQ,              /* Jump to op1, if not equal */
        RVM_BXL,                /* Jump to op1, link */
        RVM_BL,                 /* Branch Link */
        RVM_B,                  /* Branch */
@@ -235,7 +237,7 @@ do { \
                                                        (BITR(__f__, __l__, R28)) | (BITR(__f__, __l__, R29)) | (BITR(__f__, __l__, R30)) | (BITR(__f__, __l__, R31))
 
 #define RVM_OPCODE_BITS 8
-#define RVM_SWI_TABLE_BITS 10
+#define RVM_SWI_TABLE_BITS 8
 #define RVM_SWI_NUM_BITS 8
 #define RVM_SWI_TABLE(__op__) ((__op__) >> RVM_SWI_NUM_BITS)
 #define RVM_SWI_NUM(__op__) ((__op__) & ((1 << RVM_SWI_NUM_BITS) - 1))
@@ -290,8 +292,8 @@ struct rvm_asmins_s {
        ruint16 op3:RVM_OPERAND_BITS;
        ruint16 da:1;
        ruint32 opcode:8;
-       ruint32 swi:18;
-       ruint32 type:3;
+       ruint32 swi:(RVM_SWI_TABLE_BITS + RVM_SWI_NUM_BITS);
+       ruint32 type:5;
        ruint32 flags:3;
 };
 
index 5dce439..95aaac3 100644 (file)
@@ -27,10 +27,6 @@ int main(int argc, char *argv[])
        cpu = rvm_cpu_create_default();
        ntable = rvm_cpu_addswitable(cpu, switable);
 
-       rvm_codemap_invalid_add_s(cg->codemap, "add2");
-       rvm_codemap_invalid_add_s(cg->codemap, "add3");
-       rvm_codemap_invalid_add_s(cg->codemap, "varadd");
-
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, R0, DA, XX, 7));
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R0, SP, DA, 1 + RVM_CODEGEN_FUNCINITOFFSET));
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, R0, DA, XX, 8));
index d9753ad..9533005 100644 (file)
@@ -39,8 +39,6 @@ int main(int argc, char *argv[])
        cpu = rvm_cpu_create_default();
        ntable = rvm_cpu_addswitable(cpu, switable);
 
-       rvm_codemap_invalid_add_s(cg->codemap, "add2");
-
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, R0, DA, XX, 7));
        rvm_codegen_addins(cg, rvm_asm(RVM_STS, R0, SP, DA, 1 + RVM_CODEGEN_FUNCINITOFFSET));
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, R0, DA, XX, 8));
index 169b9f2..16d30d0 100644 (file)
@@ -175,7 +175,6 @@ static void rpa_matchchr(rvmcpu_t *cpu, rvm_asmins_t *ins)
        if (flags == RPA_MATCH_OPTIONAL) {
                RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, (!(cpu->status & RVM_STATUS_V) && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) ? 1 : 0);
                rpa_eqshift(cpu, ins);
-               RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, 1);
        } else if (flags == RPA_MATCH_MULTIPLE) {
                RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, (!(cpu->status & RVM_STATUS_V) && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) ? 1 : 0);
                if (cpu->status & RVM_STATUS_Z)
@@ -183,14 +182,20 @@ static void rpa_matchchr(rvmcpu_t *cpu, rvm_asmins_t *ins)
                while (!(cpu->status & RVM_STATUS_V) && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) {
                        rpa_shift(cpu, ins);
                }
+//             if (!(cpu->status & RVM_STATUS_Z))
+//                     RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, LR));
        } else if (flags == RPA_MATCH_MULTIOPT) {
+               ruint matched = 0;
                while (!(cpu->status & RVM_STATUS_V) && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) {
+                       matched = 1;
                        rpa_shift(cpu, ins);
                }
-               RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, 1);
+               RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, matched);
        } else {
                RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, (!(cpu->status & RVM_STATUS_V) && stat->instack[RVM_CPUREG_GETL(cpu, TP)].wc == wc) ? 1 : 0);
                rpa_eqshift(cpu, ins);
+//             if (!(cpu->status & RVM_STATUS_Z))
+//                     RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, LR));
        }
 }
 
@@ -261,17 +266,36 @@ void codegen_rpa_match(rpa_compiler_t *co)
        rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
        l2 = rvm_codegen_getcodesize(co->cg);
        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_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(TP)|BIT(FP)|BIT(SP)|BIT(LR)));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_BXL, 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(FP,LR)));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_MOV, R0, DA, XX, BITS(FP,LR)));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_BEQ, DA, XX, XX, 2));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_ORR, R0, R0, DA, BIT(TP)));
+       rvm_codegen_addins(co->cg, rvm_asm(RVM_POPM, R0, XX, XX, 0));
        rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
        off = rvm_codegen_getcodesize(co->cg);
        rvm_codegen_replaceins(co->cg, l2, rvm_asm(RVM_B, DA, XX, XX, off - l2));
 }
 
 
+void codegen_rpa_match_char(rpa_compiler_t *co, rword wc, rchar q)
+{
+       if (q == '?') {
+               rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR, DA, R_OPT, XX, wc));
+       } else if (q == '+') {
+               rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR, DA, R_MUL, XX, wc));
+               rvm_codegen_addins(co->cg, rvm_asm(RVM_BXNEQ, LR, XX, XX, 0));
+       } else if (q == '*') {
+               rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR, DA, R_MOP, XX, wc));
+       } else {
+               rvm_codegen_addins(co->cg, rvm_asm(RPA_MATCHCHR, DA, R_NAN, XX, wc));
+               rvm_codegen_addins(co->cg, rvm_asm(RVM_BXNEQ, LR, XX, XX, 0));
+       }
+}
+
+
 void codegen_rpa_match_abc(rpa_compiler_t *co)
 {
        rulong off, l1, l2;
@@ -284,9 +308,9 @@ void codegen_rpa_match_abc(rpa_compiler_t *co)
        rvm_codegen_addins(co->cg, rvm_asm(RVM_STRR, R0, R1, XX, 0));
        l2 = rvm_codegen_getcodesize(co->cg);
        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(RPA_MATCHCHR, DA, R_NAN, XX, 'a'));
-       rvm_codegen_addins(co->cg, rvm_asm(RPA_EQMATCHCHR, DA, R_MUL, XX, 'b'));
-       rvm_codegen_addins(co->cg, rvm_asm(RPA_EQMATCHCHR, DA, R_NAN, XX, 'c'));
+       codegen_rpa_match_char(co, 'a', ' ');
+       codegen_rpa_match_char(co, 'b', '?');
+       codegen_rpa_match_char(co, 'c', '+');
        rvm_codegen_addins(co->cg, rvm_asm(RVM_BX, LR, XX, XX, 0));
        off = rvm_codegen_getcodesize(co->cg);
        rvm_codegen_replaceins(co->cg, l2, rvm_asm(RVM_B, DA, XX, XX, off - l2));
@@ -298,9 +322,7 @@ void codegen_rpa_match_abc(rpa_compiler_t *co)
 int main(int argc, char *argv[])
 {
        rvmcpu_t *cpu;
-       rvm_asmins_t code[1024];
        rpa_compiler_t *co;
-       ruint off = 0;
        rint i;
 
        co = rpa_compiler_create();