RPA Toolkit
merge the BNF branch to trunk.
authorMartin Stoilov <martin@rpasearch.com>
Wed, 29 Dec 2010 04:17:51 +0000 (20:17 -0800)
committerMartin Stoilov <martin@rpasearch.com>
Wed, 29 Dec 2010 04:17:51 +0000 (20:17 -0800)
119 files changed:
rlib/build/linux/rlib.mk
rlib/rarray.c
rlib/rarray.h
rlib/rcarray.c [new file with mode: 0644]
rlib/rcarray.h [new file with mode: 0644]
rlib/rharray.c
rlib/rharray.h
rlib/rhash.c
rlib/rhash.h
rlib/rmath.c [new file with mode: 0644]
rlib/rmath.h [new file with mode: 0644]
rlib/robject.c
rlib/robject.h
rlib/rref.c
rlib/rref.h
rlib/rstring.c
rlib/rstring.h
rpa/rpamnode.c
rpatest/cache.in [new file with mode: 0644]
rpatest/cache.out [new file with mode: 0644]
rpatest/cache.rpa [new file with mode: 0644]
rpatest/cache.sh [new file with mode: 0755]
rpatest/common.def [new file with mode: 0644]
rpatest/loop.in [new file with mode: 0644]
rpatest/loop.out [new file with mode: 0644]
rpatest/loop.rpa [new file with mode: 0644]
rpatest/loop.sh [new file with mode: 0755]
rpatest/multiloop.in [new file with mode: 0644]
rpatest/multiloop.out [new file with mode: 0644]
rpatest/multiloop.rpa [new file with mode: 0644]
rpatest/multiloop.sh [new file with mode: 0755]
rpatest/template/newrpatest.sh [new file with mode: 0755]
rvm/build/linux/rvm.mk
rvm/rrefreg.c [deleted file]
rvm/rrefreg.h [deleted file]
rvm/rvmcodegen.c
rvm/rvmcodegen.h
rvm/rvmcodemap.c
rvm/rvmcodemap.h
rvm/rvmcpu.c
rvm/rvmcpu.h
rvm/rvmgc.c [new file with mode: 0644]
rvm/rvmgc.h [new file with mode: 0644]
rvm/rvmoperator.c
rvm/rvmoperator.h
rvm/rvmoperatoradd.c
rvm/rvmoperatoradd.h
rvm/rvmoperatorand.c
rvm/rvmoperatorand.h [new file with mode: 0644]
rvm/rvmoperatorbin.c [new file with mode: 0644]
rvm/rvmoperatorbin.h [new file with mode: 0644]
rvm/rvmoperatorcast.c
rvm/rvmoperatorcast.h
rvm/rvmoperatorcat.c
rvm/rvmoperatorcat.h
rvm/rvmoperatorcmn.c
rvm/rvmoperatorcmn.h [new file with mode: 0644]
rvm/rvmoperatorcmp.c
rvm/rvmoperatorcmp.h [new file with mode: 0644]
rvm/rvmoperatordiv.c
rvm/rvmoperatordiv.h
rvm/rvmoperatoreq.c [new file with mode: 0644]
rvm/rvmoperatoreq.h [new file with mode: 0644]
rvm/rvmoperatorgreater.c [new file with mode: 0644]
rvm/rvmoperatorgreater.h [new file with mode: 0644]
rvm/rvmoperatorgreatereq.c [new file with mode: 0644]
rvm/rvmoperatorgreatereq.h [new file with mode: 0644]
rvm/rvmoperatorless.c [new file with mode: 0644]
rvm/rvmoperatorless.h [new file with mode: 0644]
rvm/rvmoperatorlesseq.c [new file with mode: 0644]
rvm/rvmoperatorlesseq.h [new file with mode: 0644]
rvm/rvmoperatorlogicand.c [new file with mode: 0644]
rvm/rvmoperatorlogicand.h [new file with mode: 0644]
rvm/rvmoperatorlogicnot.c [new file with mode: 0644]
rvm/rvmoperatorlogicnot.h [new file with mode: 0644]
rvm/rvmoperatorlogicor.c [new file with mode: 0644]
rvm/rvmoperatorlogicor.h [new file with mode: 0644]
rvm/rvmoperatorlsl.c
rvm/rvmoperatorlsl.h [new file with mode: 0644]
rvm/rvmoperatorlsr.c
rvm/rvmoperatorlsr.h [new file with mode: 0644]
rvm/rvmoperatorlsru.c [new file with mode: 0644]
rvm/rvmoperatorlsru.h [new file with mode: 0644]
rvm/rvmoperatormod.c [new file with mode: 0644]
rvm/rvmoperatormod.h [new file with mode: 0644]
rvm/rvmoperatormul.c
rvm/rvmoperatormul.h
rvm/rvmoperatornot.c
rvm/rvmoperatornot.h [new file with mode: 0644]
rvm/rvmoperatornoteq.c [new file with mode: 0644]
rvm/rvmoperatornoteq.h [new file with mode: 0644]
rvm/rvmoperatoror.c
rvm/rvmoperatoror.h [new file with mode: 0644]
rvm/rvmoperatorsub.c
rvm/rvmoperatorsub.h
rvm/rvmoperatorxor.c
rvm/rvmoperatorxor.h [new file with mode: 0644]
rvm/rvmreg.c
rvm/rvmreg.h
rvm/rvmscope.c
rvm/rvmscope.h
tests/asm-cast.c
tests/asm-eadd.c
tests/asm-esub.c
tests/asm-stack.c
tests/build/linux/robject-tests.mk
tests/common.h
tests/ecma262.rpa [new file with mode: 0644]
tests/ecma262org.rpa [new file with mode: 0644]
tests/ecma262q.rpa [new file with mode: 0644]
tests/funcarg-test.c
tests/loop-test.c
tests/opmap-test.c
tests/rarray-test.c
tests/rcarray-test.c [new file with mode: 0644]
tests/rharray-test.c
tests/rhash-test.c
tests/rpagen-test.c
tests/string-test.c

index c747f55..f7f4fdf 100644 (file)
@@ -6,14 +6,15 @@ RLIB_SO = $(OUTDIR)/librlib.so.1.0
 RLIB_OBJECTS +=        $(OUTDIR)/rref.o
 RLIB_OBJECTS +=        $(OUTDIR)/robject.o
 RLIB_OBJECTS +=        $(OUTDIR)/rmem.o
+RLIB_OBJECTS +=        $(OUTDIR)/rmath.o
 RLIB_OBJECTS +=        $(OUTDIR)/ratomic.o
 RLIB_OBJECTS +=        $(OUTDIR)/rspinlock.o
 RLIB_OBJECTS +=        $(OUTDIR)/rharray.o
+RLIB_OBJECTS +=        $(OUTDIR)/rcarray.o
 RLIB_OBJECTS +=        $(OUTDIR)/rarray.o
 RLIB_OBJECTS +=        $(OUTDIR)/rhash.o
 RLIB_OBJECTS +=        $(OUTDIR)/rstring.o
 RLIB_OBJECTS +=        $(OUTDIR)/rlist.o
-RLIB_OBJECTS +=        $(OUTDIR)/rgc.o
 
 
 ifeq ($(OS), linux)
index 80331cc..3b373fc 100644 (file)
@@ -1,97 +1,61 @@
 #include "rarray.h"
 #include "rmem.h"
 
-#define MIN_ARRAY_LEN 2
-
-#if 0
-
-/*
- * Returns the smallest power of 2 greater than n
- */
-static ruint r_nearest_pow (ruint num)
-{
-       ruint n = 1;
-
-       while (n < num && n > 0)
-               n <<= 1;
-       return n ? n : num;
-}
-#endif
 
+#define MIN_ARRAY_LEN 2
 
 static void r_array_checkexpand(rarray_t *array, ruint index);
 
 
-static void r_array_cleanup(rarray_t *array)
+void r_array_cleanup(robject_t *obj)
 {
-       if (array->ondestroy)
-               array->ondestroy(array);
+       rarray_t *array = (rarray_t *)obj;
+       if (array->oncleanup)
+               array->oncleanup(array);
        r_free(array->data);
+       r_object_cleanup((robject_t*)array);
 }
 
 
-static rarray_t *r_array_init(rarray_t *array, ruint elt_size)
+robject_t *r_array_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy, ruint elt_size)
 {
-       r_memset(array, 0, sizeof(*array));
+       rarray_t *array = (rarray_t*)obj;
+
+       r_object_init(obj, type, cleanup, copy);
        array->elt_size = elt_size;
        array->data = r_zmalloc(MIN_ARRAY_LEN * array->elt_size);
-       array->alloc_len = MIN_ARRAY_LEN;
-       if (!array->data)
-               return NULL;
-       return array;
-}
-
-
-void r_array_destroy(rarray_t *array)
-{
-       r_array_cleanup(array);
-       r_free(array);
-}
-
-
-static void r_objectstub_destroy(robject_t *ptr)
-{
-       r_array_destroy((rarray_t*)ptr);
-}
-
-
-static robject_t *r_objectstub_copy(const robject_t *ptr)
-{
-       return (robject_t*) r_array_copy((const rarray_t*)ptr);
+       array->alloc_size = MIN_ARRAY_LEN;
+       return obj;
 }
 
 
 rarray_t *r_array_create(ruint elt_size)
 {
        rarray_t *array;
-       if ((array = (rarray_t*)r_malloc(sizeof(*array))) == NULL)
-               return NULL;
-       if (!r_array_init(array, elt_size)) {
-               r_array_destroy(array);
-               return NULL;
-       }
-       r_object_init(&array->obj, R_OBJECT_ARRAY, r_objectstub_destroy, r_objectstub_copy);
+       array = (rarray_t*)r_object_create(sizeof(*array));
+       r_array_init((robject_t*)array, R_OBJECT_ARRAY, r_array_cleanup, r_array_copy, elt_size);
        return array;
 }
 
 
-rarray_t *r_array_copy(const rarray_t *array)
+robject_t *r_array_copy(const robject_t *obj)
 {
        ruint i;
        rarray_t *dst;
+       const rarray_t *array = (const rarray_t *)obj;
 
        if (!array)
                return NULL;
        dst = r_array_create(array->elt_size);
        if (!dst)
                return NULL;
-       for (i = 0; i < array->len; i++)
+       for (i = 0; i < r_array_length(array); i++)
                r_array_replace(dst, i, r_array_slot(array, i));
        dst->oncopy = array->oncopy;
-       dst->ondestroy = array->ondestroy;
+       dst->oncleanup = array->oncleanup;
        if (dst->oncopy)
                dst->oncopy(dst);
-       return dst;
+       return (robject_t *)dst;
 }
 
 
@@ -106,23 +70,30 @@ static void r_array_exist_replace(rarray_t *array, ruint index, rconstpointer da
 
 rint r_array_add(rarray_t *array, rconstpointer data)
 {
-       rint index = array->len;
+       rint index = r_array_length(array);
 
-       r_array_setsize(array, index + 1);
+       r_array_setlength(array, index + 1);
        r_array_exist_replace(array, index, data);
        return index;
 }
 
 
+rint r_array_remove(rarray_t *array)
+{
+       r_array_setlength(array, r_array_length(array) - 1);
+       return r_array_length(array);
+}
+
+
 rint r_array_insert(rarray_t *array, ruint index, rconstpointer data)
 {
        r_array_checkexpand(array, index + 1);
-       if (index < array->len) {
-               ruint curlen = r_array_size(array);
-               r_array_setsize(array, array->len + 1);
+       if (index < r_array_length(array)) {
+               ruint curlen = r_array_length(array);
+               r_array_setlength(array, r_array_length(array) + 1);
                r_memmove(r_array_slot(array, index + 1), r_array_slot(array, index), (curlen - index) * array->elt_size);
        } else {
-               r_array_setsize(array, index + 1);
+               r_array_setlength(array, index + 1);
        }
        r_array_exist_replace(array, index, data);
        return index;
@@ -131,37 +102,45 @@ rint r_array_insert(rarray_t *array, ruint index, rconstpointer data)
 
 rint r_array_replace(rarray_t *array, ruint index, rconstpointer data)
 {
-       if (index >= array->len)
+       if (index >= r_array_length(array))
                return r_array_insert(array, index, data);
        r_array_exist_replace(array, index, data);
        return index;
 }
 
 
-void r_array_setsize(rarray_t *array, ruint size)
+void r_array_setlength(rarray_t *array, ruint len)
 {
-       r_array_checkexpand(array, size);
-       array->len = size;
+       r_array_checkexpand(array, len);
+       array->len = len;
 }
 
 
-static void r_array_checkexpand(rarray_t *array, ruint size)
+static void r_array_checkexpand(rarray_t *array, ruint len)
 {
-       ruint nalloc_len;
+       ruint nalloc_size;
        rpointer data;
 
-       while (size > array->alloc_len) {
-               nalloc_len = 2 * array->alloc_len;
-               data = r_realloc(array->data, nalloc_len * array->elt_size);
+       if (array->alloc_size < len) {
+               for (nalloc_size = array->alloc_size; nalloc_size < len;)
+                       nalloc_size = 2 * nalloc_size + 1;
+               data = r_realloc(array->data, nalloc_size * array->elt_size);
                if (data) {
-                       ruint old_len = array->alloc_len;
+                       ruint old_len = array->alloc_size;
                        array->data = data;
-                       array->alloc_len = nalloc_len;
+                       array->alloc_size = nalloc_size;
 
                        /*
-                        * Zero the newly allocated memory - only the extension (above the alloc_len).
+                        * Zero the newly allocated memory - only the extension (above the alloc_size).
                         */
-                       r_memset((void*)r_array_slot(array, old_len), 0, (array->alloc_len - old_len) * array->elt_size);
+                       r_memset((void*)r_array_slot(array, old_len), 0, (array->alloc_size - old_len) * array->elt_size);
                }
        }
 }
+
+
+void *r_array_slot_expand(rarray_t *array, ruint index)
+{
+       r_array_checkexpand(array, index+1);
+       return (void*) r_array_slot(array, index);
+}
index 9404d6d..7c636f6 100644 (file)
@@ -4,6 +4,7 @@
 #include "rtypes.h"
 #include "robject.h"
 
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -15,26 +16,38 @@ struct rarray_s {
        robject_t obj;
        rpointer *data;
        ruint len;
-       ruint alloc_len;
+       ruint alloc_size;
        ruint elt_size;
-       r_array_callback ondestroy;
+       r_array_callback oncleanup;
        r_array_callback oncopy;
+       rpointer *user;
 };
 
-#define r_array_size(__array__) ((__array__)->len)
-#define r_array_empty(__array__) ((r_array_size(__array__)) ? 0 : 1)
+
+#define r_array_size(__array__) ((__array__)->alloc_size)
+#define r_array_length(__array__) ((__array__)->len)
+#define r_array_empty(__array__) ((r_array_length(__array__)) ? 0 : 1)
+#define r_array_last(__array__, __type__) (r_array_index(__array__, (__array__)->len - 1, __type__))
 #define r_array_index(__array__, __index__, __type__) (((__type__*)(void*)(__array__)->data)[__index__])
-#define r_array_last(__array__, __type__) (r_array_empty(__array__) ? (__type__)0 : r_array_index(__array__, (__array__)->len - 1, __type__))
 #define r_array_slot(__array__, __index__) (((ruint8*)(__array__)->data) + (__array__)->elt_size * (__index__))
+#define r_array_lastslot(__array__) r_array_slot(__array__, r_array_length(__array__) - 1)
+#define r_array_push(__array__, __val__, __type__) do {__type__ __v__ = (__type__)__val__; r_array_add(__array__, &__v__); } while(0)
+#define r_array_pop(__array__, __type__) (r_array_index(__array__, (__array__)->len ? --(__array__)->len : 0, __type__))
 
+robject_t *r_array_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy, ruint elt_size);
 rarray_t *r_array_create(ruint elt_size);
-rarray_t *r_array_copy(const rarray_t *array);
-void r_array_destroy(rarray_t *array);
 rint r_array_add(rarray_t *array, rconstpointer data);
+rint r_array_remove(rarray_t *array);
 rint r_array_insert(rarray_t *array, ruint index, rconstpointer data);
 rint r_array_replace(rarray_t *array, ruint index, rconstpointer data);
-void r_array_setsize(rarray_t *array, ruint size);
-
+void r_array_setlength(rarray_t *array, ruint len);
+void *r_array_slot_expand(rarray_t *array, ruint index);
+
+/*
+ * Virtual methods implementation
+ */
+void r_array_cleanup(robject_t *obj);
+robject_t *r_array_copy(const robject_t *obj);
 
 #ifdef __cplusplus
 }
diff --git a/rlib/rcarray.c b/rlib/rcarray.c
new file mode 100644 (file)
index 0000000..99c7576
--- /dev/null
@@ -0,0 +1,144 @@
+#include "rcarray.h"
+#include "rmem.h"
+
+#define MIN_CARRAY_LEN 2
+
+
+
+static void r_carray_checkexpand(rcarray_t *carray, ruint index);
+
+
+static rpointer r_carray_allocate_chunk(ruint elt_size)
+{
+       return r_zmalloc(R_CARRAY_CHUNKSIZE * elt_size);
+}
+
+
+static rpointer r_carray_get_chunk(const rcarray_t *carray, ruint nchunk)
+{
+       return r_array_index(carray->array, nchunk, rpointer);
+}
+
+
+static void r_carray_add_chunks(rcarray_t *carray, ruint nchunks)
+{
+       rpointer chunk;
+
+       while (nchunks) {
+               chunk = r_carray_allocate_chunk(carray->elt_size);
+               r_array_add(carray->array, &chunk);
+               carray->alloc_size += R_CARRAY_CHUNKSIZE;
+               --nchunks;
+       }
+}
+
+
+void r_carray_cleanup(robject_t *obj)
+{
+       int i;
+       rcarray_t *carray = (rcarray_t *)obj;
+       if (carray->oncleanup)
+               carray->oncleanup(carray);
+       for (i = 0; i < r_array_length(carray->array); i++)
+               r_free(r_carray_get_chunk(carray, i));
+       r_object_destroy((robject_t*)carray->array);
+       r_object_cleanup((robject_t*)carray);
+}
+
+
+robject_t *r_carray_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy, ruint elt_size)
+{
+       rcarray_t *carray = (rcarray_t*)obj;
+
+       r_object_init(obj, type, cleanup, copy);
+       carray->elt_size = elt_size;
+       carray->array = r_array_create(sizeof(rpointer));
+       carray->alloc_size = 0;
+       carray->len = 0;
+       r_carray_add_chunks(carray, 1);
+       return obj;
+}
+
+
+rcarray_t *r_carray_create(ruint elt_size)
+{
+       rcarray_t *carray;
+       carray = (rcarray_t*)r_object_create(sizeof(*carray));
+       r_carray_init((robject_t*)carray, R_OBJECT_CARRAY, r_carray_cleanup, r_carray_copy, elt_size);
+       return carray;
+}
+
+
+robject_t *r_carray_copy(const robject_t *obj)
+{
+       ruint i;
+       rcarray_t *dst;
+       const rcarray_t *carray = (const rcarray_t *)obj;
+
+       if (!carray)
+               return NULL;
+       dst = r_carray_create(carray->elt_size);
+       if (!dst)
+               return NULL;
+       r_carray_add_chunks(dst, r_array_length(carray->array));
+       for (i = 0; i < r_array_length(carray->array); i++)
+               r_memcpy(r_carray_get_chunk(dst, i), r_carray_get_chunk(carray, i), R_CARRAY_CHUNKSIZE * carray->elt_size);
+       dst->len = carray->len;
+       dst->oncopy = carray->oncopy;
+       dst->oncleanup = carray->oncleanup;
+       if (dst->oncopy)
+               dst->oncopy(dst);
+       return (robject_t *)dst;
+}
+
+
+rint r_carray_replace(rcarray_t *carray, ruint index, rconstpointer data)
+{
+       if (data)
+               r_memcpy(r_carray_slot_expand(carray, index), data, carray->elt_size);
+       else
+               r_memset(r_carray_slot_expand(carray, index), 0, carray->elt_size);
+       return index;
+}
+
+
+rint r_carray_add(rcarray_t *carray, rconstpointer data)
+{
+       ruint index = r_carray_length(carray);
+       return r_carray_replace(carray, index, data);
+}
+
+
+void r_carray_setlength(rcarray_t *carray, ruint len)
+{
+       r_carray_checkexpand(carray, len);
+       carray->len = len;
+}
+
+
+static void r_carray_checkexpand(rcarray_t *carray, ruint size)
+{
+       ruint chunks;
+
+       if (r_carray_size(carray) < size) {
+               chunks = (size - r_carray_size(carray) + R_CARRAY_CHUNKSIZE) / R_CARRAY_CHUNKSIZE;
+               r_carray_add_chunks(carray, chunks);
+       }
+}
+
+
+void *r_carray_slot_expand(rcarray_t *carray, ruint index)
+{
+       r_carray_checkexpand(carray, index+1);
+       return (void*) r_carray_slot(carray, index);
+}
+
+rpointer r_carray_slot_notused(rcarray_t *carray, ruint index)
+{
+       ruint nchunk = index >> R_CARRAY_CHUNKBITS;
+       ruint offset = index & R_CARRAY_CHUNKMASK;
+       rpointer chunk = r_array_index(carray->array, nchunk, rpointer);
+
+       rpointer v = (rpointer)(((rchar*)chunk) + (offset * carray->elt_size));
+       return v;
+}
diff --git a/rlib/rcarray.h b/rlib/rcarray.h
new file mode 100644 (file)
index 0000000..3812e61
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef _RCARRAY_H_
+#define _RCARRAY_H_
+
+#include "rtypes.h"
+#include "robject.h"
+#include "rarray.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define R_CARRAY_CHUNKBITS 4
+#define R_CARRAY_CHUNKSIZE (1 << R_CARRAY_CHUNKBITS)
+#define R_CARRAY_CHUNKMASK (R_CARRAY_CHUNKSIZE - 1)
+
+typedef struct rcarray_s rcarray_t;
+typedef void (*r_carray_callback)(rcarray_t *carray);
+
+
+struct rcarray_s {
+       robject_t obj;
+       rarray_t *array;
+       ruint alloc_size;
+       ruint len;
+       ruint elt_size;
+       r_carray_callback oncleanup;
+       r_carray_callback oncopy;
+       rpointer *user;
+};
+
+#define r_carray_size(__carray__) ((__carray__)->alloc_size)
+#define r_carray_length(__carray__) ((__carray__)->len)
+#define r_carray_empty(__carray__) ((r_carray_length(__carray__)) ? 0 : 1)
+#define r_carray_slot(__carray__, __index__)(((rchar*)r_array_index((__carray__)->array, (__index__) >> R_CARRAY_CHUNKBITS, rpointer)) + ((__index__) & R_CARRAY_CHUNKMASK) * (__carray__)->elt_size)
+#define r_carray_index(__carray__, __index__, __type__) *((__type__*)r_carray_slot(__carray__, __index__))
+
+robject_t *r_carray_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy, ruint elt_size);
+rcarray_t *r_carray_create(ruint elt_size);
+rint r_carray_replace(rcarray_t *carray, ruint index, rconstpointer data);
+rint r_carray_add(rcarray_t *carray, rconstpointer data);
+void r_carray_setlength(rcarray_t *carray, ruint len);
+void *r_carray_slot_expand(rcarray_t *carray, ruint index);
+
+/*
+ * Virtual methods implementation
+ */
+void r_carray_cleanup(robject_t *obj);
+robject_t *r_carray_copy(const robject_t *obj);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index b73bc29..df317f6 100644 (file)
  *
  */
 
-static void r_objectstub_destroy(robject_t *ptr)
-{
-       r_harray_destroy((rharray_t*)ptr);
-}
-
 
-static robject_t *r_objectstub_copy(const robject_t *ptr)
-{
-       return (robject_t*) r_harray_copy((const rharray_t*)ptr);
-}
 
 /*
  * Copy the names in the hashed array.
@@ -47,7 +38,7 @@ static void r_array_oncopy_rstr(rarray_t *array)
        ruint index;
        rstr_t *src, *dst;
 
-       for (index = 0; index < array->len; index++) {
+       for (index = 0; index < r_array_length(array); index++) {
                src = r_array_index(array, index, rstr_t*);
                if (src)
                        dst = r_rstrdup(src->str, src->size);
@@ -58,12 +49,12 @@ static void r_array_oncopy_rstr(rarray_t *array)
 /*
  * Destroy the names in the hashed array.
  */
-static void r_array_ondestroy_rstr(rarray_t *array)
+static void r_array_oncleanup_rstr(rarray_t *array)
 {
        ruint index;
        rstr_t *src;
 
-       for (index = 0; index < array->len; index++) {
+       for (index = 0; index < r_array_length(array); index++) {
                src = r_array_index(array, index, rstr_t*);
                if (src)
                        r_free(src);
@@ -71,51 +62,55 @@ static void r_array_ondestroy_rstr(rarray_t *array)
 }
 
 
-rharray_t *r_harray_create(ruint elt_size)
+robject_t *r_harray_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy, ruint elt_size)
 {
-       rharray_t *harray;
-
-       harray = (rharray_t*)r_malloc(sizeof(*harray));
-       if (!harray)
-               return NULL;
-       r_memset(harray, 0, sizeof(*harray));
+       rharray_t *harray = (rharray_t*)obj;
+       r_object_init(obj, type, cleanup, copy);
+       harray->hash = r_hash_create(5, r_hash_rstrequal, r_hash_rstrhash);
        harray->members = r_array_create(elt_size);
        harray->names = r_array_create(sizeof(rstr_t*));
-       harray->names->ondestroy = r_array_ondestroy_rstr;
+       harray->names->oncleanup = r_array_oncleanup_rstr;
        harray->names->oncopy = r_array_oncopy_rstr;
-       harray->hash = r_hash_create(5, r_hash_rstrequal, r_hash_rstrhash);
-       r_object_init(&harray->obj, R_OBJECT_HARRAY, r_objectstub_destroy, r_objectstub_copy);
+       return obj;
+}
+
+rharray_t *r_harray_create(ruint elt_size)
+{
+       rharray_t *harray;
+
+       harray = (rharray_t*)r_object_create(sizeof(*harray));
+       r_harray_init((robject_t*)harray, R_OBJECT_HARRAY,r_harray_cleanup, r_harray_copy, elt_size);
        return harray;
 }
 
 
-rharray_t *r_harray_copy(const rharray_t *src)
+robject_t *r_harray_copy(const robject_t *obj)
 {
        rharray_t *harray;
        int i;
        rstr_t *n;
+       const rharray_t *src = (const rharray_t *)obj;
 
-       harray = (rharray_t*)r_malloc(sizeof(*harray));
-       if (!harray)
-               return NULL;
-       harray->names = r_array_copy(src->names);
-       harray->members = r_array_copy(src->members);
+       harray = (rharray_t*)r_object_create(sizeof(*harray));
+       r_object_init(&harray->obj, R_OBJECT_HARRAY, r_harray_cleanup, r_harray_copy);
+       harray->names = (rarray_t*)r_array_copy((robject_t*)src->names);
+       harray->members = (rarray_t*)r_array_copy((robject_t*)src->members);
        harray->hash = r_hash_create(5, r_hash_rstrequal, r_hash_rstrhash);
-       for (i = 0; i < src->members->len; i++) {
+       for (i = 0; i < r_array_length(src->members); i++) {
                n = r_array_index(harray->names, i, rstr_t*);
                r_hash_insert_indexval(harray->hash, (rconstpointer)n, i);
        }
-       r_object_init(&harray->obj, R_OBJECT_HARRAY, r_objectstub_destroy, r_objectstub_copy);
-       return harray;
+       return (robject_t*)harray;
 }
 
 
-void r_harray_destroy(rharray_t *harray)
+void r_harray_cleanup(robject_t *obj)
 {
-       r_array_destroy(harray->members);
-       r_array_destroy(harray->names);
-       r_hash_destroy(harray->hash);
-       r_free(harray);
+       rharray_t *harray = (rharray_t *)obj;
+       r_object_destroy((robject_t*)harray->members);
+       r_object_destroy((robject_t*)harray->names);
+       r_object_destroy((robject_t*)harray->hash);
+       r_object_cleanup(&harray->obj);
 }
 
 
@@ -180,7 +175,7 @@ rint r_harray_set(rharray_t *harray, rlong index, rconstpointer pval)
 
 rpointer r_harray_get(rharray_t *harray, rulong index)
 {
-       if (index >= r_array_size(harray->members))
+       if (index >= r_array_length(harray->members))
                return NULL;
        return r_array_slot(harray->members, index);
 }
index e87aecf..f04f236 100644 (file)
@@ -22,18 +22,18 @@ typedef struct rharray_s {
 
 
 rharray_t *r_harray_create(ruint elt_size);
-rharray_t *r_harray_copy(const rharray_t *array);
-void r_harray_destroy(rharray_t *harray);
+robject_t *r_harray_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy, ruint elt_size);
 rint r_harray_add(rharray_t *harray, const rchar *name, ruint namesize, rconstpointer pval);
 rint r_harray_add_s(rharray_t *harray, const rchar *name, rconstpointer pval);
 rlong r_harray_lookup(rharray_t *harray, const rchar *name, ruint namesize);
 rlong r_harray_lookup_s(rharray_t *harray, const rchar *name);
 rhash_node_t* r_harray_nodelookup(rharray_t *harray, rhash_node_t *cur, const rchar *name, ruint namesize);
 rhash_node_t* r_harray_nodelookup_s(rharray_t *harray, rhash_node_t *cur, const rchar *name);
-
 rpointer r_harray_get(rharray_t *harray, rulong index);
 rint r_harray_set(rharray_t *harray, rlong index, rconstpointer pval);
 
+robject_t *r_harray_copy(const robject_t *obj);
+void r_harray_cleanup(robject_t *obj);
 
 #ifdef __cplusplus
 }
index d0e9401..a1b4a27 100644 (file)
@@ -87,39 +87,22 @@ rboolean r_hash_rstrequal(rconstpointer key1, rconstpointer key2)
 }
 
 
-static void r_objectstub_destroy(robject_t *ptr)
-{
-       r_hash_destroy((rhash_t*)ptr);
-}
-
-
-static robject_t *r_objectstub_copy(const robject_t *ptr)
-{
-       return (robject_t*) r_hash_copy((const rhash_t*)ptr);
-}
-
-
 rhash_t *r_hash_create(ruint nbits, r_hash_equalfunc eqfunc, r_hash_hashfun hfunc)
 {
        rhash_t *hash;
 
-       hash = (rhash_t*)r_malloc(sizeof(*hash));
-       if (!hash)
-               return NULL;
-       r_memset(hash, 0, sizeof(*hash));
-       if (!r_hash_init(hash, nbits, eqfunc, hfunc)) {
-               r_hash_destroy(hash);
-               return NULL;
-       }
-       r_object_init(&hash->obj, R_OBJECT_HASH, r_objectstub_destroy, r_objectstub_copy);
+       hash = (rhash_t*)r_object_create(sizeof(*hash));
+       r_hash_init((robject_t *)hash, R_OBJECT_HASH, r_hash_cleanup, r_hash_copy, nbits, eqfunc, hfunc);
        return hash;
 }
 
 
-rhash_t *r_hash_init(rhash_t *hash, ruint nbits, r_hash_equalfunc eqfunc, r_hash_hashfun hfunc)
+robject_t *r_hash_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy,
+                                               ruint nbits, r_hash_equalfunc eqfunc, r_hash_hashfun hfunc)
 {
        ruint i;
        rsize_t size;
+       rhash_t *hash = (rhash_t *)obj;
 
        hash->nbits = nbits;
        hash->eqfunc = eqfunc;
@@ -131,25 +114,20 @@ rhash_t *r_hash_init(rhash_t *hash, ruint nbits, r_hash_equalfunc eqfunc, r_hash
        for (i = 0; i < size; i++) {
                r_list_init(&hash->buckets[i]);
        }
-       return hash;
+       r_object_init(obj, type, cleanup, copy);
+       return obj;
 }
 
 
-rhash_t *r_hash_copy(const rhash_t *hash)
+robject_t *r_hash_copy(const robject_t *obj)
 {
        return NULL;
 }
 
 
-void r_hash_destroy(rhash_t *hash)
-{
-       r_hash_cleanup(hash);
-       r_free(hash);
-}
-
-
-void r_hash_cleanup(rhash_t *hash)
+void r_hash_cleanup(robject_t *obj)
 {
+       rhash_t *hash = (rhash_t *)obj;
        r_hash_removeall(hash);
        r_free(hash->buckets);
 }
index a51a8be..072dacc 100644 (file)
@@ -30,10 +30,9 @@ struct rhash_s {
 #define r_hash_size(__h__) (1 << (__h__)->nbits)
 #define r_hash_mask(__h__) (r_hash_size(__h__) - 1)
 rhash_t *r_hash_create(ruint nbits, r_hash_equalfunc eqfunc, r_hash_hashfun hfunc);
-rhash_t *r_hash_init(rhash_t *hash, ruint nbits, r_hash_equalfunc eqfunc, r_hash_hashfun hfunc);
-rhash_t *r_hash_copy(const rhash_t *hash);
-void r_hash_destroy(rhash_t *hash);
-void r_hash_cleanup(rhash_t *hash);
+robject_t *r_hash_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy,
+                                               ruint nbits, r_hash_equalfunc eqfunc, r_hash_hashfun hfunc);
+
 void r_hash_insert(rhash_t* hash, rconstpointer key, rpointer value);
 void r_hash_remove(rhash_t* hash, rconstpointer key);
 void r_hash_removeall(rhash_t* hash);
@@ -50,6 +49,13 @@ ruint r_hash_rstrhash(rconstpointer key);
 rboolean r_hash_rstrequal(rconstpointer key1, rconstpointer key2);
 
 
+/*
+ * Virtual methods implementation
+ */
+void r_hash_cleanup(robject_t *obj);
+robject_t *r_hash_copy(const robject_t *obj);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/rlib/rmath.c b/rlib/rmath.c
new file mode 100644 (file)
index 0000000..7af2921
--- /dev/null
@@ -0,0 +1,7 @@
+#include <math.h>
+
+
+double r_fmod(double x, double y)
+{
+       return fmod(x, y);
+}
diff --git a/rlib/rmath.h b/rlib/rmath.h
new file mode 100644 (file)
index 0000000..7de3de4
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _RMATH_H_
+#define _RMATH_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+double r_fmod(double x, double y);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 92589f2..f8c03bf 100644 (file)
@@ -1,30 +1,73 @@
+#include "rmem.h"
 #include "robject.h"
 
 
-void r_object_init(robject_t *obj, ruint32 type, r_object_destroyfun destroy, r_object_copyfun copy)
+robject_t *r_object_create(rsize_t size)
 {
+       robject_t *object;
+
+       if ((object = (robject_t*)r_zmalloc(size)) == NULL)
+               return NULL;
+       return object;
+}
+
+void r_object_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy)
+{
+       r_list_init(&obj->lnk);
+       obj->lst = NULL;
        obj->type = type;
-       obj->destroy = destroy;
+       obj->cleanup = cleanup;
        obj->copy = copy;
 }
 
 
 robject_t *r_object_copy(const robject_t *obj)
 {
+       /*
+        * Nothing to do
+        */
+       return NULL;
+}
+
+
+void r_object_cleanup(robject_t *obj)
+{
+       /*
+        * if on a list, remove it
+        */
+       if (!r_list_empty(&obj->lnk))
+               r_list_del(&obj->lnk);
+       /*
+        * Nothing to do here, but for now lets wipe out the structure
+        */
+       r_memset(obj, 0, sizeof(*obj));
+}
+
+
+void r_object_destroy(robject_t *obj)
+{
+       r_object_v_cleanup(obj);
+       r_free(obj);
+}
+
+
+robject_t *r_object_v_copy(const robject_t *obj)
+{
        if (obj->copy)
                return obj->copy(obj);
        return NULL;
 }
 
 
-void r_object_destroy(robject_t *obj)
+void r_object_v_cleanup(robject_t *obj)
 {
-       r_object_destroyfun destroy = obj->destroy;
-       if (destroy)
-               destroy(obj);
+       r_object_cleanupfun cleanup = obj->cleanup;
+       if (cleanup)
+               cleanup(obj);
 }
 
 
+
 void r_object_typeset(robject_t *obj, ruint32 type)
 {
        obj->type = type;
index a4352b0..95cc5ac 100644 (file)
@@ -2,6 +2,7 @@
 #define _ROBJECT_H_
 
 #include "rtypes.h"
+#include "rlist.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -12,27 +13,41 @@ extern "C" {
 #define R_OBJECT_STRING 1
 #define R_OBJECT_ARRAY 2
 #define R_OBJECT_HARRAY 3
-#define R_OBJECT_HASH 3
-#define R_OBJECT_REFREG 4
+#define R_OBJECT_CARRAY 4
+#define R_OBJECT_HASH 5
+#define R_OBJECT_REF 6
 #define R_OBJECT_USER 256
 
 
 typedef struct robject_s robject_t;
-typedef void (*r_object_destroyfun)(robject_t *ptr);
+/*
+ * This should be renamed to cleanup
+ */
+typedef void (*r_object_cleanupfun)(robject_t *ptr);
 typedef robject_t* (*r_object_copyfun)(const robject_t *ptr);
 
 struct robject_s {
+       rlink_t lnk;
+       rlist_t *lst;
        ruint32 type;
-       r_object_destroyfun destroy;
+       ruint32 size;
+       r_object_cleanupfun cleanup;
        r_object_copyfun copy;
 };
 
+robject_t *r_object_create(rsize_t size);
 robject_t *r_object_copy(const robject_t *obj);
 void r_object_destroy(robject_t *obj);
-void r_object_init(robject_t *obj, ruint32 type, r_object_destroyfun destroy, r_object_copyfun copy);
+void r_object_cleanup(robject_t *obj);
+void r_object_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy);
 void r_object_typeset(robject_t *obj, ruint32 type);
 ruint32 r_object_typeget(robject_t *obj);
 
+/*
+ * Virtual methods
+ */
+robject_t *r_object_v_copy(const robject_t *obj);
+void r_object_v_cleanup(robject_t *obj);
 
 #ifdef __cplusplus
 }
index e31e54b..c0119a1 100644 (file)
@@ -1,12 +1,34 @@
 #include "rref.h"
 
 
-void r_ref_init(rref_t *ref, ruint32 count, ruint32 objtype, rref_type_t type, r_object_destroyfun destroy, r_object_copyfun copy)
+robject_t *r_ref_init(robject_t *obj, ruint32 objtype, r_object_cleanupfun cleanup, r_object_copyfun copy, ruint32 count, rref_type_t type)
 {
-       r_object_init(&ref->obj, objtype, destroy, copy);
+       rref_t *ref = (rref_t *)obj;
+       r_object_init(&ref->obj, objtype, cleanup, copy);
        ref->count = count;
        ref->type = type;
        r_spinlock_init(&ref->lock);
+       return obj;
+}
+
+
+rref_t *r_ref_create(rref_type_t type)
+{
+       rref_t *ref;
+       ref = (rref_t*)r_object_create(sizeof(*ref));
+       r_ref_init((robject_t*)ref, R_OBJECT_REF, r_ref_cleanup, r_ref_copy, 1, RREF_TYPE_SHARED);
+       return ref;
+}
+
+robject_t *r_ref_copy(const robject_t *obj)
+{
+       return (robject_t*) r_ref_create(((rref_t *)obj)->type);
+}
+
+
+void r_ref_cleanup(robject_t *obj)
+{
+       r_object_cleanup(obj);
 }
 
 
index c625d3c..0456844 100644 (file)
@@ -11,8 +11,8 @@ extern "C" {
 #endif
 
 typedef enum {
-       RREF_TYPE_COW = 0,
-       RREF_TYPE_SHARED,
+       RREF_TYPE_SHARED = 0,
+       RREF_TYPE_COW,
 } rref_type_t;
 
 typedef struct rref_s rref_t;
@@ -24,13 +24,20 @@ struct rref_s {
        rspinlock_t lock;
 };
 
+rref_t *r_ref_create(rref_type_t type);
+robject_t *r_ref_init(robject_t *obj, ruint32 objtype, r_object_cleanupfun cleanup, r_object_copyfun copy, ruint32 count, rref_type_t type);
+
 ruint32 r_ref_inc(rref_t *ref);
 ruint32 r_ref_dec(rref_t *ref);
 ruint32 r_ref_get(rref_t *ref);
 void r_ref_typeset(rref_t *ref, rref_type_t type);
 rref_type_t r_ref_typeget(rref_t *ref);
-void r_ref_init(rref_t *ref, ruint32 count, ruint32 objtype, rref_type_t type, r_object_destroyfun destroy, r_object_copyfun copy);
 
+/*
+ * Virtual methods implementation
+ */
+void r_ref_cleanup(robject_t *obj);
+robject_t *r_ref_copy(const robject_t *obj);
 
 #ifdef __cplusplus
 }
index 343a6b7..ca6ced6 100644 (file)
@@ -78,7 +78,7 @@ rstr_t *r_rstrdup(const rchar *s, ruint size)
        rsize_t allocsize = sizeof(rstr_t) + size + sizeof(rchar);
        rstr_t *d = (rstr_t*)r_malloc(allocsize);
        if (d) {
-               r_memset(d, allocsize, 0);
+               r_memset(d, 0, allocsize);
                d->size = size;
                d->str = (rchar*)&d[1];
                r_memcpy((rchar*)d->str, s, size);
@@ -147,63 +147,44 @@ rdouble r_strtod(const rchar *s, rchar **endptr)
 }
 
 
-static void r_objectstub_destroy(robject_t *ptr)
+robject_t *r_string_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy)
 {
-       r_string_destroy((rstring_t*)ptr);
+       rstring_t *string = (rstring_t*)obj;
+       r_object_init(obj, type, cleanup, copy);
+       r_memset(&string->s, 0, sizeof(string->s));
+       return obj;
 }
 
 
-static robject_t *r_objectstub_copy(const robject_t *ptr)
-{
-       return (robject_t*) r_string_copy((const rstring_t*)ptr);
-}
-
-
-static rstring_t *r_string_init(rstring_t *string)
-{
-       r_memset(string, 0, sizeof(*string));
-       return string;
-}
-
-
-static void r_string_cleanup(rstring_t *string)
+void r_string_cleanup(robject_t *obj)
 {
+       rstring_t *string = (rstring_t*)obj;
        if (string) {
                r_free(string->s.str);
-               r_memset(&string->s, 0, sizeof(rstr_t));
+               r_memset(&string->s, 0, sizeof(string->s));
        }
+       r_object_cleanup(obj);
 }
 
 
 rstring_t *r_string_create()
 {
        rstring_t *string;
-       if ((string = (rstring_t*)r_malloc(sizeof(*string))) == NULL)
-               return NULL;
-       if (!r_string_init(string)) {
-               r_string_destroy(string);
-               return NULL;
-       }
-       r_object_init(&string->obj, R_OBJECT_STRING, r_objectstub_destroy, r_objectstub_copy);
+       string = (rstring_t*)r_object_create(sizeof(*string));
+       r_string_init(&string->obj, R_OBJECT_STRING, r_string_cleanup, r_string_copy);
        return string;
 
 }
 
 
-void r_string_destroy(rstring_t *string)
-{
-       r_string_cleanup(string);
-       r_free(string);
-}
-
-
 void r_string_assign(rstring_t *string, const rstr_t *str)
 {
-       r_string_cleanup(string);
        if (str && str->size) {
+               r_free(string->s.str);
                string->s.str = (rchar*)r_malloc(str->size + 1);
                if (!string->s.str)
                        return;
+               r_memset(string->s.str, 0, str->size);
                r_memcpy(string->s.str, str->str, str->size);
                string->s.size = str->size;
        }
@@ -221,9 +202,10 @@ void r_string_cat(rstring_t *string, const rstr_t *str)
 }
 
 
-rstring_t *r_string_copy(const rstring_t *srcString)
+robject_t *r_string_copy(const robject_t *obj)
 {
-       return r_string_create_from_rstr(&srcString->s);
+       const rstring_t *srcString = (const rstring_t *)obj;
+       return (robject_t*)r_string_create_from_rstr(&srcString->s);
 }
 
 
index 22e9e25..8e2c8da 100644 (file)
@@ -47,14 +47,21 @@ typedef struct rstring_s {
 } rstring_t;
 
 #define R_STRING2PTR(__p__) ((rstring_t *)(__p__))->s.str
+#define r_string_empty(__p__) (!((__p__) && ((rstring_t *)(__p__))->s.size)) ? 1 : 0
 rstring_t *r_string_create();
 rstring_t *r_string_create_from_ansistr(const rchar *str);
 rstring_t *r_string_create_strsize(const char *str, ruint size);
 rstring_t *r_string_create_from_rstr(const rstr_t *str);
-void r_string_destroy(rstring_t *string);
+robject_t *r_string_init(robject_t *obj, ruint32 type, r_object_cleanupfun cleanup, r_object_copyfun copy);
 void r_string_assign(rstring_t *string, const rstr_t *str);
 void r_string_cat(rstring_t *string, const rstr_t *str);
-rstring_t *r_string_copy(const rstring_t *string);
+
+/*
+ * Virtual methods implementation
+ */
+void r_string_cleanup(robject_t *obj);
+robject_t *r_string_copy(const robject_t *obj);
+
 
 #ifdef __cplusplus
 }
index c1b7218..3711057 100644 (file)
@@ -45,6 +45,7 @@
                                        *cbrec = rpa_cbset_getrecord(&stat->cbset, (_o_) + (_off_)); \
                                }\
                        } \
+                       rpa_cbset_reset(&(_c_)->cbset, _s_); \
                } \
        } while (0)
 
@@ -376,7 +377,7 @@ int rpa_mnode_plain_loop_detect(rpa_mnode_t *mnode, rpa_stat_t *stat, const char
        rpa_link_t *pos;
 
        pLoop = rpa_stat_current_loop(stat);
-       if (pLoop && pLoop->match == mnode->match) {
+       if (pLoop && pLoop->match == mnode->match && pLoop->input == input) {
                return pLoop->size;
        }
 
@@ -506,7 +507,7 @@ int rpa_mnode_p_plain_loop_detect(rpa_mnode_t *mnode, rpa_stat_t *stat, const ch
        rpa_head_t *bucket = &stat->loophash[RPA_LOOPHASH(match)];
 
        pLoop = rpa_stat_current_loop(stat);
-       if (pLoop && pLoop->match == mnode->match) {
+       if (pLoop && pLoop->match == mnode->match && pLoop->input == input) {
                return pLoop->size;
        }
 
@@ -599,6 +600,27 @@ int rpa_mnode_p_multiopt(rpa_mnode_t *mnode, rpa_stat_t *stat, const char *input
 }
 
 
+void rpa_mcache_cbset(rpa_stat_t *stat, rpa_mcache_t *_c_, rpa_match_t *_m_, const char* _i_, int _r_, rpa_word_t _o_, int _s_)
+{
+       rpa_cbrecord_t *cbrec;
+       rpa_word_t _off_;
+       RPA_MCACHE_SET((_c_), (_m_), (_i_), (_r_));
+       rpa_cbset_reset(&(_c_)->cbset, 0);
+       if ((_s_) > 0) {
+               if (rpa_cbset_check_space_min(&(_c_)->cbset, (_s_) + 1) < 0) {
+                       RPA_MCACHE_SET((_c_), NULL, NULL, 0);
+                       return;
+               }
+               for (_off_ = 1; _off_ <= (_s_); _off_++) {
+                       if ((cbrec = rpa_cbset_getslot(&(_c_)->cbset, _off_)) != 0) {
+                               *cbrec = rpa_cbset_getrecord(&stat->cbset, (_o_) + (_off_));
+                       }
+               }
+               rpa_cbset_reset(&(_c_)->cbset, _s_);
+       }
+}
+
+
 int rpa_mnode_p_callback_plain(rpa_mnode_t *mnode, rpa_stat_t *stat, const char *input)
 {
        int ret = 0;
@@ -611,7 +633,10 @@ int rpa_mnode_p_callback_plain(rpa_mnode_t *mnode, rpa_stat_t *stat, const char
        if (((rpa_match_nlist_t*)match)->loopy) {
                ret = rpa_mnode_p_plain_loop_detect(mnode, stat, input);
        } else if (ncache->match == match && ncache->input == input) {
-               r_printf("HIT THE CACHE @ %d: %s, %d\n", hash, match->name, ncache->ret);
+               /*
+                * Debug the cache efficiency
+                * r_printf("HIT THE CACHE @ %d: %s, %d\n", hash, match->name, ncache->ret);
+                */
                return -1;
        } else if (mcache->match == match && mcache->input == input) {
                rpa_cbrecord_t *cbrec;
@@ -626,7 +651,6 @@ int rpa_mnode_p_callback_plain(rpa_mnode_t *mnode, rpa_stat_t *stat, const char
                 * Debug the cache efficiency
                 * r_printf("HIT THE CACHE @ %d: %s, %d\n", hash, match->name, ret);
                 */
-               r_printf("HIT THE CACHE @ %d: %s, %d\n", hash, match->name, ret);
        } else {
                ret = rpa_mnode_p_plain(mnode, stat, input);
                if (stat->usecache) {
diff --git a/rpatest/cache.in b/rpatest/cache.in
new file mode 100644 (file)
index 0000000..91f47f4
--- /dev/null
@@ -0,0 +1,2 @@
+abc
+
diff --git a/rpatest/cache.out b/rpatest/cache.out
new file mode 100644 (file)
index 0000000..5bdbc17
--- /dev/null
@@ -0,0 +1,9 @@
+a: a
+A: a
+B: b
+C: c
+a: a
+B: b
+C: c
+cache.in:
+abc
diff --git a/rpatest/cache.rpa b/rpatest/cache.rpa
new file mode 100644 (file)
index 0000000..31984cc
--- /dev/null
@@ -0,0 +1,9 @@
+# RPA rules
+S                      ::= [#0x0009] | [#0x000B] | [#0x000C] | [#0x0020] | [#0x00A0] | [#0xFEFF]
+a                      ::= a
+A                      ::= <:a:>
+B                      ::= b
+C                      ::= c
+D                      ::= d
+
+<:A:><:B:><:C:> & <:a:><:B:><:C:>
diff --git a/rpatest/cache.sh b/rpatest/cache.sh
new file mode 100755 (executable)
index 0000000..0a96194
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/bash
+if [ -f common.def ]; then
+. common.def
+fi
+
+RPATEST=cache
+DIFF="diff -u"
+
+if [ "" = "" ]; then
+RPAGREP=../rgrep/unix/x86_64/rgrep
+fi
+
+
+$RPAGREP -p -f $RPATEST.rpa -c ".*" $RPATEST.in > $RPATEST.res
+$DIFF $RPATEST.res $RPATEST.out
+
+if [ 0 != 0 ]; then
+    echo "$RPATEST : FAILED"
+else
+    echo "$RPATEST : PASSED"
+fi
+
diff --git a/rpatest/common.def b/rpatest/common.def
new file mode 100644 (file)
index 0000000..96b21bf
--- /dev/null
@@ -0,0 +1 @@
+RPAGREP=../rgrep/unix/x86_64/rgrep
diff --git a/rpatest/loop.in b/rpatest/loop.in
new file mode 100644 (file)
index 0000000..b98e11e
--- /dev/null
@@ -0,0 +1 @@
+c[d=2]
diff --git a/rpatest/loop.out b/rpatest/loop.out
new file mode 100644 (file)
index 0000000..ae00557
--- /dev/null
@@ -0,0 +1,11 @@
+Identifier: c
+MemberExpression: c
+Identifier: d
+MemberExpression: d
+AssignmentOperator: =
+Identifier: 2
+AssignmentExpression: 2
+AssignmentExpression: d=2
+MemberExpression: c[d=2]
+loop.in:
+c[d=2]
diff --git a/rpatest/loop.rpa b/rpatest/loop.rpa
new file mode 100644 (file)
index 0000000..df99441
--- /dev/null
@@ -0,0 +1,8 @@
+S                      ::= [#0x0009] | [#0x000B] | [#0x000C] | [#0x0020] | [#0x00A0] | [#0xFEFF]
+Identifier             ::= [a-zA-Z0-9]+
+AssignmentOperator     ::= '='
+MemberExpression       ::= <:MemberExpression:> '[' <:AssignmentExpression:> ']'  |
+                           <:Identifier:>
+AssignmentExpression   ::= <:MemberExpression:> <:AssignmentOperator:> <:AssignmentExpression:> | 
+                           <:Identifier:>
+<:MemberExpression:>                                   
diff --git a/rpatest/loop.sh b/rpatest/loop.sh
new file mode 100755 (executable)
index 0000000..41df661
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/bash
+if [ -f common.def ]; then
+. common.def
+fi
+
+RPATEST=loop
+DIFF="diff -u"
+
+if [ "" = "" ]; then
+RPAGREP=../rgrep/unix/x86_64/rgrep
+fi
+
+
+$RPAGREP -p -f $RPATEST.rpa -c ".*" $RPATEST.in > $RPATEST.res
+$DIFF $RPATEST.res $RPATEST.out
+
+if [ $? != 0 ]; then
+    echo "$RPATEST : FAILED"
+else
+    echo "$RPATEST : PASSED"
+fi
+
diff --git a/rpatest/multiloop.in b/rpatest/multiloop.in
new file mode 100644 (file)
index 0000000..0f52e66
--- /dev/null
@@ -0,0 +1 @@
+hello()[][]()
diff --git a/rpatest/multiloop.out b/rpatest/multiloop.out
new file mode 100644 (file)
index 0000000..aa89981
--- /dev/null
@@ -0,0 +1,16 @@
+Identifier: hello
+Expression: hello
+CallExpressionBase: hello
+CallExpression: hello()
+Expression: hello()
+MemberExpressionBase: hello()
+MemberExpression: hello()[]
+Expression: hello()[]
+MemberExpressionBase: hello()[]
+MemberExpression: hello()[][]
+Expression: hello()[][]
+CallExpressionBase: hello()[][]
+CallExpression: hello()[][]()
+Expression: hello()[][]()
+multiloop.in:
+hello()[][]()
diff --git a/rpatest/multiloop.rpa b/rpatest/multiloop.rpa
new file mode 100644 (file)
index 0000000..11ab200
--- /dev/null
@@ -0,0 +1,16 @@
+S                      ::= ([#0x0009] | [#0x000B] | [#0x000C] | [#0x0020] | [#0x00A0] | [#0xFEFF])+
+Identifier             ::= [a-zA-Z0-9]+
+AssignmentOperator     ::= '='
+
+MemberExpressionBase   ::= <:Expression:>
+CallExpressionBase     ::= <:Expression:>
+MemberExpression       ::= <:MemberExpressionBase:> '[' <S>? ']'
+CallExpression         ::= <:CallExpressionBase:> '(' <S>? ')'
+
+Expression             ::= <:MemberExpression:> |
+                           <:CallExpression:> |
+                           <:Identifier:>
+
+
+
+all                    ::= <:Expression:>                                      
diff --git a/rpatest/multiloop.sh b/rpatest/multiloop.sh
new file mode 100755 (executable)
index 0000000..69d6179
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/bash
+if [ -f common.def ]; then
+. common.def
+fi
+
+RPATEST=multiloop
+DIFF="diff -u"
+
+if [ "" = "" ]; then
+RPAGREP=../rgrep/unix/x86_64/rgrep
+fi
+
+
+$RPAGREP -p -f $RPATEST.rpa -c ".*" $RPATEST.in > $RPATEST.res
+$DIFF $RPATEST.res $RPATEST.out
+
+if [ $? != 0 ]; then
+    echo "$RPATEST : FAILED"
+else
+    echo "$RPATEST : PASSED"
+fi
+
diff --git a/rpatest/template/newrpatest.sh b/rpatest/template/newrpatest.sh
new file mode 100755 (executable)
index 0000000..5721a9f
--- /dev/null
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+NAME=$1
+DESTDIR=$2
+
+if [ "$NAME" = "" ] || [ "$DESTDIR" = "" ]; then
+    echo "$0 <testname> <destdir>"
+    exit 1
+fi
+
+DESTFILE="$DESTDIR/$NAME"
+
+echo "#!/bin/bash
+if [ -f common.def ]; then
+. common.def
+fi
+
+RPATEST=$NAME
+DIFF=\"diff -u\"
+
+if [ \"$RPAGREP\" = \"\" ]; then
+RPAGREP=../rgrep/unix/x86_64/rgrep
+fi
+
+
+\$RPAGREP -p -f \$RPATEST.rpa -c \".*\" \$RPATEST.in > \$RPATEST.res
+\$DIFF \$RPATEST.res \$RPATEST.out
+
+if [ \$? != 0 ]; then
+    echo \"\$RPATEST : FAILED\"
+else
+    echo \"\$RPATEST : PASSED\"
+fi
+" > $DESTFILE.sh
+
+chmod ugo+x $DESTFILE.sh
+if [ ! -f $DESTFILE.rpa ]; then
+    echo "# RPA rules" > $DESTFILE.rpa
+    echo "S                    ::= [#0x0009] | [#0x000B] | [#0x000C] | [#0x0020] | [#0x00A0] | [#0xFEFF]" >> $DESTFILE.rpa
+fi
+
+if [ ! -f $DESTFILE.in ]; then
+    echo "sample text goes here" > $DESTFILE.in
+fi
index c95d41d..62ce74e 100644 (file)
@@ -5,27 +5,39 @@ RVM_SO = $(OUTDIR)/librvm.so.1.0
 CFLAGS += -I$(RVM_SRCDIR)/config -I$(SRCDIR)/rlib
 
 
-RVM_OBJECTS += $(OUTDIR)/rrefreg.o
 RVM_OBJECTS += $(OUTDIR)/rvmcpu.o 
 RVM_OBJECTS += $(OUTDIR)/rvmoperator.o
+RVM_OBJECTS += $(OUTDIR)/rvmcodemap.o
+RVM_OBJECTS += $(OUTDIR)/rvmcodegen.o
+RVM_OBJECTS += $(OUTDIR)/rvmreg.o
+RVM_OBJECTS += $(OUTDIR)/rvmscope.o
+RVM_OBJECTS += $(OUTDIR)/rvmgc.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatorbin.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatoradd.o
 RVM_OBJECTS += $(OUTDIR)/rvmoperatorand.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatoreq.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatornoteq.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatorlogicor.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatorlogicand.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatorlogicnot.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatorless.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatorlesseq.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatorgreater.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatorgreatereq.o
 RVM_OBJECTS += $(OUTDIR)/rvmoperatorxor.o
 RVM_OBJECTS += $(OUTDIR)/rvmoperatoror.o
 RVM_OBJECTS += $(OUTDIR)/rvmoperatorcmp.o
 RVM_OBJECTS += $(OUTDIR)/rvmoperatorcmn.o
-RVM_OBJECTS += $(OUTDIR)/rvmoperatornot.o
 RVM_OBJECTS += $(OUTDIR)/rvmoperatorlsl.o
 RVM_OBJECTS += $(OUTDIR)/rvmoperatorlsr.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatorlsru.o
 RVM_OBJECTS += $(OUTDIR)/rvmoperatorcast.o
 RVM_OBJECTS += $(OUTDIR)/rvmoperatorcat.o
-RVM_OBJECTS += $(OUTDIR)/rvmoperatoradd.o
 RVM_OBJECTS += $(OUTDIR)/rvmoperatorsub.o
 RVM_OBJECTS += $(OUTDIR)/rvmoperatormul.o
 RVM_OBJECTS += $(OUTDIR)/rvmoperatordiv.o
-RVM_OBJECTS += $(OUTDIR)/rvmcodemap.o
-RVM_OBJECTS += $(OUTDIR)/rvmcodegen.o
-RVM_OBJECTS += $(OUTDIR)/rvmreg.o
-RVM_OBJECTS += $(OUTDIR)/rvmscope.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatormod.o
+RVM_OBJECTS += $(OUTDIR)/rvmoperatornot.o
 
 
 ifeq ($(OS), linux)
diff --git a/rvm/rrefreg.c b/rvm/rrefreg.c
deleted file mode 100644 (file)
index bfe6e06..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "rrefreg.h"
-#include "rmem.h"
-
-rrefreg_t *r_refreg_create()
-{
-       rrefreg_t *refreg = (rrefreg_t*)r_malloc(sizeof(*refreg));
-       if (!refreg)
-               return NULL;
-       return r_refreg_init(refreg);
-}
-
-
-rrefreg_t *r_refreg_copy(const rrefreg_t* src)
-{
-       rrefreg_t *refreg = r_refreg_create();
-       if (!refreg)
-               return NULL;
-       rvm_reg_copy(&refreg->reg, &refreg->reg);
-       return refreg;
-}
-
-
-void r_refreg_cleanup(rrefreg_t *refreg)
-{
-       rvm_reg_cleanup(&refreg->reg);
-}
-
-
-void r_refreg_destroy(rrefreg_t *refreg)
-{
-       if (refreg) {
-               r_refreg_cleanup(refreg);
-               r_free(refreg);
-       }
-}
-
-
-static void r_object_destroy_stub(robject_t *ptr)
-{
-       if (ptr)
-               r_refreg_destroy((rrefreg_t*)ptr);
-}
-
-
-static robject_t *r_object_copy_stub(const robject_t *ptr)
-{
-       return (robject_t*) r_refreg_copy((const rrefreg_t*)ptr);
-}
-
-
-rrefreg_t *r_refreg_init(rrefreg_t *refreg)
-{
-       r_memset(refreg, 0, sizeof(*refreg));
-       r_ref_init(&refreg->ref, 1, R_OBJECT_REFREG, RREF_TYPE_COW, r_object_destroy_stub, r_object_copy_stub);
-       return refreg;
-}
-
diff --git a/rvm/rrefreg.h b/rvm/rrefreg.h
deleted file mode 100644 (file)
index 1a9ea55..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef _RREFREG_H_
-#define _RREFREG_H_
-
-#include "rvmcpu.h"
-#include "rvmreg.h"
-#include "rref.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct rrefreg_s {
-       rref_t ref;
-       rvmreg_t reg;
-} rrefreg_t;
-
-#define REFREG2REG(__p__) ((rrefreg_t*)(__p__))->reg
-#define REFREG2REGPTR(__p__) &REFREG2REG(__p__)
-rrefreg_t *r_refreg_create();
-void r_refreg_destroy(rrefreg_t *refreg);
-rrefreg_t *r_refreg_init(rrefreg_t *refreg);
-rrefreg_t *r_refreg_copy(const rrefreg_t* src);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
index a9e7fe4..5929add 100644 (file)
@@ -20,14 +20,14 @@ rvm_codegen_t *rvm_codegen_create()
 void rvm_codegen_destroy(rvm_codegen_t *cg)
 {
        rvm_codemap_destroy(cg->codemap);
-       r_array_destroy(cg->code);
+       r_object_destroy((robject_t*)cg->code);
        r_free(cg);
 }
 
 
 void rvm_codegen_clear(rvm_codegen_t *cg)
 {
-       r_array_setsize(cg->code, 0);
+       r_array_setlength(cg->code, 0);
        rvm_codemap_clear(cg->codemap);
 }
 
@@ -40,7 +40,7 @@ rvm_asmins_t *rvm_codegen_getcode(rvm_codegen_t *cg, ruint index)
 
 rulong rvm_codegen_getcodesize(rvm_codegen_t *cg)
 {
-       return r_array_size(cg->code);
+       return r_array_length(cg->code);
 }
 
 
@@ -56,9 +56,18 @@ ruint rvm_codegen_insertins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins)
 }
 
 
+ruint rvm_codegen_replaceins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins)
+{
+       return r_array_replace(cg->code, index, &ins);
+
+}
+
+
 ruint rvm_codegen_funcstart(rvm_codegen_t *cg, const rchar* name, ruint namesize, ruint args)
 {
-       ruint start = rvm_codegen_addins(cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R0)|BIT(FP)|BIT(SP)|BIT(LR)));
+       ruint start;
+       rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
+       start = rvm_codegen_addins(cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
        rvm_codegen_addins(cg, rvm_asm(RVM_ADD, SP, SP, DA, args));
        rvm_codemap_add(cg->codemap, name, namesize, start);
@@ -74,7 +83,9 @@ ruint rvm_codegen_funcstart_s(rvm_codegen_t *cg, const rchar* name, ruint args)
 
 ruint rvm_codegen_vargs_funcstart(rvm_codegen_t *cg, const rchar* name, ruint namesize)
 {
-       ruint start = rvm_codegen_addins(cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(R0)|BIT(FP)|BIT(SP)|BIT(LR)));
+       ruint start;
+       rvm_codegen_addins(cg, rvm_asm(RVM_NOP, XX, XX, XX, 0));
+       start = rvm_codegen_addins(cg, rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(FP)|BIT(SP)|BIT(LR)));
        rvm_codegen_addins(cg, rvm_asm(RVM_MOV, FP, SP, XX, 0));
        rvm_codegen_addins(cg, rvm_asm(RVM_ADD, SP, SP, R0, 0));
        rvm_codemap_add(cg->codemap, name, namesize, start);
index 254c519..b80f44c 100644 (file)
@@ -13,7 +13,7 @@
 extern "C" {
 #endif
 
-#define RVM_CODEGEN_FUNCINITOFFSET 4
+#define RVM_CODEGEN_FUNCINITOFFSET 3
 #define RVM_CODEGEN_E_NONE 0
 
 typedef struct rvm_codegen_s {
@@ -32,6 +32,7 @@ ruint rvm_codegen_vargs_funcstart_s(rvm_codegen_t *cg, const rchar* name);
 void rvm_codegen_funcend(rvm_codegen_t *cg);
 ruint rvm_codegen_addins(rvm_codegen_t *cg, rvm_asmins_t ins);
 ruint rvm_codegen_insertins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins);
+ruint rvm_codegen_replaceins(rvm_codegen_t *cg, ruint index, rvm_asmins_t ins);
 rvm_asmins_t *rvm_codegen_getcode(rvm_codegen_t *cg, ruint index);
 rulong rvm_codegen_getcodesize(rvm_codegen_t *cg);
 void rvm_codegen_clear(rvm_codegen_t *cg);
index a8cf290..a674c8d 100644 (file)
@@ -11,6 +11,7 @@ rvm_codemap_t *rvm_codemap_create()
        if (!codemap)
                return NULL;
        r_memset(codemap, 0, sizeof(*codemap));
+       codemap->blocks = r_array_create(sizeof(rvm_loopblock_t));
        codemap->labels = r_array_create(sizeof(rvm_codelabel_t*));
        codemap->hash = r_hash_create(5, r_hash_rstrequal, r_hash_rstrhash);
        return codemap;
@@ -21,7 +22,7 @@ void rvm_codemap_destroy(rvm_codemap_t *codemap)
 {
        int i;
        rvm_codelabel_t *label;
-       int len = codemap->labels->len;
+       int len = r_array_length(codemap->labels);
 
        for (i = 0; i < len; i++) {
                label = r_array_index(codemap->labels, i, rvm_codelabel_t*);
@@ -29,16 +30,45 @@ void rvm_codemap_destroy(rvm_codemap_t *codemap)
                r_free(label);
        }
 
-       r_array_destroy(codemap->labels);
-       r_hash_destroy(codemap->hash);
+       r_object_destroy((robject_t*)codemap->blocks);
+       r_object_destroy((robject_t*)codemap->labels);
+       r_object_destroy((robject_t*)codemap->hash);
        r_free(codemap);
 }
 
 
+void rvm_codemap_pushloopblock(rvm_codemap_t *codemap, rulong begin, rulong size)
+{
+       rvm_loopblock_t loop;
+       loop.begin = begin;
+       loop.size = size;
+       r_array_add(codemap->blocks, &loop);
+}
+
+
+void rvm_codemap_poploopblock(rvm_codemap_t *codemap)
+{
+       ruint len;
+       if ((len = r_array_length(codemap->blocks)) > 0) {
+               r_array_setlength(codemap->blocks, len - 1);
+       }
+}
+
+
+rvm_loopblock_t *rvm_codemap_currentloopblock(rvm_codemap_t *codemap)
+{
+       ruint len;
+       if ((len = r_array_length(codemap->blocks)) > 0) {
+               return (rvm_loopblock_t*)r_array_slot(codemap->blocks, len - 1);
+       }
+       return NULL;
+}
+
+
 void rvm_codemap_clear(rvm_codemap_t *codemap)
 {
        r_hash_removeall(codemap->hash);
-       r_array_setsize(codemap->labels, 0);
+       r_array_setlength(codemap->labels, 0);
 }
 
 
@@ -75,6 +105,14 @@ void rvm_codemap_invalid_add_s(rvm_codemap_t *codemap, const rchar *name)
 }
 
 
+rvm_codelabel_t *rvm_codemap_lastlabel(rvm_codemap_t *codemap)
+{
+       if (r_array_size(codemap->labels)) {
+               return (rvm_codelabel_t*)r_array_last(codemap->labels, rvm_codelabel_t*);
+       }
+       return NULL;
+}
+
 rvm_codelabel_t *rvm_codemap_lookup(rvm_codemap_t *codemap, const rchar *name, ruint namesize)
 {
        rstr_t lookupstr = {(char*)name, namesize};
index f21ecba..a664fe5 100644 (file)
@@ -16,10 +16,18 @@ extern "C" {
 typedef struct rvm_codelabel_s {
        rstr_t *name;
        rulong index;
+       rulong size; // Optional, used for function declarations
 } rvm_codelabel_t;
 
 
+typedef struct rvm_loopblock_s {
+       rulong begin;
+       rulong size;
+} rvm_loopblock_t;
+
+
 typedef struct rvm_codemap_s {
+       rarray_t *blocks;
        rarray_t *labels;
        rhash_t *hash;
 } rvm_codemap_t;
@@ -34,7 +42,11 @@ void rvm_codemap_add(rvm_codemap_t *codemap, const rchar *name, ruint namesize,
 void 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);
 
+void rvm_codemap_pushloopblock(rvm_codemap_t *codemap, rulong begin, rulong size);
+void rvm_codemap_poploopblock(rvm_codemap_t *codemap);
+rvm_loopblock_t *rvm_codemap_currentloopblock(rvm_codemap_t *codemap);
 
 #ifdef __cplusplus
 }
index a7d1419..b1af619 100644 (file)
 #include <stdarg.h>
 #include "rvmcpu.h"
 #include "rvmoperator.h"
+#include "rvmoperatorbin.h"
 #include "rvmoperatorcast.h"
-#include "rvmoperatoradd.h"
-#include "rvmoperatorsub.h"
-#include "rvmoperatormul.h"
-#include "rvmoperatordiv.h"
+#include "rvmoperatornot.h"
+#include "rvmoperatorlogicnot.h"
 #include "rmem.h"
 #include "rstring.h"
 #include "rvmreg.h"
 
 static const char *stropcalls[] = {
        "RVM_EXT",
+       "RVM_ABORT",
        "RVM_PRN",
        "RVM_ASR",
        "RVM_SWI",
        "RVM_MOV",
+       "RVM_INC",
+       "RVM_DEC",
        "RVM_ADD",
        "RVM_ADDS",
        "RVM_ADC",
@@ -56,6 +58,8 @@ static const char *stropcalls[] = {
        "RVM_DIV",
        "RVM_DVS",
        "RVM_DIVS",
+       "RVM_MOD",
+       "RVM_MODS",
        "RVM_BX",
        "RVM_BL",
        "RVM_B",
@@ -94,25 +98,46 @@ static const char *stropcalls[] = {
        "RVM_ROR",
        "RVM_PUSHM",
        "RVM_POPM",     
-       "RVM_TST",      
+       "RVM_TST",
        "RVM_TEQ",
        "RVM_CLR",
+       "RVM_ADDRS",
+
        "RVM_CAST",             /* Cast: op1 = (op3)op2 */
        "RVM_TYPE",             /* Type: op1 = typeof(op2) */
+       "RVM_SETTYPE",  /* Type: op1.type = op2 */
        "RVM_EMOV",
        "RVM_EADD",
        "RVM_ESUB",
        "RVM_EMUL",
        "RVM_EDIV",
+       "RVM_EMOD",
        "RVM_ELSL",
        "RVM_ELSR",
+       "RVM_ELSRU",
        "RVM_EAND",
        "RVM_EORR",
        "RVM_EXOR",
        "RVM_ENOT",
+       "RVM_ELAND",
+       "RVM_ELOR",
+       "RVM_ELNOT",
+       "RVM_EEQ",
+       "RVM_ENOTEQ",
+       "RVM_EGREAT",
+       "RVM_EGREATEQ",
+       "RVM_ELESS",
+       "RVM_ELESSEQ",
        "RVM_ECMP",
        "RVM_ECMN",
        "RVM_ALLOCSTR",
+       "RVM_ALLOCARR",
+       "RVM_ADDRA",
+       "RVM_ELDA",
+       "RVM_ESTA",
+       "RVM_ELDS",
+       "RVM_ESTS",
+       "UNKNOWN",
        "UNKNOWN",
        "UNKNOWN",
        "UNKNOWN",
@@ -128,48 +153,118 @@ static const char *stropcalls[] = {
 
 static void rvm_op_b(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       RVM_CPUREG_INCIP(cpu, PC, RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+       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);
+//     RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+       RVM_CPUREG_INCIP(cpu, PC, pc - 1);
 }
 
 
 static void rvm_op_beq(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       if ((cpu->status & RVM_STATUS_Z))
-               RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+       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);
+//             RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+               RVM_CPUREG_INCIP(cpu, PC, pc - 1);
+       }
 }
 
 
 static void rvm_op_bneq(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       if ((cpu->status & RVM_STATUS_Z) == 0)
-               RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+       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);
+//             RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+               RVM_CPUREG_INCIP(cpu, PC, pc - 1);
+       }
 }
 
 
 static void rvm_op_bleq(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       if ((cpu->status & RVM_STATUS_N) || (cpu->status & RVM_STATUS_Z))
-               RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+       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);
+//             RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+               RVM_CPUREG_INCIP(cpu, PC, pc - 1);
+       }
 }
 
 static void rvm_op_bgeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       if ((cpu->status & RVM_STATUS_N) == 0 || (cpu->status & RVM_STATUS_Z) == 1)
-               RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+       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);
+//             RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+               RVM_CPUREG_INCIP(cpu, PC, pc - 1);
+       }
 }
 
 
 static void rvm_op_bles(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       if ((cpu->status & RVM_STATUS_N))
-               RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+       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);
+//             RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+               RVM_CPUREG_INCIP(cpu, PC, pc - 1);
+       }
 }
 
 
 static void rvm_op_bgre(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       if ((cpu->status & RVM_STATUS_N) == 0 && (cpu->status & RVM_STATUS_Z) == 0)
-               RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETU(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+       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);
+//             RVM_CPUREG_SETIP(cpu, PC, RVM_CPUREG_GETIP(cpu, PC) + RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+               RVM_CPUREG_INCIP(cpu, PC, pc - 1);
+       }
 }
 
 
@@ -181,8 +276,16 @@ static void rvm_op_bx(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
 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);
+
        RVM_CPUREG_SETIP(cpu, LR, RVM_CPUREG_GETIP(cpu, PC));
-       RVM_CPUREG_INCIP(cpu, PC, RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+       RVM_CPUREG_INCIP(cpu, PC, pc - 1);
 }
 
 
@@ -483,6 +586,18 @@ static void rvm_op_add(rvmcpu_t *cpu, rvm_asmins_t *ins)
 }
 
 
+static void rvm_op_inc(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op1) + 1);
+}
+
+
+static void rvm_op_dec(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op1) - 1);
+}
+
+
 static void rvm_op_swi(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rvmcpu_swi swi;
@@ -490,7 +605,7 @@ static void rvm_op_swi(rvmcpu_t *cpu, rvm_asmins_t *ins)
        ruint ntable = (ruint) RVM_SWI_TABLE(ins->swi);
        ruint nswi = (ruint) RVM_SWI_NUM(ins->swi);
 
-       if (r_array_size(cpu->switables) <= ntable)
+       if (r_array_length(cpu->switables) <= ntable)
                RVM_ABORT(cpu, RVM_E_SWITABLE);
        switable = r_array_index(cpu->switables, ntable, rvm_switable_t*);
        swi = switable[nswi].op;
@@ -588,6 +703,30 @@ static void rvm_op_divs(rvmcpu_t *cpu, rvm_asmins_t *ins)
 }
 
 
+static void rvm_op_mod(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       if (!RVM_CPUREG_GETU(cpu, ins->op3))
+               RVM_ABORT(cpu, RVM_E_DIVZERO);
+
+       RVM_CPUREG_SETU(cpu, ins->op1, RVM_CPUREG_GETU(cpu, ins->op2) % RVM_CPUREG_GETU(cpu, ins->op3));
+}
+
+
+static void rvm_op_mods(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rsword res, op2 = RVM_CPUREG_GETU(cpu, ins->op2), op3 = RVM_CPUREG_GETU(cpu, ins->op3);
+
+       if (!op3)
+               RVM_ABORT(cpu, RVM_E_DIVZERO);
+       res = op2 % op3;
+       r_printf("mod RES: %ld\n", res);
+       RVM_CPUREG_SETU(cpu, ins->op1, res);
+       RVM_STATUS_CLRALL(cpu);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !res);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, res & RVM_SIGN_BIT);
+}
+
+
 static void rvm_op_dvs(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rsword res;
@@ -607,16 +746,16 @@ static void rvm_op_push(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rword sp = RVM_CPUREG_GETU(cpu, SP) + 1;
 
-       r_array_replace(cpu->stack, sp, (rconstpointer)&RVM_CPUREG_GET(cpu, ins->op1));
+       r_carray_replace(cpu->stack, sp, (rconstpointer)&RVM_CPUREG_GET(cpu, ins->op1));
        RVM_CPUREG_SETU(cpu, SP, sp);
 }
 
 
 static void rvm_op_sts(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rword sp = RVM_CPUREG_GETU(cpu, ins->op2) + RVM_CPUREG_GETU(cpu, ins->op3);
+       rword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
 
-       r_array_replace(cpu->stack, sp, (rconstpointer)&RVM_CPUREG_GET(cpu, ins->op1));
+       r_carray_replace(cpu->stack, sp, (rconstpointer)&RVM_CPUREG_GET(cpu, ins->op1));
 }
 
 
@@ -630,7 +769,7 @@ static void rvm_op_pushm(rvmcpu_t *cpu, rvm_asmins_t *ins)
                if (((rword)(1 << n)) & bits) {
                        i += 1;
                        sp += 1;
-                       r_array_replace(cpu->stack, sp, (rconstpointer)&RVM_CPUREG_GET(cpu, n));
+                       r_carray_replace(cpu->stack, sp, (rconstpointer)&RVM_CPUREG_GET(cpu, n));
                        bits &= ~(1<<n);
                }
        }
@@ -642,7 +781,7 @@ static void rvm_op_pop(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rword sp = RVM_CPUREG_GETU(cpu, SP);
 
-       RVM_CPUREG_SET(cpu, ins->op1, r_array_index(cpu->stack, sp, rvmreg_t));
+       RVM_CPUREG_SET(cpu, ins->op1, r_carray_index(cpu->stack, sp, rvmreg_t));
        if (ins->op1 != SP)
                RVM_CPUREG_SETU(cpu, SP, sp - 1);
 }
@@ -652,25 +791,36 @@ static void rvm_op_popm(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        int n;
        rword bits = RVM_CPUREG_GETU(cpu, ins->op1);
+       rword savedbits = bits;
        rword sp = RVM_CPUREG_GETU(cpu, SP);
 
        for (n = RLST - 1; bits && n >= 0; n--) {
                if (((rword)(1 << n)) & bits) {
-                       RVM_CPUREG_SET(cpu, n, r_array_index(cpu->stack, sp, rvmreg_t));
+                       RVM_CPUREG_SET(cpu, n, r_carray_index(cpu->stack, sp, rvmreg_t));
                        sp -= 1;
                        bits &= ~(1<<n);
                }
        }
-       if (!(((rword)(1 << SP)) & bits))
+       if (!(((rword)(1 << SP)) & savedbits))
                RVM_CPUREG_SETU(cpu, SP, sp);
 }
 
 
 static void rvm_op_lds(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rword sp = RVM_CPUREG_GETU(cpu, ins->op2) + RVM_CPUREG_GETU(cpu, ins->op3);
+       rword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
 
-       RVM_CPUREG_SET(cpu, ins->op1, r_array_index(cpu->stack, sp, rvmreg_t));
+       RVM_CPUREG_SET(cpu, ins->op1, r_carray_index(cpu->stack, sp, rvmreg_t));
+}
+
+
+static void rvm_op_addrs(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rword sp = ((ins->op2 != XX) ? RVM_CPUREG_GETU(cpu, ins->op2) : 0) + ((ins->op3 != XX) ? RVM_CPUREG_GETU(cpu, ins->op3) : 0);
+
+       RVM_CPUREG_CLEAR(cpu, ins->op1);
+       RVM_CPUREG_SETTYPE(cpu, ins->op1, RVM_DTYPE_POINTER);
+       RVM_CPUREG_SETP(cpu, ins->op1, r_carray_slot_expand(cpu->stack, sp));
 }
 
 
@@ -698,6 +848,7 @@ static void rvm_op_ldm(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
        for (n = 0; bits && n < RLST; n++) {
                if (((rword)(1 << n)) & bits) {
+                       RVM_CPUREG_CLEAR(cpu, n);
                        RVM_CPUREG_SETU(cpu, n, *src);
                        src += 1;
                        bits &= ~(1<<n);
@@ -791,10 +942,10 @@ int rvm_asm_dump_reg_to_str(unsigned char reg, char *str, ruint size)
                ret = rvm_snprintf(str, size, "PC ");
        else if (reg == DA)
                ret = rvm_snprintf(str, size, "DA ");
-       else if (reg >= 0 && reg < 10)
+       else if (reg >= 0 && reg < RVM_REGS_NUM/2)
                ret = rvm_snprintf(str, size, "R%d ",  reg);
-       else if (reg >= 10)
-               ret = rvm_snprintf(str, size, "R%d",  reg);
+       else if (reg >= RVM_REGS_NUM/2)
+               ret = rvm_snprintf(str, size, "S%d ",  reg & ((1 << (RVM_OPERAND_BITS-1))-1));
 
        return ret;
 }
@@ -802,29 +953,46 @@ int rvm_asm_dump_reg_to_str(unsigned char reg, char *str, ruint size)
 
 static void rvm_op_prn(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *r = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op1));
+       rvmreg_t *r = RVM_CPUREG_PTR(cpu, ins->op1);
 
        if (rvm_reg_gettype(r) == RVM_DTYPE_UNSIGNED)
                rvm_printf("(UNSIGNED) R%d = %lu(0x%lx)\n", ins->op1, RVM_REG_GETU(r), RVM_REG_GETU(r));
+       else if (rvm_reg_gettype(r) == RVM_DTYPE_BOOLEAN)
+               rvm_printf("(UNSIGNED) R%d = %lu(0x%lx)\n", ins->op1, RVM_REG_GETU(r), RVM_REG_GETU(r));
+       else if (rvm_reg_gettype(r) == RVM_DTYPE_POINTER)
+               rvm_printf("(POINTER) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
        else if (rvm_reg_gettype(r) == RVM_DTYPE_LONG)
                rvm_printf("(LONG) R%d = %ld\n", ins->op1, RVM_REG_GETL(r));
        else if (rvm_reg_gettype(r) == RVM_DTYPE_DOUBLE)
                rvm_printf("(DOUBLE) R%d = %0.2f\n", ins->op1, RVM_REG_GETD(r));
        else if (rvm_reg_gettype(r) == RVM_DTYPE_STRING)
                rvm_printf("(STRING) R%d = %s\n", ins->op1, ((rstring_t*) RVM_REG_GETP(r))->s.str);
+       else if (rvm_reg_gettype(r) == RVM_DTYPE_ARRAY)
+               rvm_printf("(ARRAY) R%d = %p\n", ins->op1, RVM_REG_GETP(r));
        else
                rvm_printf("(UNKNOWN) R%d = ?\n", ins->op1);
 }
 
 
-int rvm_asm_dump_pi_to_str(rvm_asmins_t *pi, char *str, ruint size)
+int rvm_asm_dump_pi_to_str(rvmcpu_t *vm, rvm_asmins_t *pi, char *str, ruint size)
 {
        int ret = 0, sz = size;
 
        if (pi->opcode == RVM_SWI) {
                rchar szSwi[64];
                r_memset(szSwi, 0, sizeof(szSwi));
-               rvm_snprintf(szSwi, sizeof(szSwi) - 1, "%s(%x)", stropcalls[pi->opcode], (ruint32)pi->swi);
+               if (!vm) {
+                       rvm_snprintf(szSwi, sizeof(szSwi) - 1, "%s(%x)", stropcalls[pi->opcode], (ruint32)pi->swi);
+               } else {
+                       rvm_switable_t *switable;
+                       ruint ntable = (ruint) RVM_SWI_TABLE(pi->swi);
+                       ruint nswi = (ruint) RVM_SWI_NUM(pi->swi);
+
+                       if (ntable < r_array_length(vm->switables)) {
+                               switable = r_array_index(vm->switables, ntable, rvm_switable_t*);
+                               rvm_snprintf(szSwi, sizeof(szSwi) - 1, "(%s)",  switable[nswi].name ? switable[nswi].name : "unknown");
+                       }
+               }
                if ((ret = rvm_snprintf(str, sz, "%16s   ", szSwi)) < 0)
                        return ret;
        } else {
@@ -886,7 +1054,7 @@ void rvm_asm_dump(rvm_asmins_t *pi, ruint count)
 {
        char buffer[256];
        while (count) {
-               rvm_asm_dump_pi_to_str(pi, buffer, sizeof(buffer));
+               rvm_asm_dump_pi_to_str(NULL, pi, buffer, sizeof(buffer));
                rvm_printf("%s\n", buffer);
                ++pi;
                --count;
@@ -899,7 +1067,7 @@ static void rvm_cpu_dumpregs(rvm_asmins_t *pi, rvmcpu_t *vm)
     int ret;
        char buffer[1024];
        
-       ret = rvm_asm_dump_pi_to_str(pi, buffer, sizeof(buffer));
+       ret = rvm_asm_dump_pi_to_str(vm, pi, buffer, sizeof(buffer));
        if (ret < 0)
                return;
     ret = rvm_snprintf(buffer + ret, sizeof(buffer) - ret, "                                                                                        ");
@@ -934,11 +1102,18 @@ static void rvm_op_type(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rvmreg_type_t type = (rvmreg_type_t)RVM_CPUREG_GETTYPE(cpu, ins->op2);
 
-       RVM_CPUREG_CLEAR(cpu, ins->op1);
        RVM_CPUREG_SETU(cpu, ins->op1, type);
 }
 
 
+static void rvm_op_settype(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_type_t type = (rvmreg_type_t)RVM_CPUREG_GETU(cpu, ins->op2);
+
+       RVM_CPUREG_SETTYPE(cpu, ins->op1, type);
+}
+
+
 static void rvm_op_emov(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
        rvm_op_mov(cpu, ins);
@@ -947,8 +1122,8 @@ static void rvm_op_emov(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
 static void rvm_op_eadd(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *arg2 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op2));
-       rvmreg_t *arg3 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op3));
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
 
        rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_ADD, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
 }
@@ -956,8 +1131,8 @@ static void rvm_op_eadd(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
 static void rvm_op_esub(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *arg2 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op2));
-       rvmreg_t *arg3 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op3));
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
 
        rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_SUB, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
 }
@@ -965,8 +1140,8 @@ static void rvm_op_esub(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
 static void rvm_op_emul(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *arg2 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op2));
-       rvmreg_t *arg3 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op3));
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
 
        rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_MUL, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
 }
@@ -974,17 +1149,26 @@ static void rvm_op_emul(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
 static void rvm_op_ediv(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *arg2 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op2));
-       rvmreg_t *arg3 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op3));
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
 
        rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_DIV, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
 }
 
 
+static void rvm_op_emod(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
+
+       rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_MOD, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
+}
+
+
 static void rvm_op_elsl(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *arg2 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op2));
-       rvmreg_t *arg3 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op3));
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
 
        rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LSL, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
 }
@@ -992,17 +1176,26 @@ static void rvm_op_elsl(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
 static void rvm_op_elsr(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *arg2 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op2));
-       rvmreg_t *arg3 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op3));
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
 
        rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LSR, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
 }
 
 
+static void rvm_op_elsru(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
+
+       rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LSRU, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
+}
+
+
 static void rvm_op_eand(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *arg2 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op2));
-       rvmreg_t *arg3 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op3));
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
 
        rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_AND, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
 }
@@ -1010,8 +1203,8 @@ static void rvm_op_eand(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
 static void rvm_op_eorr(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *arg2 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op2));
-       rvmreg_t *arg3 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op3));
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
 
        rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_OR, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
 }
@@ -1019,8 +1212,8 @@ static void rvm_op_eorr(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
 static void rvm_op_exor(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *arg2 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op2));
-       rvmreg_t *arg3 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op3));
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
 
        rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_XOR, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
 }
@@ -1028,16 +1221,96 @@ static void rvm_op_exor(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
 static void rvm_op_enot(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *arg2 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op2));
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
 
        rvm_opmap_invoke_unary_handler(cpu->opmap, RVM_OPID_NOT, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2);
 }
 
 
+static void rvm_op_eland(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
+
+       rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LOGICAND, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
+}
+
+
+static void rvm_op_elor(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
+
+       rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LOGICOR, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
+}
+
+
+static void rvm_op_elnot(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+
+       rvm_opmap_invoke_unary_handler(cpu->opmap, RVM_OPID_LOGICNOT, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2);
+}
+
+
+static void rvm_op_eeq(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
+
+       rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_EQ, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
+}
+
+
+static void rvm_op_enoteq(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
+
+       rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_NOTEQ, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
+}
+
+
+static void rvm_op_egreat(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
+
+       rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_GREATER, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
+}
+
+
+static void rvm_op_egreateq(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
+
+       rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_GREATEREQ, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
+}
+
+
+static void rvm_op_elesseq(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
+
+       rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LESSEQ, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
+}
+
+
+static void rvm_op_eless(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       rvmreg_t *arg3 = RVM_CPUREG_PTR(cpu, ins->op3);
+
+       rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_LESS, cpu, RVM_CPUREG_PTR(cpu, ins->op1), arg2, arg3);
+}
+
+
 static void rvm_op_ecmp(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *arg1 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op1));
-       rvmreg_t *arg2 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op2));
+       rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
 
        rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CMP, cpu, NULL, arg1, arg2);
 }
@@ -1045,8 +1318,8 @@ static void rvm_op_ecmp(rvmcpu_t *cpu, rvm_asmins_t *ins)
 
 static void rvm_op_ecmn(rvmcpu_t *cpu, rvm_asmins_t *ins)
 {
-       rvmreg_t *arg1 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op1));
-       rvmreg_t *arg2 = rvm_reg_unshadow(RVM_CPUREG_PTR(cpu, ins->op2));
+       rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
 
        rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CMN, cpu, NULL, arg1, arg2);
 }
@@ -1060,17 +1333,98 @@ static void rvm_op_allocstr(rvmcpu_t *cpu, rvm_asmins_t *ins)
        if (!s) {
                RVM_ABORT(cpu, RVM_E_ILLEGAL);
        }
+       rvm_gc_add(cpu->gc, (robject_t*)s);
        rvm_reg_setstring(arg1, s);
-       rvm_reg_convert_to_refreg(arg1);
+}
+
+
+static void rvm_op_allocarr(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
+       ruint size = RVM_CPUREG_GETU(cpu, ins->op2);
+       rcarray_t *a = r_carray_create_rvmreg();
+       if (!a) {
+               RVM_ABORT(cpu, RVM_E_ILLEGAL);
+       }
+       r_carray_setlength(a, size);
+       rvm_gc_add(cpu->gc, (robject_t*)a);
+       rvm_reg_setarray(arg1, (robject_t*)a);
+}
+
+
+static void rvm_op_addra(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       ruint index = RVM_CPUREG_GETU(cpu, ins->op3);
+       rcarray_t *a = RVM_REG_GETP(arg2);
+
+       if (rvm_reg_gettype(arg2) != RVM_DTYPE_ARRAY) {
+               RVM_ABORT(cpu, RVM_E_ILLEGAL);
+       }
+       RVM_REG_CLEAR(arg1);
+       RVM_REG_SETTYPE(arg1, RVM_DTYPE_POINTER);
+       RVM_REG_SETP(arg1, r_carray_slot_expand(a, index));
+}
+
+
+static void rvm_op_elda(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       ruint index = RVM_CPUREG_GETU(cpu, ins->op3);
+       rcarray_t *a = RVM_REG_GETP(arg2);
+
+       if (rvm_reg_gettype(arg2) != RVM_DTYPE_ARRAY) {
+               RVM_ABORT(cpu, RVM_E_ILLEGAL);
+       }
+       *arg1 = *((rvmreg_t*)r_carray_slot_expand(a, index));
+}
+
+
+static void rvm_op_esta(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       rvmreg_t *arg1 = RVM_CPUREG_PTR(cpu, ins->op1);
+       rvmreg_t *arg2 = RVM_CPUREG_PTR(cpu, ins->op2);
+       ruint index = RVM_CPUREG_GETU(cpu, ins->op3);
+       rcarray_t *a = RVM_REG_GETP(arg2);
+
+       if (rvm_reg_gettype(arg2) != RVM_DTYPE_ARRAY) {
+               RVM_ABORT(cpu, RVM_E_ILLEGAL);
+       }
+       r_carray_replace(a, index, arg1);
+}
+
+
+static void rvm_op_abort(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       RVM_ABORT(cpu, RVM_CPUREG_GETU(cpu, ins->op1));
+}
+
+
+static void rvm_op_elds(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       ruint index = RVM_CPUREG_GETU(cpu, ins->op2) + RVM_CPUREG_GETU(cpu, ins->op3);
+       RVM_CPUREG_SET(cpu, ins->op1, *RVM_STACK_ADDR(cpu, index));
+}
+
+
+static void rvm_op_ests(rvmcpu_t *cpu, rvm_asmins_t *ins)
+{
+       ruint index = RVM_CPUREG_GETU(cpu, ins->op2) + RVM_CPUREG_GETU(cpu, ins->op3);
+       *RVM_STACK_ADDR(cpu, index) = RVM_CPUREG_GET(cpu, ins->op1);
 }
 
 
 static rvm_cpu_op ops[] = {
        rvm_op_exit,            // RVM_EXT
+       rvm_op_abort,           // RVM_ABORT
        rvm_op_prn,                     // RVM_PRN
        rvm_op_asr,                     // RVM_ASR
        rvm_op_swi,                     // RVM_swi
        rvm_op_mov,                     // RVM_MOV
+       rvm_op_inc,                     // RVM_INC
+       rvm_op_dec,                     // RVM_DEC
        rvm_op_add,                     // RVM_ADD
        rvm_op_adds,            // RVM_ADDS
        rvm_op_adc,                     // RVM_ADC
@@ -1089,6 +1443,8 @@ static rvm_cpu_op ops[] = {
        rvm_op_div,                     // RVM_DIV
        rvm_op_dvs,                     // RVM_DVS
        rvm_op_divs,            // RVM_DIVS
+       rvm_op_mod,                     // RVM_MOD
+       rvm_op_mods,            // RVM_MODS
        rvm_op_bx,                      // RVM_BX
        rvm_op_bl,                      // RVM_BL
        rvm_op_b,                       // RVM_B
@@ -1130,24 +1486,44 @@ static rvm_cpu_op ops[] = {
        rvm_op_tst,             // RVM_TST
        rvm_op_teq,             // RVM_TEQ
        rvm_op_clr,             // RVM_CLR
+       rvm_op_addrs,           // RVM_ADDRS
 
 /* Extended VM instructions */
        rvm_op_cast,            // RVM_CAST
        rvm_op_type,            // RVM_TYPE
+       rvm_op_settype,         // RVM_SETTYPE
        rvm_op_emov,            // RVM_EMOV
        rvm_op_eadd,            // RVM_EADD
        rvm_op_esub,            // RVM_ESUB
        rvm_op_emul,            // RVM_EMUL
        rvm_op_ediv,            // RVM_EDIV
+       rvm_op_emod,            // RVM_MOD
        rvm_op_elsl,            // RVM_ELSL
        rvm_op_elsr,            // RVM_ELSR
+       rvm_op_elsru,           // RVM_ELSRU
        rvm_op_eand,            // RVM_EAND
        rvm_op_eorr,            // RVM_EORR
        rvm_op_exor,            // RVM_EXOR
        rvm_op_enot,            // RVM_ENOT
+
+       rvm_op_eland,           // RVM_ELAND
+       rvm_op_elor,            // RVM_ELOR
+       rvm_op_elnot,           // RVM_ELNOT
+       rvm_op_eeq,                     // RVM_EEQ
+       rvm_op_enoteq,          // RVM_ENOTEQ
+       rvm_op_egreat,          // RVM_EGREAT
+       rvm_op_egreateq,        // RVM_EGREATEQ
+       rvm_op_eless,           // RVM_ELESS
+       rvm_op_elesseq,         // RVM_ELESSEQ
        rvm_op_ecmp,            // RVM_ECMP
        rvm_op_ecmn,            // RVM_ECMN
        rvm_op_allocstr,        // RVM_ALLOCSTR
+       rvm_op_allocarr,        // RVM_ALLOCARR
+       rvm_op_addra,           // RVM_ADDRA
+       rvm_op_elda,            // RVM_ELDA
+       rvm_op_esta,            // RVM_ESTA
+       rvm_op_elds,            // RVM_ELDS
+       rvm_op_ests,            // RVM_ESTS
        (void*) 0,
        (void*) 0,
        (void*) 0,
@@ -1158,7 +1534,7 @@ static rvm_cpu_op ops[] = {
        (void*) 0,
        
 };
-       
+
 
 rvmcpu_t *rvm_cpu_create()
 {
@@ -1169,21 +1545,14 @@ rvmcpu_t *rvm_cpu_create()
                return ((void*)0);
        r_memset(cpu, 0, sizeof(*cpu));
        cpu->switables = r_array_create(sizeof(rvm_switable_t*));
-       cpu->stack = r_array_create(sizeof(rvmreg_t));
+       cpu->stack = r_carray_create(sizeof(rvmreg_t));
+       cpu->stack->user = (void*)cpu;
        cpu->opmap = rvm_opmap_create();
+       cpu->gc = rvm_gc_create();
+       rvm_op_binary_init(cpu->opmap);
        rvm_op_cast_init(cpu->opmap);
-       rvm_op_add_init(cpu->opmap);
-       rvm_op_sub_init(cpu->opmap);
-       rvm_op_mul_init(cpu->opmap);
-       rvm_op_div_init(cpu->opmap);
-       rvm_op_lsl_init(cpu->opmap);
-       rvm_op_lsr_init(cpu->opmap);
-       rvm_op_or_init(cpu->opmap);
-       rvm_op_xor_init(cpu->opmap);
-       rvm_op_and_init(cpu->opmap);
        rvm_op_not_init(cpu->opmap);
-       rvm_op_cmp_init(cpu->opmap);
-       rvm_op_cmn_init(cpu->opmap);
+       rvm_op_logicnot_init(cpu->opmap);
 
        return cpu;
 }
@@ -1191,14 +1560,16 @@ rvmcpu_t *rvm_cpu_create()
 
 void rvm_cpu_destroy(rvmcpu_t *cpu)
 {
-       r_array_destroy(cpu->switables);
-       r_array_destroy(cpu->stack);
+       r_object_destroy((robject_t*)cpu->switables);
+       r_object_destroy((robject_t*)cpu->stack);
        rvm_opmap_destroy(cpu->opmap);
+       rvm_gc_deallocate_all(cpu->gc);
+       rvm_gc_destroy(cpu->gc);
        r_free(cpu);
 }
 
 
-rint rvm_cpu_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off)
+rint rvm_cpu_dbgarg_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off, rint debug)
 {
        rvm_asmins_t *pi;
        rvmreg_t *regda = RVM_CPUREG_PTR(cpu, DA);
@@ -1209,14 +1580,18 @@ rint rvm_cpu_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off)
        cpu->error = 0;
        do {
                pi = RVM_REG_GETIP(regpc);
-               if (pi->type == RVM_DTYPE_DOUBLE) {
-                       RVM_REG_SETD(regda, pi->data.d);
-               } else {
-                       RVM_REG_SETU(regda, pi->data.u);
+               if (pi->da) {
+                       if (pi->type == RVM_DTYPE_DOUBLE) {
+                               RVM_REG_SETD(regda, pi->data.d);
+                       } else {
+                               RVM_REG_SETU(regda, pi->data.u);
+                       }
+                       RVM_REG_SETTYPE(regda, pi->type);
+                       RVM_REG_ASSIGNFLAGS(regda, (pi->type >= RVM_DTYPE_STRING) ? RVM_INFOBIT_ROBJECT : 0);
                }
-               RVM_REG_SETTYPE(regda, pi->type);
-               RVM_REG_CLRFLAG(regda, RVM_INFOBIT_ALL);
                ops[pi->opcode](cpu, pi);
+               if (debug)
+                       rvm_cpu_dumpregs(pi, cpu);
                if (cpu->abort)
                        return -1;
                RVM_REG_INCIP(regpc, 1);
@@ -1225,31 +1600,15 @@ rint rvm_cpu_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off)
 }
 
 
-rint rvm_cpu_exec_debug(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off)
+rint rvm_cpu_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off)
 {
-       rvm_asmins_t *pi;
-       rvmreg_t *regda = RVM_CPUREG_PTR(cpu, DA);
-       rvmreg_t *regpc = RVM_CPUREG_PTR(cpu, PC);
+       return rvm_cpu_dbgarg_exec(cpu, prog, off, 0);
+}
 
-       RVM_CPUREG_SETIP(cpu, PC, prog + off);
-       cpu->abort = 0;
-       cpu->error = 0;
-       do {
-               pi = RVM_REG_GETIP(regpc);
-               if (pi->type == RVM_DTYPE_DOUBLE) {
-                       RVM_REG_SETD(regda, pi->data.d);
-               } else {
-                       RVM_REG_SETU(regda, pi->data.u);
-               }
-               RVM_REG_SETTYPE(regda, pi->type);
-               RVM_REG_CLRFLAG(regda, RVM_INFOBIT_ALL);
-               ops[pi->opcode](cpu, pi);
-               if (cpu->abort)
-                       return -1;
-               rvm_cpu_dumpregs(pi, cpu);              
-               RVM_REG_INCIP(regpc, 1);
-       } while (pi->opcode);
-       return 0;
+
+rint rvm_cpu_exec_debug(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off)
+{
+       return rvm_cpu_dbgarg_exec(cpu, prog, off, 1);
 }
 
 
@@ -1258,7 +1617,7 @@ rint rvm_cpu_getswi(rvmcpu_t *cpu, const rchar *swiname)
        rint ntable, nswi;
        rvm_switable_t *swientry;
 
-       for (ntable = 0; ntable < cpu->switables->len; ntable++) {
+       for (ntable = 0; ntable < r_array_length(cpu->switables); ntable++) {
                swientry = r_array_index(cpu->switables, ntable, rvm_switable_t*);
                for (nswi = 0; swientry[nswi].name; nswi++) {
                        if (r_strcmp(swientry[nswi].name, swiname) == 0)
@@ -1293,7 +1652,8 @@ rvm_asmins_t rvm_asmp(rword opcode, rword op1, rword op2, rword op3, rpointer da
        a.op2 = (ruint8)op2;
        a.op3 = (ruint8)op3;
        a.data.u = (rword)data;
-
+       if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
+               a.da = 1;
        return a;
 }
 
@@ -1309,7 +1669,8 @@ rvm_asmins_t rvm_asm(rword opcode, rword op1, rword op2, rword op3, rword data)
        a.op2 = (ruint8)op2;
        a.op3 = (ruint8)op3;
        a.data.u = (rword)data;
-
+       if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
+               a.da = 1;
        return a;
 }
 
@@ -1326,6 +1687,26 @@ rvm_asmins_t rvm_asml(rword opcode, rword op1, rword op2, rword op3, rlong data)
        a.op3 = (ruint8)op3;
        a.data.u = (rword)data;
        a.type = RVM_DTYPE_LONG;
+       if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
+               a.da = 1;
+       return a;
+}
+
+
+rvm_asmins_t rvm_asmb(rword opcode, rword op1, rword op2, rword op3, rword data)
+{
+       rvm_asmins_t a;
+
+       r_memset(&a, 0, sizeof(a));
+       a.opcode = (ruint32) RVM_ASMINS_OPCODE(opcode);
+       a.swi = (ruint32) RVM_ASMINS_SWI(opcode);
+       a.op1 = (ruint8)op1;
+       a.op2 = (ruint8)op2;
+       a.op3 = (ruint8)op3;
+       a.data.u = (rword)(data ? 1 : 0);
+       a.type = RVM_DTYPE_BOOLEAN;
+       if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
+               a.da = 1;
        return a;
 }
 
@@ -1342,6 +1723,9 @@ rvm_asmins_t rvm_asmd(rword opcode, rword op1, rword op2, rword op3, rdouble dat
        a.op3 = (ruint8)op3;
        a.data.d = data;
        a.type = RVM_DTYPE_DOUBLE;
+       if ((ruint8)op1 == DA || (ruint8)op2 == DA || (ruint8)op3 == DA)
+               a.da = 1;
+
        return a;
 }
 
@@ -1358,6 +1742,7 @@ rvm_asmins_t rvm_asmr(rword opcode, rword op1, rword op2, rword op3, rpointer pR
        a.op3 = (ruint8)op3;
        a.data.u = (rword)pReloc;
        a.flags = RVM_ASMINS_RELOC | RVM_ASMINS_RELOCPTR;
+       a.da = 1;
 
        return a;
 }
@@ -1375,6 +1760,7 @@ rvm_asmins_t rvm_asmx(rword opcode, rword op1, rword op2, rword op3, rpointer pR
        a.op3 = (ruint8)op3;
        a.data.u = (rword)pReloc;
        a.flags = RVM_ASMINS_RELOC;
+       a.da = 1;
 
        return a;
 }
index 79ac15a..a65b729 100644 (file)
 
 #include "rtypes.h"
 #include "rarray.h"
+#include "rcarray.h"
+#include "rvmreg.h"
+#include "rvmgc.h"
 
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#define RVM_MIN_REGSIZE (sizeof(rword)/8)
-
 
 enum {
        RVM_EXT = 0,
+       RVM_ABORT,              /* Abort: set the error code, op1: error code */
        RVM_PRN,
        RVM_ASR,                /* Arithmetic shift right: op1 = op2 >> op3, preserve the signed bit */
        RVM_SWI,
        RVM_MOV,
+       RVM_INC,                /* INC: op1 = op1 + 1 */
+       RVM_DEC,                /* DEC: op1 = op1 - 1 */
        RVM_ADD,                /* Add: op1 = op2 + op3 */
        RVM_ADDS,               /* Add: op1 = op2 + op3, update the status register */
        RVM_ADC,                /* Add: op1 = op2 + op3 + C, update the status register */
@@ -56,6 +60,8 @@ enum {
        RVM_DIV,                /* Divide: op1 = op2 / op3 */
        RVM_DVS,                /* Signed division: op1 = op2 / op3 */  
        RVM_DIVS,               /* Divide: op1 = op2 / op3, Update the status register */
+       RVM_MOD,                /* Modulo: op1 = op2 % op3 */
+       RVM_MODS,               /* Modulo: op1 = op2 % op3, Update the status register */
        RVM_BX,                 /* Jump to op1 */
        RVM_BL,                 /* Branch Link */
        RVM_B,                  /* Branch */
@@ -97,49 +103,47 @@ enum {
        RVM_TST,
        RVM_TEQ,
        RVM_CLR,                /* Clear op1. If the reg has dynamic memory associated with with it (RVM_INFOBIT_ROBJECT) it will be cleared */
+       RVM_ADDRS,              /* Memory location of the stack at offset op2 + op3 */
 
 /* Extended VM opcodes, */
        RVM_CAST,               /* Cast: op1 = (op3)op2 */
        RVM_TYPE,               /* Type: op1 = typeof(op2) */
+       RVM_SETTYPE,    /* Type: op1.type = op2 */
        RVM_EMOV,
        RVM_EADD,               /* Add: op1 = op2 + op3 */
        RVM_ESUB,               /* Subtract: op1 = op2 - op3 */
        RVM_EMUL,               /* Multiply: op1 = op2 * op3 */
        RVM_EDIV,               /* Divide: op1 = op2 / op3 */
+       RVM_EMOD,               /* Modulo: op1 = op2 % op3 */
        RVM_ELSL,               /* Logical Shift Left: op1 = op2 << op3, update the status register */
        RVM_ELSR,               /* Logical Shift Right: op1 = op2 >> op3, update the status register */
+       RVM_ELSRU,              /* Logical Unsigned Shift Right: op1 = op2 >>> op3, update the status register */
        RVM_EAND,               /* Bitwise AND: op1 = op2 & op3, update status register */
-       RVM_EORR,               /* Logical OR: op1 = op2 | op3, update the status register */
-       RVM_EXOR,               /* LOGICAL XOR: op1 = op2 ^ op3, update the status register */
+       RVM_EORR,               /* Bitwise OR: op1 = op2 | op3, update the status register */
+       RVM_EXOR,               /* Bitwise XOR: op1 = op2 ^ op3, update the status register */
        RVM_ENOT,               /* Bitwise NOT: op1 = ~op2, Update the status register */
+       RVM_ELAND,              /* Logical AND: op1 = op2 && op3, update status register */
+       RVM_ELOR,               /* Logical OR: op1 = op2 || op3, update the status register */
+       RVM_ELNOT,              /* Logical NOT: op1 = !op2, update the status register */
+       RVM_EEQ,                /* op1 = op2 == op3 ? 1 : 0 */
+       RVM_ENOTEQ,             /* op1 = op2 != op3 ? 1 : 0 */
+       RVM_EGREAT,             /* op1 = op2 > op3 ? 1 : 0 */
+       RVM_EGREATEQ,   /* op1 = op2 >= op3 ? 1 : 0 */
+       RVM_ELESS,              /* op1 = op2 < op3 ? 1 : 0 */
+       RVM_ELESSEQ,    /* op1 = op2 <= op3 ? 1 : 0 */
+
        RVM_ECMP,               /* Compare: status register is updated based on the result: op1 - op2 */
        RVM_ECMN,               /* Compare Negative: status register is updated based on the result: op1 + op2 */
-       RVM_ALLOCSTR    /* Allocate string in op1, op2 is pointer (char*) to string, op3 is the size */
-};
+       RVM_ALLOCSTR,   /* Allocate string in op1, op2 is pointer (char*) to string, op3 is the size */
+       RVM_ALLOCARR,   /* Allocate array in op1, op2 is the size */
+       RVM_ADDRA,              /* op1 is the destination memory, op2 is the array, op3 is the offset */
+       RVM_ELDA,               /* op1 is the destination, op2 is the array, op3 is the offset */
+       RVM_ESTA,               /* op1 is the source, op2 is the array, op3 is the offset */
+       RVM_ELDS,               /* op1 is the destination, load the value from stack at offset op2 + op3 */
+       RVM_ESTS,               /* op1 is the source, store the value on stack at offset op2 + op3  */
 
+};
 
-#define RVM_DTYPE_NONE 0
-#define RVM_DTYPE_WORD RVM_DTYPE_NONE
-#define RVM_DTYPE_UNSIGNED RVM_DTYPE_NONE
-#define RVM_DTYPE_LONG 1
-#define RVM_DTYPE_POINTER 2                    /* Generic pointer, it can point to any memory object */
-#define RVM_DTYPE_DOUBLE 3
-#define RVM_DTYPE_BOOLEAN 4
-#define RVM_DTYPE_STRING 5
-#define RVM_DTYPE_ARRAY 6
-#define RVM_DTYPE_HARRAY 7
-#define RVM_DTYPE_REFREG 8                     /* Reference pointer, points to another rrefreg_t object */
-#define RVM_DTYPE_RELOCPTR 14          /* Relocation, using pointers */
-#define RVM_DTYPE_RELOCINDEX 15                /* Relocation, using offsets */
-#define RVM_DTYPE_USER 16
-#define RVM_DTYPE_SIZE (1 << 5)
-#define RVM_DTYPE_MASK (RVM_DTYPE_SIZE - 1)
-#define RVM_DTYPE_MAX (RVM_DTYPE_MASK)
-#define RVM_DTYPE_USERDEF(__n__) (RVM_DTYPE_USER + (__n__))
-
-#define RVM_INFOBIT_ROBJECT (1 << 0)
-#define RVM_INFOBIT_LAST (1 << 15)
-#define RVM_INFOBIT_ALL (RVM_INFOBIT_ROBJECT | RVM_INFOBIT_LAST)
 
 #define RVM_REGISTER_BITS (8 * sizeof(rword))
 #define RVM_SIGN_BIT (1LU << (RVM_REGISTER_BITS - 1))
@@ -160,7 +164,8 @@ do { \
         RVM_STATUS_CLRBIT(cpu, b); \
 } while (0)
 
-
+#define RVM_OPERAND_BITS 5
+#define RVM_REGS_NUM (1 << RVM_OPERAND_BITS)
 #define R0 0
 #define R1 1
 #define R2 2
@@ -198,62 +203,14 @@ do { \
 #define SP R27
 #define LR R28
 #define PC R29
-#define DA 30          /* The DA register should never be modified manually, otherwise the result is undefined */
-#define XX 31
-#define RLST 31
+#define DA R30         /* The DA register should never be modified manually, otherwise the result is undefined */
+#define XX R31
+#define RLST XX
 
 #define RVM_STACK_CHUNK 256
 #define RVM_ABORT(__cpu__, __e__) do { __cpu__->error = (__e__); (__cpu__)->abort = 1; ASSERT(0); return; } while (0)
 #define BIT(__shiftby__) (1 << (__shiftby__))
 
-#define RVM_CPUREG_PTR(__cpu__, __r__) (&(__cpu__)->r[(__r__)])
-#define RVM_CPUREG_GET(__cpu__, __r__) (__cpu__)->r[(__r__)]
-#define RVM_CPUREG_SET(__cpu__, __r__, __val__) do { (__cpu__)->r[(__r__)] = (rvmreg_t)(__val__); } while (0)
-
-#define RVM_REG_GETTYPE(__r__) (__r__)->type
-#define RVM_REG_SETTYPE(__r__, __val__) do { (__r__)->type = (__val__); } while(0);
-#define RVM_CPUREG_GETTYPE(__cpu__, __r__) RVM_REG_GETTYPE(RVM_CPUREG_PTR(__cpu__, __r__))
-#define RVM_CPUREG_SETTYPE(__cpu__, __r__, __val__) RVM_REG_SETTYPE(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
-
-#define RVM_REG_TSTFLAG(__r__, __flag__) ((__r__)->flags & (__flag__)) ? TRUE : FALSE
-#define RVM_REG_SETFLAG(__r__, __flag__) do { (__r__)->flags |= (__flag__); } while (0)
-#define RVM_REG_CLRFLAG(__r__, __flag__) do { (__r__)->flags &= ~(__flag__); } while (0)
-#define RVM_CPUREG_TSTFLAG(__cpu__, __r__, __flag__) RVM_REG_TSTFLAG(RVM_CPUREG_PTR(__cpu__, __r__), __flag__)
-#define RVM_CPUREG_SETFLAG(__cpu__, __r__, __flag__) RVM_REG_SETFLAG(RVM_CPUREG_PTR(__cpu__, __r__), __flag__)
-#define RVM_CPUREG_CLRFLAG(__cpu__, __r__, __flag__) RVM_REG_CLRFLAG(RVM_CPUREG_PTR(__cpu__, __r__), __flag__)
-
-#define RVM_REG_GETU(__r__) (__r__)->v.w
-#define RVM_REG_SETU(__r__, __val__) do { (__r__)->v.w = (rword)(__val__); } while (0)
-#define RVM_CPUREG_GETU(__cpu__, __r__) RVM_CPUREG_PTR(__cpu__, __r__)->v.w
-#define RVM_CPUREG_SETU(__cpu__, __r__, __val__) RVM_REG_SETU(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
-
-#define RVM_REG_GETL(__r__) (__r__)->v.l
-#define RVM_REG_SETL(__r__, __val__) do { (__r__)->v.l = (rlong)(__val__); } while (0)
-#define RVM_CPUREG_GETL(__cpu__, __r__) RVM_CPUREG_PTR(__cpu__, __r__)->v.l
-#define RVM_CPUREG_SETL(__cpu__, __r__, __val__) RVM_REG_SETL(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
-
-#define RVM_REG_GETP(__r__) (__r__)->v.p
-#define RVM_REG_SETP(__r__, __val__) do { (__r__)->v.p = (rpointer)(__val__); } while (0)
-#define RVM_CPUREG_GETP(__cpu__, __r__) RVM_CPUREG_PTR(__cpu__, __r__)->v.p
-#define RVM_CPUREG_SETP(__cpu__, __r__, __val__) RVM_REG_SETP(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
-
-#define RVM_REG_GETD(__r__) (__r__)->v.d
-#define RVM_REG_SETD(__r__, __val__) do { (__r__)->v.d = (rdouble)(__val__); } while (0)
-#define RVM_CPUREG_GETD(__cpu__, __r__) RVM_CPUREG_PTR(__cpu__, __r__)->v.d
-#define RVM_CPUREG_SETD(__cpu__, __r__, __val__) RVM_REG_SETD(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
-
-#define RVM_REG_GETIP(__r__) (rvm_asmins_t*)((__r__)->v.p)
-#define RVM_REG_SETIP(__r__, __val__) do { (__r__)->v.p = (rpointer)(__val__); } while (0)
-#define RVM_REG_INCIP(__r__, __val__) do {rvm_asmins_t *p = RVM_REG_GETIP(__r__); (__r__)->v.p = (rpointer)(p + (__val__)); } while (0)
-#define RVM_CPUREG_GETIP(__cpu__, __r__) ((rvm_asmins_t*)RVM_CPUREG_PTR(__cpu__, __r__)->v.p)
-#define RVM_CPUREG_SETIP(__cpu__, __r__, __val__) RVM_REG_SETIP(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
-#define RVM_CPUREG_INCIP(__cpu__, __r__, __val__) do {rvm_asmins_t *p = RVM_CPUREG_GETIP(__cpu__, __r__); (__cpu__)->r[(__r__)].v.p = (rpointer)(p + (__val__)); } while (0)
-
-#define RVM_REG_SIZE(__r__) (__r__)->size
-//#define RVM_REG_REF(__r__) do { if (rvm_reg_gettype(__r__) == RVM_DTYPE_REFREG) r_ref_inc((rref_t*)RVM_REG_GETP(__r__));} while (0)
-//#define RVM_REG_UNREF(__r__) do { if (rvm_reg_gettype(__r__) == RVM_DTYPE_REFREG) r_ref_dec((rref_t*)RVM_REG_GETP(__r__));} while (0)
-#define RVM_REG_CLEAR(__r__) do { (__r__)->v.w = 0UL; (__r__)->type = 0; (__r__)->flags = 0;  } while (0)
-#define RVM_CPUREG_CLEAR(__cpu__, __r__) RVM_REG_CLEAR(RVM_CPUREG_PTR(__cpu__, __r__))
 
 
 #define RVM_OPCODE_BITS 8
@@ -284,22 +241,6 @@ typedef struct rvm_switable_s {
 } rvm_switable_t;
 
 
-typedef ruint16 rvmreg_type_t;
-typedef ruint16 rvmreg_flags_t;
-
-typedef struct rvmreg_s {
-       union {
-               rword w;
-               rlong l;
-               rpointer p;
-               rdouble d;
-               ruint8 c[RVM_MIN_REGSIZE];
-       } v;
-       rvmreg_type_t type;
-       rvmreg_flags_t flags;
-       ruint32 size;
-} rvmreg_t;
-
 #define RVM_ASMINS_RELOC (1 << 0)
 #define RVM_ASMINS_RELOCPTR (1 << 1)
 
@@ -308,26 +249,28 @@ struct rvm_asmins_s {
                rword u;
                rdouble d;
        } data;
-       ruint16 op1:5;
-       ruint16 op2:5;
-       ruint16 op3:5;
-       ruint32 opcode:7;
+       ruint16 op1:RVM_OPERAND_BITS;
+       ruint16 op2:RVM_OPERAND_BITS;
+       ruint16 op3:RVM_OPERAND_BITS;
+       ruint16 da:1;
+       ruint32 opcode:8;
        ruint32 swi:18;
        ruint32 type:3;
-       ruint32 flags:4;
+       ruint32 flags:3;
 };
 
 struct rvm_opmap_s;
 
 struct rvmcpu_s {
-       rvmreg_t r[DA + 1];
+       rvmreg_t r[RVM_REGS_NUM];
        rword status;
        rword error;
        rword abort;
        rarray_t *switables;
-       rarray_t *stack;
+       rcarray_t *stack;
        struct rvm_opmap_s *opmap;
        void *userdata;
+       rvm_gc_t *gc;
 };
 
 
@@ -336,10 +279,12 @@ void rvm_cpu_destroy(rvmcpu_t * vm);
 rint rvmcpu_switable_add(rvmcpu_t * cpu, rvm_switable_t *switalbe);
 rint rvm_cpu_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off);
 rint rvm_cpu_exec_debug(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off);
+rint rvm_cpu_dbgarg_exec(rvmcpu_t *cpu, rvm_asmins_t *prog, rword off, rint debug);
 rint rvm_cpu_getswi(rvmcpu_t *cpu, const rchar *swiname);
 void rvm_relocate(rvm_asmins_t *code, rsize_t size);
 rvm_asmins_t rvm_asm(rword opcode, rword op1, rword op2, rword op3, rword data);
 rvm_asmins_t rvm_asml(rword opcode, rword op1, rword op2, rword op3, rlong data);
+rvm_asmins_t rvm_asmb(rword opcode, rword op1, rword op2, rword op3, rword data);
 rvm_asmins_t rvm_asmd(rword opcode, rword op1, rword op2, rword op3, rdouble data);
 rvm_asmins_t rvm_asmp(rword opcode, rword op1, rword op2, rword op3, rpointer data);
 rvm_asmins_t rvm_asmr(rword opcode, rword op1, rword op2, rword op3, rpointer pReloc);
diff --git a/rvm/rvmgc.c b/rvm/rvmgc.c
new file mode 100644 (file)
index 0000000..895ec92
--- /dev/null
@@ -0,0 +1,129 @@
+#include "rmem.h"
+#include "rvmgc.h"
+
+
+rvm_gc_t *rvm_gc_create()
+{
+       rvm_gc_t *gc;
+
+       gc = (rvm_gc_t *)r_zmalloc(sizeof(*gc));
+       rvm_gc_init(gc);
+       return gc;
+}
+
+
+rvm_gc_t *rvm_gc_init(rvm_gc_t *gc)
+{
+       r_list_init(&gc->head[0]);
+       r_list_init(&gc->head[1]);
+       gc->active = 0;
+       return gc;
+}
+
+
+void rvm_gc_cleanup(rvm_gc_t *gc)
+{
+       r_memset(gc, 0, sizeof(gc));
+}
+
+void rvm_gc_destroy(rvm_gc_t *gc)
+{
+       rvm_gc_cleanup(gc);
+       r_free(gc);
+}
+
+rhead_t *rvm_gc_activelist(rvm_gc_t *gc)
+{
+       return &gc->head[gc->active];
+}
+
+
+rhead_t *rvm_gc_inactivelist(rvm_gc_t *gc)
+{
+       return &gc->head[(gc->active + 1) & 1];
+}
+
+
+void rvm_gc_savelifes(rvm_gc_t *gc, rvmreg_t *array, ruint size)
+{
+
+}
+
+
+
+
+void rvm_gc_deallocate(rvm_gc_t *gc)
+{
+       rlink_t *pos;
+       rlist_t *inactiv = rvm_gc_inactivelist(gc);
+       robject_t *obj;
+
+       /*
+        * First pass: remove GC managed data from arrays
+        */
+       r_list_foreach(pos, inactiv) {
+               obj = r_list_entry(pos, robject_t, lnk);
+               rvm_reg_array_unref_gcdata(obj);
+       }
+
+       while ((pos = r_list_first(inactiv)) != NULL) {
+               obj = r_list_entry(pos, robject_t, lnk);
+               r_list_del(pos);
+               r_list_init(pos);
+               r_object_destroy(obj);
+       }
+       gc->active = (gc->active + 1) & 1;
+}
+
+
+void rvm_gc_deallocate_all(rvm_gc_t *gc)
+{
+       gc->active = (gc->active + 1) & 1;
+       rvm_gc_deallocate(gc);
+       gc->active = (gc->active + 1) & 1;
+}
+
+
+int rvm_gc_add(rvm_gc_t *gc, robject_t *obj)
+{
+       rlist_t *activ = rvm_gc_activelist(gc);
+
+       if (!r_list_empty(&obj->lnk))
+               return 0;
+       r_list_addt(activ, &obj->lnk);
+#if 0
+       if (obj->type == R_OBJECT_ARRAY) {
+               /*
+                * Go through the data and add to gc. If the array is gc managed
+                * all the data in the array MUST be gc managed too.
+                */
+               int i;
+               rarray_t *array = (rarray_t*)obj;
+               for (i = 0; i < r_array_length(array); i++) {
+                       rvmreg_t *r = (rvmreg_t *)r_array_slot(array, i);
+                       if (rvm_reg_tstflag(r, RVM_INFOBIT_ROBJECT)) {
+                               rvm_gc_add(gc, RVM_REG_GETP(r));
+                       }
+               }
+       } else if (obj->type == R_OBJECT_HARRAY) {
+               /*
+                * Go through the data and add to gc. If the array is gc managed
+                * all the data in the array MUST be gc managed too.
+                */
+               int i;
+               rarray_t *array = ((rharray_t*)obj)->members;
+               for (i = 0; i < r_array_length(array); i++) {
+                       rvmreg_t *r = (rvmreg_t *)r_array_slot(array, i);
+                       if (rvm_reg_tstflag(r, RVM_INFOBIT_ROBJECT)) {
+                               rvm_gc_add(gc, RVM_REG_GETP(r));
+                       }
+               }
+
+       } else {
+               /*
+                * Nothing to do
+                */
+       }
+#endif
+       return 0;
+}
diff --git a/rvm/rvmgc.h b/rvm/rvmgc.h
new file mode 100644 (file)
index 0000000..2547ba4
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _RVMGC_H_
+#define _RVMGC_H_
+
+#include "rtypes.h"
+#include "rlist.h"
+#include "robject.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct rvm_gc_s {
+       rhead_t head[2];
+       ruint active;
+
+} rvm_gc_t;
+
+void rvm_gc_destroy(rvm_gc_t *gc);
+rvm_gc_t *rvm_gc_create();
+rvm_gc_t *rvm_gc_init(rvm_gc_t *gc);
+void rvm_gc_cleanup(rvm_gc_t *gc);
+
+void rvm_gc_savelifes(rvm_gc_t *gc, rvmreg_t *array, ruint size);
+int rvm_gc_add(rvm_gc_t *gc, robject_t *obj);
+rhead_t *rvm_gc_activelist(rvm_gc_t *gc);
+rhead_t *rvm_gc_inactivelist(rvm_gc_t *gc);
+void rvm_gc_deallocate(rvm_gc_t *gc);
+void rvm_gc_deallocate_all(rvm_gc_t *gc);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 46af6ac..42972ea 100644 (file)
@@ -23,12 +23,12 @@ void rvm_opmap_destroy(rvm_opmap_t *opmap)
 
        if (!opmap)
                return;
-       for (i = 0; i < opmap->operators->len; i++) {
+       for (i = 0; i < r_array_length(opmap->operators); i++) {
                opinfo = ((rvm_opinfo_t*)r_array_slot(opmap->operators, i));
                if (opinfo->opid)
                        r_free(opinfo->handlers);
        }
-       r_array_destroy(opmap->operators);
+       r_object_destroy((robject_t*)opmap->operators);
        r_free(opmap);
 }
 
@@ -39,7 +39,7 @@ void rvm_opmap_add_binary_operator(rvm_opmap_t *opmap, rushort opid)
 
        r_memset(&opinfo, 0, sizeof(opinfo));
        opinfo.opid = opid;
-       opinfo.handlers = r_malloc(RVM_DTYPE_MAX * RVM_DTYPE_MAX * sizeof(rvm_ophandler_t));
+       opinfo.handlers = r_zmalloc(RVM_DTYPE_MAX * RVM_DTYPE_MAX * sizeof(rvm_ophandler_t));
        r_array_replace(opmap->operators, opid, &opinfo);
 }
 
@@ -87,13 +87,13 @@ void rvm_opmap_invoke_binary_handler(rvm_opmap_t *opmap, rushort opid, rvmcpu_t
        rvm_opinfo_t *opinfo;
        ruint index = RVM_OP_HANDLER(RVM_REG_GETTYPE(arg1), RVM_REG_GETTYPE(arg2));
 
-       if (opid >= opmap->operators->len)
+       if (opid >= r_array_length(opmap->operators))
                goto error;
        opinfo = ((rvm_opinfo_t*)r_array_slot(opmap->operators, opid));
        h = &opinfo->handlers[index];
        if (h->op == NULL)
                goto error;
-       h->op(cpu, res, arg1, arg2);
+       h->op(cpu, opid, res, arg1, arg2);
        return;
 
 error:
@@ -107,13 +107,13 @@ void rvm_opmap_invoke_unary_handler(rvm_opmap_t *opmap, rushort opid, rvmcpu_t *
        rvm_opinfo_t *opinfo;
        ruint index = RVM_UNARY_HANDLER(RVM_REG_GETTYPE(arg));
 
-       if (opid >= opmap->operators->len)
+       if (opid >= r_array_length(opmap->operators))
                goto error;
        opinfo = ((rvm_opinfo_t*)r_array_slot(opmap->operators, opid));
        h = &opinfo->handlers[index];
        if (h->unary == NULL)
                goto error;
-       h->unary(cpu, res, arg);
+       h->unary(cpu, opid, res, arg);
        return;
 
 error:
index f0f06a8..33b7396 100644 (file)
@@ -9,6 +9,54 @@
 #define RVM_OP_HANDLER(__ft__, __st__) ((__ft__) * RVM_DTYPE_MAX + (__st__))
 
 
+enum {
+       RVM_OPID_NONE = 0,
+       RVM_OPID_ADD,
+       RVM_OPID_SUB,
+       RVM_OPID_MUL,
+       RVM_OPID_DIV,
+       RVM_OPID_CAT,
+       RVM_OPID_CAST,
+       RVM_OPID_LSL,
+       RVM_OPID_LSR,
+       RVM_OPID_LSRU,
+       RVM_OPID_AND,
+       RVM_OPID_XOR,
+       RVM_OPID_OR,
+       RVM_OPID_NOT,
+       RVM_OPID_CMP,
+       RVM_OPID_CMN,
+       RVM_OPID_MOD,
+       RVM_OPID_LOGICAND,
+       RVM_OPID_LOGICOR,
+       RVM_OPID_LOGICNOT,
+       RVM_OPID_EQ,
+       RVM_OPID_NOTEQ,
+       RVM_OPID_LESS,
+       RVM_OPID_LESSEQ,
+       RVM_OPID_GREATER,
+       RVM_OPID_GREATEREQ,
+
+       RVM_OPID_USER0,
+       RVM_OPID_USER1,
+       RVM_OPID_USER2,
+       RVM_OPID_USER3,
+       RVM_OPID_USER4,
+       RVM_OPID_USER5,
+       RVM_OPID_USER6,
+       RVM_OPID_USER7,
+       RVM_OPID_USER8,
+       RVM_OPID_USER9,
+       RVM_OPID_USER10,
+       RVM_OPID_USER11,
+       RVM_OPID_USER12,
+       RVM_OPID_USER13,
+       RVM_OPID_USER14,
+       RVM_OPID_USER15,
+       RVM_OPID_LAST
+};
+
+/*
 #define RVM_OPID_NONE 0
 #define RVM_OPID_ADD 1
 #define RVM_OPID_SUB 2
 #define RVM_OPID_CAST 6
 #define RVM_OPID_LSL 7
 #define RVM_OPID_LSR 8
+#define RVM_OPID_LSRU 8
+
 #define RVM_OPID_AND 9
 #define RVM_OPID_XOR 10
 #define RVM_OPID_OR 11
 #define RVM_OPID_NOT 12
 #define RVM_OPID_CMP 13
 #define RVM_OPID_CMN 14
+#define RVM_OPID_MOD 15
+#define RVM_OPID_LESS 16
 
-
+#define RVM_OPID_LAST 32
+*/
 /*
  * Important: the res pointer might be the same as one of the arguments, the operator must
  * be implemented to take care of such cases.
  */
-typedef void (*rvm_unaryop_handler)(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg);
-typedef void (*rvm_binaryop_handler)(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2);
+typedef void (*rvm_unaryop_handler)(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg);
+typedef void (*rvm_binaryop_handler)(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2);
 
 typedef union rvm_ophandler_s {
        rvm_unaryop_handler unary;
@@ -58,14 +111,4 @@ rint rvm_opmap_set_unary_handler(rvm_opmap_t *opmap, rushort opid, rvm_unaryop_h
 void rvm_opmap_invoke_binary_handler(rvm_opmap_t *opmap, rushort opid, rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2);
 void rvm_opmap_invoke_unary_handler(rvm_opmap_t *opmap, rushort opid, rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg);
 
-
-void rvm_op_lsl_init(rvm_opmap_t *opmap);
-void rvm_op_lsr_init(rvm_opmap_t *opmap);
-void rvm_op_and_init(rvm_opmap_t *opmap);
-void rvm_op_xor_init(rvm_opmap_t *opmap);
-void rvm_op_or_init(rvm_opmap_t *opmap);
-void rvm_op_cmp_init(rvm_opmap_t *opmap);
-void rvm_op_cmn_init(rvm_opmap_t *opmap);
-void rvm_op_not_init(rvm_opmap_t *opmap);
-
 #endif
index 87d25e5..f469395 100644 (file)
@@ -1,11 +1,10 @@
-#include "rvmoperatoradd.h"
+#include "rvmoperator.h"
 #include "rvmreg.h"
 
 
-static void rvm_op_add_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword op2)
+void rvm_op_add_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
 {
        rword r;
-
        r = op1 + op2;
        RVM_REG_SETU(res, r);
        RVM_REG_SETTYPE(res, RVM_DTYPE_UNSIGNED);
@@ -16,10 +15,9 @@ static void rvm_op_add_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword o
 }
 
 
-static void rvm_op_add_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
+void rvm_op_add_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
 {
        rlong r;
-
        r = op1 + op2;
        RVM_REG_SETL(res, r);
        RVM_REG_SETTYPE(res, RVM_DTYPE_LONG);
@@ -27,114 +25,12 @@ static void rvm_op_add_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
        RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, r & RVM_SIGN_BIT);
 }
 
-
-static void rvm_op_add_double(rvmcpu_t *cpu, rvmreg_t *res, rdouble op1, rdouble op2)
+void rvm_op_add_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
 {
        rdouble r;
-
        r = op1 + op2;
        RVM_REG_SETD(res, r);
        RVM_REG_SETTYPE(res, RVM_DTYPE_DOUBLE);
        RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
        RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, r < 0.0);
 }
-
-
-static void rvm_op_add_unsigned_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_add_unsigned(cpu, res, RVM_REG_GETU(arg1), RVM_REG_GETU(arg2));
-}
-
-
-static void rvm_op_add_long_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_add_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(arg2));
-}
-
-
-static void rvm_op_add_double_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_add_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(arg2));
-}
-
-
-void rvm_op_add_long_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_add_double(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_add_double_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_add_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_add_string_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2double(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_add_double(cpu, res, RVM_REG_GETD(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_add_string_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2num(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-
-       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
-               rvm_op_add_double(cpu, res, RVM_REG_GETD(&s), RVM_REG_GETL(arg2));
-       } else {
-               rvm_op_add_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETL(arg2));
-       }
-}
-
-
-static void rvm_op_add_double_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2double(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_add_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(&s));
-}
-
-
-static void rvm_op_add_long_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2num(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
-               rvm_op_add_double(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(&s));
-       } else {
-               rvm_op_add_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(&s));
-       }
-}
-
-
-void rvm_op_add_init(rvm_opmap_t *opmap)
-{
-       rvm_opmap_add_binary_operator(opmap, RVM_OPID_ADD);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_unsigned_unsigned, RVM_DTYPE_UNSIGNED, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_double_double, RVM_DTYPE_DOUBLE, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_long_long, RVM_DTYPE_LONG, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_long_long, RVM_DTYPE_UNSIGNED, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_long_long, RVM_DTYPE_LONG, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_long_double, RVM_DTYPE_LONG, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_long_double, RVM_DTYPE_UNSIGNED, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_string_long, RVM_DTYPE_STRING, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_string_long, RVM_DTYPE_STRING, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_string_double, RVM_DTYPE_STRING, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_long_string, RVM_DTYPE_UNSIGNED, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_long_string, RVM_DTYPE_LONG, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_ADD, rvm_op_add_double_string, RVM_DTYPE_DOUBLE, RVM_DTYPE_STRING);
-}
index ba586fd..96f05a9 100644 (file)
@@ -1,9 +1,20 @@
-#ifndef _RVMOPERATORADD_H_
-#define _RVMOPERATORADD_H_
+#ifndef __RVMOPERATORADD_H_
+#define __RVMOPERATORADD_H_
 
 #include "rvmoperator.h"
+#include "rvmreg.h"
 
-void rvm_op_add_init(rvm_opmap_t *opmap);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_add_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_add_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_add_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
 
 
 #endif
index 0ca8391..396a53c 100644 (file)
@@ -2,7 +2,7 @@
 #include "rvmreg.h"
 
 
-static void rvm_op_and_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword op2)
+void rvm_op_and_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
 {
        rword r;
 
@@ -14,7 +14,7 @@ static void rvm_op_and_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword o
 }
 
 
-static void rvm_op_and_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
+void rvm_op_and_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
 {
        rlong r;
 
@@ -26,92 +26,7 @@ static void rvm_op_and_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
 }
 
 
-static void rvm_op_and_unsigned_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_and_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
 {
-       rvm_op_and_unsigned(cpu, res, RVM_REG_GETU(arg1), RVM_REG_GETU(arg2));
-}
-
-
-static void rvm_op_and_long_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_and_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(arg2));
-}
-
-
-static void rvm_op_and_double_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_and_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(arg2));
-}
-
-
-void rvm_op_and_long_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_and_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_and_double_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_and_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_and_string_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_and_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_and_string_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_and_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_and_double_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_and_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(&s));
-}
-
-
-static void rvm_op_and_long_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_and_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(&s));
-}
-
-
-void rvm_op_and_init(rvm_opmap_t *opmap)
-{
-       rvm_opmap_add_binary_operator(opmap, RVM_OPID_AND);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_unsigned_unsigned, RVM_DTYPE_UNSIGNED, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_double_double, RVM_DTYPE_DOUBLE, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_long_long, RVM_DTYPE_LONG, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_long_long, RVM_DTYPE_UNSIGNED, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_long_long, RVM_DTYPE_LONG, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_long_double, RVM_DTYPE_LONG, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_long_double, RVM_DTYPE_UNSIGNED, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_string_long, RVM_DTYPE_STRING, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_string_long, RVM_DTYPE_STRING, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_string_double, RVM_DTYPE_STRING, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_long_string, RVM_DTYPE_UNSIGNED, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_long_string, RVM_DTYPE_LONG, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_AND, rvm_op_and_double_string, RVM_DTYPE_DOUBLE, RVM_DTYPE_STRING);
+       rvm_op_and_long(cpu, opid, res, op1, op2);
 }
diff --git a/rvm/rvmoperatorand.h b/rvm/rvmoperatorand.h
new file mode 100644 (file)
index 0000000..9743fa7
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef __RVMOPERATORAND_H_
+#define __RVMOPERATORAND_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_and_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_and_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_and_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/rvm/rvmoperatorbin.c b/rvm/rvmoperatorbin.c
new file mode 100644 (file)
index 0000000..f198758
--- /dev/null
@@ -0,0 +1,213 @@
+#include "rvmoperator.h"
+#include "rvmreg.h"
+#include "rvmoperatornot.h"
+#include "rvmoperatorbin.h"
+#include "rvmoperatorlsr.h"
+#include "rvmoperatorlsru.h"
+#include "rvmoperatoreq.h"
+#include "rvmoperatornoteq.h"
+#include "rvmoperatorlogicor.h"
+#include "rvmoperatorlogicand.h"
+#include "rvmoperatorless.h"
+#include "rvmoperatorlesseq.h"
+#include "rvmoperatorgreater.h"
+#include "rvmoperatorgreatereq.h"
+#include "rvmoperatoror.h"
+#include "rvmoperatorxor.h"
+#include "rvmoperatorcast.h"
+#include "rvmoperatorsub.h"
+#include "rvmoperatoradd.h"
+#include "rvmoperatormod.h"
+#include "rvmoperatormul.h"
+#include "rvmoperatorlsl.h"
+#include "rvmoperatorcmn.h"
+#include "rvmoperatorcmp.h"
+#include "rvmoperatorand.h"
+#include "rvmoperatorcat.h"
+#include "rvmoperatordiv.h"
+
+static rvm_binopmap_t binary_operations[RVM_OPID_LAST+1];
+
+static void rvm_op_abort_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
+{
+       RVM_ABORT(cpu, RVM_E_ILLEGAL);
+}
+
+
+static void rvm_op_abort_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
+{
+       RVM_ABORT(cpu, RVM_E_ILLEGAL);
+}
+
+
+static void rvm_op_abort_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
+{
+       RVM_ABORT(cpu, RVM_E_ILLEGAL);
+}
+
+
+inline void rvm_op_binary_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
+{
+       binary_operations[opid].unsigned_binop_fun(cpu, opid, res, op1, op2);
+}
+
+
+inline void rvm_op_binary_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
+{
+       binary_operations[opid].long_binop_fun(cpu, opid, res, op1, op2);
+}
+
+
+inline void rvm_op_binary_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
+{
+       binary_operations[opid].double_binop_fun(cpu, opid, res, op1, op2);
+}
+
+
+static void rvm_op_binary_unsigned_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+{
+       rvm_op_binary_unsigned(cpu, opid, res, RVM_REG_GETU(arg1), RVM_REG_GETU(arg2));
+}
+
+
+static void rvm_op_binary_long_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+{
+       rvm_op_binary_long(cpu, opid, res, RVM_REG_GETL(arg1), RVM_REG_GETL(arg2));
+}
+
+
+static void rvm_op_binary_double_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+{
+       rvm_op_binary_double(cpu, opid, res, RVM_REG_GETD(arg1), RVM_REG_GETL(arg2));
+}
+
+
+void rvm_op_binary_long_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+{
+       rvm_op_binary_double(cpu, opid, res, RVM_REG_GETL(arg1), RVM_REG_GETD(arg2));
+}
+
+
+static void rvm_op_binary_double_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+{
+       rvm_op_binary_double(cpu, opid, res, RVM_REG_GETD(arg1), RVM_REG_GETD(arg2));
+}
+
+
+static void rvm_op_binary_string_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+{
+       rvmreg_t s;
+
+       if (rvm_reg_str2double(&s, arg1) < 0)
+               RVM_ABORT(cpu, RVM_E_ILLEGAL);
+       rvm_op_binary_double(cpu, opid, res, RVM_REG_GETD(&s), RVM_REG_GETD(arg2));
+}
+
+
+static void rvm_op_binary_string_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+{
+       rvmreg_t s;
+
+       if (rvm_reg_str2num(&s, arg1) < 0)
+               RVM_ABORT(cpu, RVM_E_ILLEGAL);
+
+       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
+               rvm_op_binary_double(cpu, opid, res, RVM_REG_GETD(&s), RVM_REG_GETL(arg2));
+       } else {
+               rvm_op_binary_long(cpu, opid, res, RVM_REG_GETL(&s), RVM_REG_GETL(arg2));
+       }
+}
+
+
+static void rvm_op_binary_double_string(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+{
+       rvmreg_t s;
+
+       if (rvm_reg_str2double(&s, arg2) < 0)
+               RVM_ABORT(cpu, RVM_E_ILLEGAL);
+       rvm_op_binary_double(cpu, opid, res, RVM_REG_GETD(arg1), RVM_REG_GETD(&s));
+}
+
+
+static void rvm_op_binary_long_string(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+{
+       rvmreg_t s;
+
+       if (rvm_reg_str2num(&s, arg2) < 0)
+               RVM_ABORT(cpu, RVM_E_ILLEGAL);
+       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
+               rvm_op_binary_double(cpu, opid, res, RVM_REG_GETL(arg1), RVM_REG_GETD(&s));
+       } else {
+               rvm_op_binary_long(cpu, opid, res, RVM_REG_GETL(arg1), RVM_REG_GETL(&s));
+       }
+}
+
+
+void rvm_op_binary_insert(rvm_opmap_t *opmap, rushort opid, rvm_binop_unsigned u, rvm_binop_long l, rvm_binop_double d)
+{
+       binary_operations[opid].opid = opid;
+       binary_operations[opid].unsigned_binop_fun = u;
+       binary_operations[opid].long_binop_fun = l;
+       binary_operations[opid].double_binop_fun = d;
+       rvm_opmap_add_binary_operator(opmap, opid);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_unsigned_unsigned, RVM_DTYPE_BOOLEAN, RVM_DTYPE_BOOLEAN);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_unsigned_unsigned, RVM_DTYPE_BOOLEAN, RVM_DTYPE_UNSIGNED);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_long_long, RVM_DTYPE_BOOLEAN, RVM_DTYPE_LONG);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_long_double, RVM_DTYPE_BOOLEAN, RVM_DTYPE_DOUBLE);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_long_string, RVM_DTYPE_BOOLEAN, RVM_DTYPE_STRING);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_unsigned_unsigned, RVM_DTYPE_UNSIGNED, RVM_DTYPE_BOOLEAN);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_unsigned_unsigned, RVM_DTYPE_LONG, RVM_DTYPE_BOOLEAN);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_BOOLEAN);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_string_long, RVM_DTYPE_STRING, RVM_DTYPE_BOOLEAN);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_unsigned_unsigned, RVM_DTYPE_UNSIGNED, RVM_DTYPE_UNSIGNED);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_double_double, RVM_DTYPE_DOUBLE, RVM_DTYPE_DOUBLE);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_long_long, RVM_DTYPE_LONG, RVM_DTYPE_LONG);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_long_long, RVM_DTYPE_UNSIGNED, RVM_DTYPE_LONG);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_long_long, RVM_DTYPE_LONG, RVM_DTYPE_UNSIGNED);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_long_double, RVM_DTYPE_LONG, RVM_DTYPE_DOUBLE);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_long_double, RVM_DTYPE_UNSIGNED, RVM_DTYPE_DOUBLE);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_LONG);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_UNSIGNED);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_string_long, RVM_DTYPE_STRING, RVM_DTYPE_UNSIGNED);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_string_long, RVM_DTYPE_STRING, RVM_DTYPE_LONG);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_string_double, RVM_DTYPE_STRING, RVM_DTYPE_DOUBLE);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_long_string, RVM_DTYPE_UNSIGNED, RVM_DTYPE_STRING);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_long_string, RVM_DTYPE_LONG, RVM_DTYPE_STRING);
+       rvm_opmap_set_binary_handler(opmap, opid, rvm_op_binary_double_string, RVM_DTYPE_DOUBLE, RVM_DTYPE_STRING);
+}
+
+
+void rvm_op_binary_init(rvm_opmap_t *opmap)
+{
+       int i;
+
+       for (i = 0; i < sizeof(binary_operations)/sizeof(binary_operations[0]); i++) {
+               binary_operations[i].opid = RVM_OPID_NONE;
+               binary_operations[i].unsigned_binop_fun = rvm_op_abort_unsigned;
+               binary_operations[i].long_binop_fun = rvm_op_abort_long;
+               binary_operations[i].double_binop_fun = rvm_op_abort_double;
+       }
+
+       rvm_op_binary_insert(opmap, RVM_OPID_ADD, rvm_op_add_unsigned, rvm_op_add_long, rvm_op_add_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_SUB, rvm_op_sub_unsigned, rvm_op_sub_long, rvm_op_sub_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_MUL, rvm_op_mul_unsigned, rvm_op_mul_long, rvm_op_mul_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_DIV, rvm_op_div_unsigned, rvm_op_div_long, rvm_op_div_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_LSL, rvm_op_lsl_unsigned, rvm_op_lsl_long, rvm_op_lsl_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_LSR, rvm_op_lsr_unsigned, rvm_op_lsr_long, rvm_op_lsr_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_LSRU, rvm_op_lsru_unsigned, rvm_op_lsru_long, rvm_op_lsru_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_AND, rvm_op_and_unsigned, rvm_op_and_long, rvm_op_and_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_XOR, rvm_op_xor_unsigned, rvm_op_xor_long, rvm_op_xor_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_OR, rvm_op_or_unsigned, rvm_op_or_long, rvm_op_or_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_CMP, rvm_op_cmp_unsigned, rvm_op_cmp_long, rvm_op_cmp_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_CMN, rvm_op_cmn_unsigned, rvm_op_cmn_long, rvm_op_cmn_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_MOD, rvm_op_mod_unsigned, rvm_op_mod_long, rvm_op_mod_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_LOGICOR, rvm_op_logicor_unsigned, rvm_op_logicor_long, rvm_op_logicor_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_LOGICAND, rvm_op_logicand_unsigned, rvm_op_logicand_long, rvm_op_logicand_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_EQ, rvm_op_eq_unsigned, rvm_op_eq_long, rvm_op_eq_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_NOTEQ, rvm_op_noteq_unsigned, rvm_op_noteq_long, rvm_op_noteq_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_LESS, rvm_op_less_unsigned, rvm_op_less_long, rvm_op_less_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_LESSEQ, rvm_op_lesseq_unsigned, rvm_op_lesseq_long, rvm_op_lesseq_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_GREATER, rvm_op_greater_unsigned, rvm_op_greater_long, rvm_op_greater_double);
+       rvm_op_binary_insert(opmap, RVM_OPID_GREATEREQ, rvm_op_greatereq_unsigned, rvm_op_greatereq_long, rvm_op_greatereq_double);
+
+}
diff --git a/rvm/rvmoperatorbin.h b/rvm/rvmoperatorbin.h
new file mode 100644 (file)
index 0000000..f115845
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef __RVMOPERATORBIN_H_
+#define __RVMOPERATORBIN_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*rvm_binop_unsigned)(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+typedef void (*rvm_binop_long)(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+typedef void (*rvm_binop_double)(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+
+typedef struct rvm_binopmap_s {
+       rushort opid;
+       rvm_binop_unsigned unsigned_binop_fun;
+       rvm_binop_long long_binop_fun;
+       rvm_binop_double double_binop_fun;
+} rvm_binopmap_t;
+
+void rvm_op_binary_insert(rvm_opmap_t *opmap, rushort opid, rvm_binop_unsigned u, rvm_binop_long l, rvm_binop_double d);
+void rvm_op_binary_init(rvm_opmap_t *opmap);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 8298563..42562e6 100644 (file)
@@ -1,14 +1,14 @@
-#include "rvmoperatorcast.h"
+#include "rvmoperator.h"
 #include "rvmreg.h"
 
 
-void rvm_op_cast_static_static(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_cast_static_static(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
 {
        *res = *arg1;
 }
 
 
-void rvm_op_cast_double_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_cast_double_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
 {
        rword r = (rword)RVM_REG_GETD(arg1);
 
@@ -17,7 +17,7 @@ void rvm_op_cast_double_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *a
        RVM_REG_SETL(res, r);
 }
 
-void rvm_op_cast_double_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_cast_double_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
 {
        rlong r = (rlong)RVM_REG_GETD(arg1);
 
@@ -27,7 +27,7 @@ void rvm_op_cast_double_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1,
 }
 
 
-void rvm_op_cast_long_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_cast_long_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
 {
        rword r = (rword)RVM_REG_GETL(arg1);
 
@@ -37,7 +37,7 @@ void rvm_op_cast_long_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg
 }
 
 
-void rvm_op_cast_long_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_cast_long_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
 {
        rdouble r = (rdouble)RVM_REG_GETL(arg1);
 
@@ -47,72 +47,80 @@ void rvm_op_cast_long_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1,
 }
 
 
-void rvm_op_cast_unsigned_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_cast_long_boolean(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
 {
-       rlong r = (rlong)RVM_REG_GETU(arg1);
+       rword r = (rword)RVM_REG_GETL(arg1);
 
        RVM_REG_CLEAR(res);
-       RVM_REG_SETTYPE(res, RVM_DTYPE_LONG);
-       RVM_REG_SETL(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_REG_SETL(res, r ? 1 : 0);
 }
 
 
-void rvm_op_cast_unsigned_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_cast_double_boolean(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
 {
-       rdouble r = (rdouble)RVM_REG_GETU(arg1);
+       rword r = (rword)RVM_REG_GETD(arg1);
 
        RVM_REG_CLEAR(res);
-       RVM_REG_SETTYPE(res, RVM_DTYPE_DOUBLE);
-       RVM_REG_SETD(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_REG_SETL(res, r ? 1 : 0);
 }
 
 
-void rvm_op_cast_string_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_cast_pointer_boolean(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
 {
-       if (res == arg1)
-               RVM_ABORT(cpu, RVM_E_ILLEGALDST);
-       rvm_reg_setstring(res, r_string_copy(RVM_REG_GETP(arg1)));
+       rpointer r = (rpointer)RVM_REG_GETP(arg1);
+
+       RVM_REG_CLEAR(res);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_REG_SETL(res, r ? 1 : 0);
 }
 
 
-void rvm_op_cast_refreg_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_cast_unsigned_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
 {
-       if (res == arg1)
-               RVM_ABORT(cpu, RVM_E_ILLEGALDST);
-       rvm_reg_refer(res, arg1);
+       rlong r = (rlong)RVM_REG_GETU(arg1);
+
+       RVM_REG_CLEAR(res);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_LONG);
+       RVM_REG_SETL(res, r);
+}
+
+
+void rvm_op_cast_unsigned_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+{
+       rdouble r = (rdouble)RVM_REG_GETU(arg1);
+
+       RVM_REG_CLEAR(res);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_DOUBLE);
+       RVM_REG_SETD(res, r);
 }
 
 
-void rvm_op_cast_string_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_cast_string_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
 {
        rvmreg_t s;
 
-       if (res == arg1)
-               RVM_ABORT(cpu, RVM_E_ILLEGALDST);
        if (rvm_reg_str2long(&s, arg1) < 0)
                RVM_ABORT(cpu, RVM_E_ILLEGAL);
        rvm_reg_setunsigned(res, RVM_REG_GETL(&s));
 }
 
 
-void rvm_op_cast_string_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_cast_string_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
 {
        rvmreg_t s;
 
-       if (res == arg1)
-               RVM_ABORT(cpu, RVM_E_ILLEGALDST);
        if (rvm_reg_str2long(&s, arg1) < 0)
                RVM_ABORT(cpu, RVM_E_ILLEGAL);
        rvm_reg_setlong(res, RVM_REG_GETL(&s));
 }
 
 
-void rvm_op_cast_string_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_cast_string_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
 {
        rvmreg_t s;
 
-       if (res == arg1)
-               RVM_ABORT(cpu, RVM_E_ILLEGALDST);
        if (rvm_reg_str2double(&s, arg1) < 0)
                RVM_ABORT(cpu, RVM_E_ILLEGAL);
        rvm_reg_setdouble(res, RVM_REG_GETD(&s));
@@ -125,14 +133,23 @@ void rvm_op_cast_init(rvm_opmap_t *opmap)
        rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_static_static, RVM_DTYPE_UNSIGNED, RVM_DTYPE_UNSIGNED);
        rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_static_static, RVM_DTYPE_DOUBLE, RVM_DTYPE_DOUBLE);
        rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_static_static, RVM_DTYPE_LONG, RVM_DTYPE_LONG);
+       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_static_static, RVM_DTYPE_STRING, RVM_DTYPE_STRING);
+       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_static_static, RVM_DTYPE_BOOLEAN, RVM_DTYPE_BOOLEAN);
+       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_long_boolean, RVM_DTYPE_LONG, RVM_DTYPE_BOOLEAN);
+       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_long_boolean, RVM_DTYPE_UNSIGNED, RVM_DTYPE_BOOLEAN);
+       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_double_boolean, RVM_DTYPE_DOUBLE, RVM_DTYPE_BOOLEAN);
+       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_pointer_boolean, RVM_DTYPE_STRING, RVM_DTYPE_BOOLEAN);
+       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_pointer_boolean, RVM_DTYPE_ARRAY, RVM_DTYPE_BOOLEAN);
+       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_pointer_boolean, RVM_DTYPE_HARRAY, RVM_DTYPE_BOOLEAN);
+       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_unsigned_long, RVM_DTYPE_BOOLEAN, RVM_DTYPE_LONG);
+       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_unsigned_double, RVM_DTYPE_BOOLEAN, RVM_DTYPE_DOUBLE);
+
        rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_long_double, RVM_DTYPE_LONG, RVM_DTYPE_DOUBLE);
        rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_long_unsigned, RVM_DTYPE_LONG, RVM_DTYPE_UNSIGNED);
        rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_LONG);
        rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_double_unsigned, RVM_DTYPE_DOUBLE, RVM_DTYPE_UNSIGNED);
        rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_unsigned_long, RVM_DTYPE_UNSIGNED, RVM_DTYPE_LONG);
        rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_unsigned_double, RVM_DTYPE_UNSIGNED, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_refreg_string, RVM_DTYPE_REFREG, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_string_string, RVM_DTYPE_STRING, RVM_DTYPE_STRING);
        rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_string_unsigned, RVM_DTYPE_STRING, RVM_DTYPE_UNSIGNED);
        rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_string_long, RVM_DTYPE_STRING, RVM_DTYPE_LONG);
        rvm_opmap_set_binary_handler(opmap, RVM_OPID_CAST, rvm_op_cast_string_double, RVM_DTYPE_STRING, RVM_DTYPE_DOUBLE);
index cfe2ab8..f4ec406 100644 (file)
@@ -1,8 +1,21 @@
-#ifndef _RVMOPERATORCAST_H_
-#define _RVMOPERATORCAST_H_
+#ifndef __RVMOPERATORCAST_H_
+#define __RVMOPERATORCAST_H_
 
 #include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_cast_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_cast_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_cast_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
 
 void rvm_op_cast_init(rvm_opmap_t *opmap);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
index e279a72..82da162 100644 (file)
@@ -1,4 +1,4 @@
-#include "rvmoperatorcat.h"
+#include "rvmoperator.h"
 #include "rstring.h"
 #include "rvmreg.h"
 
index d1b6314..0f5196b 100644 (file)
@@ -1,8 +1,19 @@
-#ifndef _RVMOPERATORCAT_H_
-#define _RVMOPERATORCAT_H_
+#ifndef __RVMOPERATORCAT_H_
+#define __RVMOPERATORCAT_H_
 
 #include "rvmoperator.h"
+#include "rvmreg.h"
 
-void rvm_op_cat_string_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_cat_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_cat_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_cat_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
index ad8cc0a..8e4f095 100644 (file)
@@ -1,8 +1,8 @@
-#include "rvmoperatormul.h"
+#include "rvmoperator.h"
 #include "rvmreg.h"
 
 
-static void rvm_op_cmn_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword op2)
+void rvm_op_cmn_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
 {
        rword r;
 
@@ -15,111 +15,17 @@ static void rvm_op_cmn_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword o
 }
 
 
-static void rvm_op_cmn_double(rvmcpu_t *cpu, rvmreg_t *res, rdouble op1, rdouble op2)
+void rvm_op_cmn_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
 {
-       rdouble r;
-
-       r = op1 + op2;
-       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
-       RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, r < 0.0);
-}
-
-
-static void rvm_op_cmn_unsigned_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_cmn_unsigned(cpu, res, RVM_REG_GETU(arg1), RVM_REG_GETU(arg2));
-}
-
-
-static void rvm_op_cmn_long_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_cmn_unsigned(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(arg2));
-}
-
-
-static void rvm_op_cmn_double_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_cmn_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(arg2));
-}
-
-
-void rvm_op_cmn_long_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_cmn_double(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_cmn_double_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_cmn_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(arg2));
+       rvm_op_cmn_unsigned(cpu, opid, res, op1, op2);
 }
 
 
-static void rvm_op_cmn_string_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_cmn_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
 {
-       rvmreg_t s;
-
-       if (rvm_reg_str2double(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_cmn_double(cpu, res, RVM_REG_GETD(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_cmn_string_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2num(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-
-       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
-               rvm_op_cmn_double(cpu, res, RVM_REG_GETD(&s), RVM_REG_GETL(arg2));
-       } else {
-               rvm_op_cmn_unsigned(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETL(arg2));
-       }
-}
-
-
-static void rvm_op_cmn_double_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2double(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_cmn_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(&s));
-}
-
-
-static void rvm_op_cmn_long_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2num(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
-               rvm_op_cmn_double(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(&s));
-       } else {
-               rvm_op_cmn_unsigned(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(&s));
-       }
-}
-
+       rdouble r;
 
-void rvm_op_cmn_init(rvm_opmap_t *opmap)
-{
-       rvm_opmap_add_binary_operator(opmap, RVM_OPID_CMN);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_unsigned_unsigned, RVM_DTYPE_UNSIGNED, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_double_double, RVM_DTYPE_DOUBLE, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_long_long, RVM_DTYPE_LONG, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_long_long, RVM_DTYPE_UNSIGNED, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_long_long, RVM_DTYPE_LONG, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_long_double, RVM_DTYPE_LONG, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_long_double, RVM_DTYPE_UNSIGNED, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_string_long, RVM_DTYPE_STRING, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_string_long, RVM_DTYPE_STRING, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_string_double, RVM_DTYPE_STRING, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_long_string, RVM_DTYPE_UNSIGNED, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_long_string, RVM_DTYPE_LONG, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMN, rvm_op_cmn_double_string, RVM_DTYPE_DOUBLE, RVM_DTYPE_STRING);
+       r = op1 + op2;
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, r < 0.0);
 }
diff --git a/rvm/rvmoperatorcmn.h b/rvm/rvmoperatorcmn.h
new file mode 100644 (file)
index 0000000..d782175
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORCMN_H_
+#define __RVMOPERATORCMN_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_cmn_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_cmn_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_cmn_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index da50870..622df2e 100644 (file)
@@ -1,8 +1,8 @@
-#include "rvmoperatormul.h"
+#include "rvmoperator.h"
 #include "rvmreg.h"
 
 
-static void rvm_op_cmp_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword op2)
+void rvm_op_cmp_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
 {
        rword r;
 
@@ -16,7 +16,13 @@ static void rvm_op_cmp_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword o
 }
 
 
-static void rvm_op_cmp_double(rvmcpu_t *cpu, rvmreg_t *res, rdouble op1, rdouble op2)
+void rvm_op_cmp_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
+{
+       rvm_op_cmp_unsigned(cpu, opid, res, op1, op2);
+}
+
+
+void rvm_op_cmp_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
 {
        rdouble r;
 
@@ -25,103 +31,3 @@ static void rvm_op_cmp_double(rvmcpu_t *cpu, rvmreg_t *res, rdouble op1, rdouble
        RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
        RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, r < 0.0);
 }
-
-
-static void rvm_op_cmp_unsigned_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_cmp_unsigned(cpu, res, RVM_REG_GETU(arg1), RVM_REG_GETU(arg2));
-}
-
-
-static void rvm_op_cmp_long_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_cmp_unsigned(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(arg2));
-}
-
-
-static void rvm_op_cmp_double_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_cmp_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(arg2));
-}
-
-
-void rvm_op_cmp_long_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_cmp_double(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_cmp_double_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_cmp_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_cmp_string_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2double(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_cmp_double(cpu, res, RVM_REG_GETD(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_cmp_string_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2num(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-
-       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
-               rvm_op_cmp_double(cpu, res, RVM_REG_GETD(&s), RVM_REG_GETL(arg2));
-       } else {
-               rvm_op_cmp_unsigned(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETL(arg2));
-       }
-}
-
-
-static void rvm_op_cmp_double_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2double(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_cmp_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(&s));
-}
-
-
-static void rvm_op_cmp_long_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2num(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
-               rvm_op_cmp_double(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(&s));
-       } else {
-               rvm_op_cmp_unsigned(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(&s));
-       }
-}
-
-
-void rvm_op_cmp_init(rvm_opmap_t *opmap)
-{
-       rvm_opmap_add_binary_operator(opmap, RVM_OPID_CMP);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_unsigned_unsigned, RVM_DTYPE_UNSIGNED, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_double_double, RVM_DTYPE_DOUBLE, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_long_long, RVM_DTYPE_LONG, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_long_long, RVM_DTYPE_UNSIGNED, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_long_long, RVM_DTYPE_LONG, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_long_double, RVM_DTYPE_LONG, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_long_double, RVM_DTYPE_UNSIGNED, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_string_long, RVM_DTYPE_STRING, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_string_long, RVM_DTYPE_STRING, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_string_double, RVM_DTYPE_STRING, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_long_string, RVM_DTYPE_UNSIGNED, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_long_string, RVM_DTYPE_LONG, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_CMP, rvm_op_cmp_double_string, RVM_DTYPE_DOUBLE, RVM_DTYPE_STRING);
-}
diff --git a/rvm/rvmoperatorcmp.h b/rvm/rvmoperatorcmp.h
new file mode 100644 (file)
index 0000000..b557565
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORCMP_H_
+#define __RVMOPERATORCMP_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_cmp_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_cmp_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_cmp_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 407fbcd..828469f 100644 (file)
@@ -1,8 +1,8 @@
-#include "rvmoperatordiv.h"
+#include "rvmoperator.h"
 #include "rvmreg.h"
 
 
-static void rvm_op_div_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword op2)
+void rvm_op_div_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
 {
        rword r;
 
@@ -16,7 +16,7 @@ static void rvm_op_div_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword o
 }
 
 
-static void rvm_op_div_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
+void rvm_op_div_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
 {
        rlong r;
 
@@ -30,7 +30,7 @@ static void rvm_op_div_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
 }
 
 
-static void rvm_op_div_double(rvmcpu_t *cpu, rvmreg_t *res, rdouble op1, rdouble op2)
+void rvm_op_div_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
 {
        rdouble r;
 
@@ -42,103 +42,3 @@ static void rvm_op_div_double(rvmcpu_t *cpu, rvmreg_t *res, rdouble op1, rdouble
        RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
        RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, r < 0.0);
 }
-
-
-static void rvm_op_div_unsigned_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_div_unsigned(cpu, res, RVM_REG_GETU(arg1), RVM_REG_GETU(arg2));
-}
-
-
-static void rvm_op_div_long_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_div_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(arg2));
-}
-
-
-static void rvm_op_div_double_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_div_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(arg2));
-}
-
-
-void rvm_op_div_long_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_div_double(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_div_double_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_div_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_div_string_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2double(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_div_double(cpu, res, RVM_REG_GETD(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_div_string_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2num(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-
-       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
-               rvm_op_div_double(cpu, res, RVM_REG_GETD(&s), RVM_REG_GETL(arg2));
-       } else {
-               rvm_op_div_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETL(arg2));
-       }
-}
-
-
-static void rvm_op_div_double_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2double(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_div_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(&s));
-}
-
-
-static void rvm_op_div_long_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2num(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
-               rvm_op_div_double(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(&s));
-       } else {
-               rvm_op_div_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(&s));
-       }
-}
-
-
-void rvm_op_div_init(rvm_opmap_t *opmap)
-{
-       rvm_opmap_add_binary_operator(opmap, RVM_OPID_DIV);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_unsigned_unsigned, RVM_DTYPE_UNSIGNED, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_double_double, RVM_DTYPE_DOUBLE, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_long_long, RVM_DTYPE_LONG, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_long_long, RVM_DTYPE_UNSIGNED, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_long_long, RVM_DTYPE_LONG, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_long_double, RVM_DTYPE_LONG, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_long_double, RVM_DTYPE_UNSIGNED, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_string_long, RVM_DTYPE_STRING, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_string_long, RVM_DTYPE_STRING, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_string_double, RVM_DTYPE_STRING, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_long_string, RVM_DTYPE_UNSIGNED, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_long_string, RVM_DTYPE_LONG, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_DIV, rvm_op_div_double_string, RVM_DTYPE_DOUBLE, RVM_DTYPE_STRING);
-}
index 4e5a969..f3c3d54 100644 (file)
@@ -1,8 +1,19 @@
-#ifndef _RVMOPERATORDIV_H_
-#define _RVMOPERATORDIV_H_
+#ifndef __RVMOPERATORDIV_H_
+#define __RVMOPERATORDIV_H_
 
 #include "rvmoperator.h"
+#include "rvmreg.h"
 
-void rvm_op_div_init(rvm_opmap_t *opmap);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_div_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_div_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_div_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
diff --git a/rvm/rvmoperatoreq.c b/rvm/rvmoperatoreq.c
new file mode 100644 (file)
index 0000000..52dd4d3
--- /dev/null
@@ -0,0 +1,35 @@
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+
+void rvm_op_eq_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
+{
+       rword r;
+
+       r = (op1 == op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_eq_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
+{
+       rword r;
+
+       r = (op1 == op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_eq_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
+{
+       rword r;
+
+       r = (op1 == op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
diff --git a/rvm/rvmoperatoreq.h b/rvm/rvmoperatoreq.h
new file mode 100644 (file)
index 0000000..7ce6725
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATOREQ_H_
+#define __RVMOPERATOREQ_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_eq_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_eq_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_eq_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/rvm/rvmoperatorgreater.c b/rvm/rvmoperatorgreater.c
new file mode 100644 (file)
index 0000000..61ec64c
--- /dev/null
@@ -0,0 +1,36 @@
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+
+void rvm_op_greater_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
+{
+       rword r;
+
+       r = (op1 > op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_greater_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
+{
+       rword r;
+
+       r = (op1 > op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_greater_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
+{
+       rword r;
+
+       r = (op1 > op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
diff --git a/rvm/rvmoperatorgreater.h b/rvm/rvmoperatorgreater.h
new file mode 100644 (file)
index 0000000..44f3fa8
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORGREATER_H_
+#define __RVMOPERATORGREATER_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_greater_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_greater_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_greater_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/rvm/rvmoperatorgreatereq.c b/rvm/rvmoperatorgreatereq.c
new file mode 100644 (file)
index 0000000..e153271
--- /dev/null
@@ -0,0 +1,36 @@
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+
+void rvm_op_greatereq_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
+{
+       rword r;
+
+       r = (op1 >= op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_greatereq_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
+{
+       rword r;
+
+       r = (op1 >= op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_greatereq_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
+{
+       rword r;
+
+       r = (op1 >= op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
diff --git a/rvm/rvmoperatorgreatereq.h b/rvm/rvmoperatorgreatereq.h
new file mode 100644 (file)
index 0000000..83d8aba
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORGREATEREQ_H_
+#define __RVMOPERATORMULGREATEREQ_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_greatereq_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_greatereq_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_greatereq_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/rvm/rvmoperatorless.c b/rvm/rvmoperatorless.c
new file mode 100644 (file)
index 0000000..1f287fd
--- /dev/null
@@ -0,0 +1,35 @@
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+
+void rvm_op_less_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
+{
+       rword r;
+
+       r = (op1 < op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_less_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
+{
+       rword r;
+
+       r = (op1 < op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_less_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
+{
+       rword r;
+
+       r = (op1 < op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
diff --git a/rvm/rvmoperatorless.h b/rvm/rvmoperatorless.h
new file mode 100644 (file)
index 0000000..da7330a
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORLESS_H_
+#define __RVMOPERATORLESS_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_less_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_less_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_less_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/rvm/rvmoperatorlesseq.c b/rvm/rvmoperatorlesseq.c
new file mode 100644 (file)
index 0000000..7c772b1
--- /dev/null
@@ -0,0 +1,35 @@
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+
+void rvm_op_lesseq_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
+{
+       rword r;
+
+       r = (op1 <= op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_lesseq_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
+{
+       rword r;
+
+       r = (op1 <= op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_lesseq_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
+{
+       rword r;
+
+       r = (op1 <= op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
diff --git a/rvm/rvmoperatorlesseq.h b/rvm/rvmoperatorlesseq.h
new file mode 100644 (file)
index 0000000..945481e
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORLESSEQ_H_
+#define __RVMOPERATORLESSEQ_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_lesseq_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_lesseq_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_lesseq_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/rvm/rvmoperatorlogicand.c b/rvm/rvmoperatorlogicand.c
new file mode 100644 (file)
index 0000000..0ea7e66
--- /dev/null
@@ -0,0 +1,36 @@
+#include "rvmoperator.h"
+#include "rvmoperatorlogicand.h"
+#include "rvmreg.h"
+
+
+void rvm_op_logicand_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
+{
+       rword r;
+
+       r = (op1 && op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_logicand_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
+{
+       rword r;
+
+       r = (op1 && op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_logicand_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
+{
+       rword r;
+
+       r = (op1 && op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
diff --git a/rvm/rvmoperatorlogicand.h b/rvm/rvmoperatorlogicand.h
new file mode 100644 (file)
index 0000000..9ad59a3
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORLOGICAND_H_
+#define __RVMOPERATORLOGICAND_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_logicand_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_logicand_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_logicand_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/rvm/rvmoperatorlogicnot.c b/rvm/rvmoperatorlogicnot.c
new file mode 100644 (file)
index 0000000..1b183ab
--- /dev/null
@@ -0,0 +1,60 @@
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+
+static void rvm_op_logicnot_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1)
+{
+       rword r;
+
+       r = (RVM_REG_GETU(arg1)) ? 0 : 1;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+static void rvm_op_logicnot_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1)
+{
+       rword r;
+
+       r = (RVM_REG_GETL(arg1)) ? 0 : 1;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+static void rvm_op_logicnot_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1)
+{
+       rword r;
+
+       r = (RVM_REG_GETD(arg1)) ? 0 : 1;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+static void rvm_op_logicnot_string(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1)
+{
+       rword r;
+
+       r = (r_string_empty(RVM_REG_GETP(arg1))) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+
+void rvm_op_logicnot_init(rvm_opmap_t *opmap)
+{
+       rvm_opmap_add_unary_operator(opmap, RVM_OPID_LOGICNOT);
+       rvm_opmap_set_unary_handler(opmap, RVM_OPID_LOGICNOT, rvm_op_logicnot_unsigned, RVM_DTYPE_UNSIGNED);
+       rvm_opmap_set_unary_handler(opmap, RVM_OPID_LOGICNOT, rvm_op_logicnot_unsigned, RVM_DTYPE_BOOLEAN);
+       rvm_opmap_set_unary_handler(opmap, RVM_OPID_LOGICNOT, rvm_op_logicnot_unsigned, RVM_DTYPE_ARRAY);
+       rvm_opmap_set_unary_handler(opmap, RVM_OPID_LOGICNOT, rvm_op_logicnot_unsigned, RVM_DTYPE_HARRAY);
+       rvm_opmap_set_unary_handler(opmap, RVM_OPID_LOGICNOT, rvm_op_logicnot_long, RVM_DTYPE_LONG);
+       rvm_opmap_set_unary_handler(opmap, RVM_OPID_LOGICNOT, rvm_op_logicnot_double, RVM_DTYPE_DOUBLE);
+       rvm_opmap_set_unary_handler(opmap, RVM_OPID_LOGICNOT, rvm_op_logicnot_string, RVM_DTYPE_STRING);
+}
diff --git a/rvm/rvmoperatorlogicnot.h b/rvm/rvmoperatorlogicnot.h
new file mode 100644 (file)
index 0000000..1da9ac5
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __RVMOPERATORLOGICNOT_H_
+#define __RVMOPERATORLOGICNOT_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void rvm_op_logicnot_init(rvm_opmap_t *opmap);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/rvm/rvmoperatorlogicor.c b/rvm/rvmoperatorlogicor.c
new file mode 100644 (file)
index 0000000..0118eb1
--- /dev/null
@@ -0,0 +1,36 @@
+#include "rvmoperator.h"
+#include "rvmoperatorlogicor.h"
+#include "rvmreg.h"
+
+
+void rvm_op_logicor_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
+{
+       rword r;
+
+       r = (op1 || op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_logicor_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
+{
+       rword r;
+
+       r = (op1 || op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_logicor_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
+{
+       rword r;
+
+       r = (op1 || op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
diff --git a/rvm/rvmoperatorlogicor.h b/rvm/rvmoperatorlogicor.h
new file mode 100644 (file)
index 0000000..567fbce
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORLOGICOR_H_
+#define __RVMOPERATORLOGICOR_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_logicor_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_logicor_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_logicor_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 13e61b5..78eb838 100644 (file)
@@ -2,7 +2,7 @@
 #include "rvmreg.h"
 
 
-static void rvm_op_lsl_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword op2)
+void rvm_op_lsl_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
 {
        rword r;
 
@@ -14,7 +14,7 @@ static void rvm_op_lsl_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword o
 }
 
 
-static void rvm_op_lsl_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
+void rvm_op_lsl_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
 {
        rlong r;
 
@@ -26,92 +26,8 @@ static void rvm_op_lsl_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
 }
 
 
-static void rvm_op_lsl_unsigned_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_lsl_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
 {
-       rvm_op_lsl_unsigned(cpu, res, RVM_REG_GETU(arg1), RVM_REG_GETU(arg2));
+       rvm_op_lsl_long(cpu, opid, res, op1, op2);
 }
 
-
-static void rvm_op_lsl_long_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_lsl_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(arg2));
-}
-
-
-static void rvm_op_lsl_double_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_lsl_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(arg2));
-}
-
-
-void rvm_op_lsl_long_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_lsl_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_lsl_double_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_lsl_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_lsl_string_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_lsl_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_lsl_string_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_lsl_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_lsl_double_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_lsl_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(&s));
-}
-
-
-static void rvm_op_lsl_long_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_lsl_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(&s));
-}
-
-
-void rvm_op_lsl_init(rvm_opmap_t *opmap)
-{
-       rvm_opmap_add_binary_operator(opmap, RVM_OPID_LSL);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_unsigned_unsigned, RVM_DTYPE_UNSIGNED, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_double_double, RVM_DTYPE_DOUBLE, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_long_long, RVM_DTYPE_LONG, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_long_long, RVM_DTYPE_UNSIGNED, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_long_long, RVM_DTYPE_LONG, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_long_double, RVM_DTYPE_LONG, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_long_double, RVM_DTYPE_UNSIGNED, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_string_long, RVM_DTYPE_STRING, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_string_long, RVM_DTYPE_STRING, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_string_double, RVM_DTYPE_STRING, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_long_string, RVM_DTYPE_UNSIGNED, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_long_string, RVM_DTYPE_LONG, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSL, rvm_op_lsl_double_string, RVM_DTYPE_DOUBLE, RVM_DTYPE_STRING);
-}
diff --git a/rvm/rvmoperatorlsl.h b/rvm/rvmoperatorlsl.h
new file mode 100644 (file)
index 0000000..211f179
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORLSL_H_
+#define __RVMOPERATORLSL_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_lsl_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_lsl_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_lsl_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index ea1edf1..2450a72 100644 (file)
@@ -2,7 +2,7 @@
 #include "rvmreg.h"
 
 
-static void rvm_op_lsr_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword op2)
+void rvm_op_lsr_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
 {
        rword r;
 
@@ -14,7 +14,7 @@ static void rvm_op_lsr_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword o
 }
 
 
-static void rvm_op_lsr_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
+void rvm_op_lsr_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
 {
        rlong r;
 
@@ -26,92 +26,8 @@ static void rvm_op_lsr_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
 }
 
 
-static void rvm_op_lsr_unsigned_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_lsr_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
 {
-       rvm_op_lsr_unsigned(cpu, res, RVM_REG_GETU(arg1), RVM_REG_GETU(arg2));
+       rvm_op_lsr_long(cpu, opid, res, op1, op2);
 }
 
-
-static void rvm_op_lsr_long_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_lsr_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(arg2));
-}
-
-
-static void rvm_op_lsr_double_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_lsr_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(arg2));
-}
-
-
-void rvm_op_lsr_long_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_lsr_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_lsr_double_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_lsr_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_lsr_string_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_lsr_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_lsr_string_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_lsr_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_lsr_double_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_lsr_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(&s));
-}
-
-
-static void rvm_op_lsr_long_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_lsr_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(&s));
-}
-
-
-void rvm_op_lsr_init(rvm_opmap_t *opmap)
-{
-       rvm_opmap_add_binary_operator(opmap, RVM_OPID_LSR);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_unsigned_unsigned, RVM_DTYPE_UNSIGNED, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_double_double, RVM_DTYPE_DOUBLE, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_long_long, RVM_DTYPE_LONG, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_long_long, RVM_DTYPE_UNSIGNED, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_long_long, RVM_DTYPE_LONG, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_long_double, RVM_DTYPE_LONG, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_long_double, RVM_DTYPE_UNSIGNED, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_string_long, RVM_DTYPE_STRING, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_string_long, RVM_DTYPE_STRING, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_string_double, RVM_DTYPE_STRING, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_long_string, RVM_DTYPE_UNSIGNED, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_long_string, RVM_DTYPE_LONG, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_LSR, rvm_op_lsr_double_string, RVM_DTYPE_DOUBLE, RVM_DTYPE_STRING);
-}
diff --git a/rvm/rvmoperatorlsr.h b/rvm/rvmoperatorlsr.h
new file mode 100644 (file)
index 0000000..7ffedae
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORLSR_H_
+#define __RVMOPERATORLSR_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_lsr_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_lsr_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_lsr_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/rvm/rvmoperatorlsru.c b/rvm/rvmoperatorlsru.c
new file mode 100644 (file)
index 0000000..ce48f4c
--- /dev/null
@@ -0,0 +1,27 @@
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+
+void rvm_op_lsru_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
+{
+       rword r;
+
+       r = op1 >> op2;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_UNSIGNED);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, r & RVM_SIGN_BIT);
+}
+
+
+void rvm_op_lsru_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
+{
+       rvm_op_lsru_unsigned(cpu, opid, res, op1, op2);
+}
+
+
+void rvm_op_lsru_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
+{
+       rvm_op_lsru_unsigned(cpu, opid, res, op1, op2);
+}
+
diff --git a/rvm/rvmoperatorlsru.h b/rvm/rvmoperatorlsru.h
new file mode 100644 (file)
index 0000000..a96fa82
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORLSRU_H_
+#define __RVMOPERATORLSRU_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_lsru_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_lsru_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_lsru_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/rvm/rvmoperatormod.c b/rvm/rvmoperatormod.c
new file mode 100644 (file)
index 0000000..d8d8c95
--- /dev/null
@@ -0,0 +1,45 @@
+#include "rmath.h"
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+
+void rvm_op_mod_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
+{
+       rword r;
+
+       if (!op2)
+               RVM_ABORT(cpu, RVM_E_DIVZERO);
+       r = op1 % op2;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_UNSIGNED);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, r & RVM_SIGN_BIT);
+}
+
+
+void rvm_op_mod_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
+{
+       rlong r;
+
+       if (!op2)
+               RVM_ABORT(cpu, RVM_E_DIVZERO);
+       r = op1 % op2;
+       RVM_REG_SETL(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_LONG);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, r & RVM_SIGN_BIT);
+}
+
+
+void rvm_op_mod_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
+{
+       rdouble r;
+
+       if (!op2)
+               RVM_ABORT(cpu, RVM_E_DIVZERO);
+       r = r_fmod(op1, op2);
+       RVM_REG_SETD(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_DOUBLE);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, r < 0.0);
+}
diff --git a/rvm/rvmoperatormod.h b/rvm/rvmoperatormod.h
new file mode 100644 (file)
index 0000000..3a156a0
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORMOD_H_
+#define __RVMOPERATORMOD_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_mod_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_mod_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_mod_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 8be5d6c..b3cab52 100644 (file)
@@ -1,8 +1,8 @@
-#include "rvmoperatormul.h"
+#include "rvmoperator.h"
 #include "rvmreg.h"
 
 
-static void rvm_op_mul_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword op2)
+void rvm_op_mul_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
 {
        rword r;
 
@@ -15,7 +15,7 @@ static void rvm_op_mul_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword o
 }
 
 
-static void rvm_op_mul_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
+void rvm_op_mul_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
 {
        rlong r;
 
@@ -27,7 +27,7 @@ static void rvm_op_mul_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
 }
 
 
-static void rvm_op_mul_double(rvmcpu_t *cpu, rvmreg_t *res, rdouble op1, rdouble op2)
+void rvm_op_mul_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
 {
        rdouble r;
 
@@ -38,102 +38,3 @@ static void rvm_op_mul_double(rvmcpu_t *cpu, rvmreg_t *res, rdouble op1, rdouble
        RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, r < 0.0);
 }
 
-
-static void rvm_op_mul_unsigned_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_mul_unsigned(cpu, res, RVM_REG_GETU(arg1), RVM_REG_GETU(arg2));
-}
-
-
-static void rvm_op_mul_long_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_mul_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(arg2));
-}
-
-
-static void rvm_op_mul_double_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_mul_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(arg2));
-}
-
-
-void rvm_op_mul_long_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_mul_double(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_mul_double_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_mul_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_mul_string_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2double(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_mul_double(cpu, res, RVM_REG_GETD(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_mul_string_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2num(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-
-       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
-               rvm_op_mul_double(cpu, res, RVM_REG_GETD(&s), RVM_REG_GETL(arg2));
-       } else {
-               rvm_op_mul_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETL(arg2));
-       }
-}
-
-
-static void rvm_op_mul_double_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2double(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_mul_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(&s));
-}
-
-
-static void rvm_op_mul_long_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2num(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
-               rvm_op_mul_double(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(&s));
-       } else {
-               rvm_op_mul_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(&s));
-       }
-}
-
-
-void rvm_op_mul_init(rvm_opmap_t *opmap)
-{
-       rvm_opmap_add_binary_operator(opmap, RVM_OPID_MUL);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_unsigned_unsigned, RVM_DTYPE_UNSIGNED, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_double_double, RVM_DTYPE_DOUBLE, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_long_long, RVM_DTYPE_LONG, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_long_long, RVM_DTYPE_UNSIGNED, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_long_long, RVM_DTYPE_LONG, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_long_double, RVM_DTYPE_LONG, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_long_double, RVM_DTYPE_UNSIGNED, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_string_long, RVM_DTYPE_STRING, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_string_long, RVM_DTYPE_STRING, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_string_double, RVM_DTYPE_STRING, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_long_string, RVM_DTYPE_UNSIGNED, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_long_string, RVM_DTYPE_LONG, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_MUL, rvm_op_mul_double_string, RVM_DTYPE_DOUBLE, RVM_DTYPE_STRING);
-}
index 7c6cf2a..055431c 100644 (file)
@@ -1,8 +1,19 @@
-#ifndef _RVMOPERATORMUL_H_
-#define _RVMOPERATORMUL_H_
+#ifndef __RVMOPERATORMUL_H_
+#define __RVMOPERATORMUL_H_
 
 #include "rvmoperator.h"
+#include "rvmreg.h"
 
-void rvm_op_mul_init(rvm_opmap_t *opmap);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_mul_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_mul_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_mul_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
index 25a158b..29eb4e5 100644 (file)
@@ -1,21 +1,20 @@
-#include "rvmoperatormul.h"
+#include "rvmoperator.h"
 #include "rvmreg.h"
 
 
-static void rvm_op_not_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1)
+static void rvm_op_not_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1)
 {
        rword r;
 
        r = ~(RVM_REG_GETU(arg1));
        RVM_REG_SETU(res, r);
        RVM_REG_SETTYPE(res, RVM_DTYPE_UNSIGNED);
-       RVM_STATUS_CLRALL(cpu);
        RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
        RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, r & RVM_SIGN_BIT);
 }
 
 
-static void rvm_op_not_castunsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1)
+static void rvm_op_not_castunsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, const rvmreg_t *arg1)
 {
        rvmreg_t uarg;
 
@@ -23,7 +22,7 @@ static void rvm_op_not_castunsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t
        rvm_opmap_invoke_binary_handler(cpu->opmap, RVM_OPID_CAST, cpu, &uarg, arg1, &uarg);
        if (cpu->error)
                return;
-       rvm_op_not_unsigned(cpu, res, &uarg);
+       rvm_op_not_unsigned(cpu, opid, res, &uarg);
 }
 
 
@@ -31,6 +30,7 @@ void rvm_op_not_init(rvm_opmap_t *opmap)
 {
        rvm_opmap_add_unary_operator(opmap, RVM_OPID_NOT);
        rvm_opmap_set_unary_handler(opmap, RVM_OPID_NOT, rvm_op_not_unsigned, RVM_DTYPE_UNSIGNED);
+       rvm_opmap_set_unary_handler(opmap, RVM_OPID_NOT, rvm_op_not_unsigned, RVM_DTYPE_BOOLEAN);
        rvm_opmap_set_unary_handler(opmap, RVM_OPID_NOT, rvm_op_not_castunsigned, RVM_DTYPE_LONG);
        rvm_opmap_set_unary_handler(opmap, RVM_OPID_NOT, rvm_op_not_castunsigned, RVM_DTYPE_DOUBLE);
        rvm_opmap_set_unary_handler(opmap, RVM_OPID_NOT, rvm_op_not_castunsigned, RVM_DTYPE_STRING);
diff --git a/rvm/rvmoperatornot.h b/rvm/rvmoperatornot.h
new file mode 100644 (file)
index 0000000..333d68e
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef __RVMOPERATORNOT_H_
+#define __RVMOPERATORNOT_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void rvm_op_not_init(rvm_opmap_t *opmap);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/rvm/rvmoperatornoteq.c b/rvm/rvmoperatornoteq.c
new file mode 100644 (file)
index 0000000..c459f3b
--- /dev/null
@@ -0,0 +1,35 @@
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+
+void rvm_op_noteq_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
+{
+       rword r;
+
+       r = (op1 != op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_noteq_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
+{
+       rword r;
+
+       r = (op1 != op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
+
+
+void rvm_op_noteq_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
+{
+       rword r;
+
+       r = (op1 != op2) ? 1 : 0;
+       RVM_REG_SETU(res, r);
+       RVM_REG_SETTYPE(res, RVM_DTYPE_BOOLEAN);
+       RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
+}
diff --git a/rvm/rvmoperatornoteq.h b/rvm/rvmoperatornoteq.h
new file mode 100644 (file)
index 0000000..03f556a
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORNOTEQ_H_
+#define __RVMOPERATORNOTEQ_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_noteq_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_noteq_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_noteq_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 1f78ed7..25c0441 100644 (file)
@@ -2,7 +2,7 @@
 #include "rvmreg.h"
 
 
-static void rvm_op_or_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword op2)
+void rvm_op_or_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
 {
        rword r;
 
@@ -14,7 +14,7 @@ static void rvm_op_or_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword op
 }
 
 
-static void rvm_op_or_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
+void rvm_op_or_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
 {
        rlong r;
 
@@ -26,92 +26,7 @@ static void rvm_op_or_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
 }
 
 
-static void rvm_op_or_unsigned_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_or_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
 {
-       rvm_op_or_unsigned(cpu, res, RVM_REG_GETU(arg1), RVM_REG_GETU(arg2));
-}
-
-
-static void rvm_op_or_long_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_or_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(arg2));
-}
-
-
-static void rvm_op_or_double_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_or_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(arg2));
-}
-
-
-void rvm_op_or_long_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_or_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_or_double_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_or_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_or_string_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_or_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_or_string_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_or_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_or_double_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_or_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(&s));
-}
-
-
-static void rvm_op_or_long_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_or_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(&s));
-}
-
-
-void rvm_op_or_init(rvm_opmap_t *opmap)
-{
-       rvm_opmap_add_binary_operator(opmap, RVM_OPID_OR);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_unsigned_unsigned, RVM_DTYPE_UNSIGNED, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_double_double, RVM_DTYPE_DOUBLE, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_long_long, RVM_DTYPE_LONG, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_long_long, RVM_DTYPE_UNSIGNED, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_long_long, RVM_DTYPE_LONG, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_long_double, RVM_DTYPE_LONG, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_long_double, RVM_DTYPE_UNSIGNED, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_string_long, RVM_DTYPE_STRING, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_string_long, RVM_DTYPE_STRING, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_string_double, RVM_DTYPE_STRING, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_long_string, RVM_DTYPE_UNSIGNED, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_long_string, RVM_DTYPE_LONG, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_OR, rvm_op_or_double_string, RVM_DTYPE_DOUBLE, RVM_DTYPE_STRING);
+       rvm_op_or_long(cpu, opid, res, op1, op2);
 }
diff --git a/rvm/rvmoperatoror.h b/rvm/rvmoperatoror.h
new file mode 100644 (file)
index 0000000..305b7e3
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATOROR_H_
+#define __RVMOPERATOROR_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_or_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_or_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_or_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index 0f5a094..be133f8 100644 (file)
@@ -1,8 +1,8 @@
-#include "rvmoperatorsub.h"
+#include "rvmoperator.h"
 #include "rvmreg.h"
 
 
-static void rvm_op_sub_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword op2)
+void rvm_op_sub_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
 {
        rword r;
 
@@ -17,7 +17,7 @@ static void rvm_op_sub_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword o
 }
 
 
-static void rvm_op_sub_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
+void rvm_op_sub_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
 {
        rlong r;
 
@@ -29,7 +29,7 @@ static void rvm_op_sub_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
 }
 
 
-static void rvm_op_sub_double(rvmcpu_t *cpu, rvmreg_t *res, rdouble op1, rdouble op2)
+void rvm_op_sub_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
 {
        rdouble r;
 
@@ -39,103 +39,3 @@ static void rvm_op_sub_double(rvmcpu_t *cpu, rvmreg_t *res, rdouble op1, rdouble
        RVM_STATUS_UPDATE(cpu, RVM_STATUS_Z, !r);
        RVM_STATUS_UPDATE(cpu, RVM_STATUS_N, r < 0.0);
 }
-
-
-static void rvm_op_sub_unsigned_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_sub_unsigned(cpu, res, RVM_REG_GETU(arg1), RVM_REG_GETU(arg2));
-}
-
-
-static void rvm_op_sub_long_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_sub_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(arg2));
-}
-
-
-static void rvm_op_sub_double_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_sub_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(arg2));
-}
-
-
-void rvm_op_sub_long_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_sub_double(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_sub_double_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_sub_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_sub_string_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2double(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_sub_double(cpu, res, RVM_REG_GETD(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_sub_string_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2num(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-
-       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
-               rvm_op_sub_double(cpu, res, RVM_REG_GETD(&s), RVM_REG_GETL(arg2));
-       } else {
-               rvm_op_sub_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETL(arg2));
-       }
-}
-
-
-static void rvm_op_sub_double_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2double(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_sub_double(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(&s));
-}
-
-
-static void rvm_op_sub_long_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2num(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       if (rvm_reg_gettype(&s) == RVM_DTYPE_DOUBLE) {
-               rvm_op_sub_double(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(&s));
-       } else {
-               rvm_op_sub_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(&s));
-       }
-}
-
-
-void rvm_op_sub_init(rvm_opmap_t *opmap)
-{
-       rvm_opmap_add_binary_operator(opmap, RVM_OPID_SUB);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_unsigned_unsigned, RVM_DTYPE_UNSIGNED, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_double_double, RVM_DTYPE_DOUBLE, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_long_long, RVM_DTYPE_LONG, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_long_long, RVM_DTYPE_UNSIGNED, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_long_long, RVM_DTYPE_LONG, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_long_double, RVM_DTYPE_LONG, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_long_double, RVM_DTYPE_UNSIGNED, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_string_long, RVM_DTYPE_STRING, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_string_long, RVM_DTYPE_STRING, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_string_double, RVM_DTYPE_STRING, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_long_string, RVM_DTYPE_UNSIGNED, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_long_string, RVM_DTYPE_LONG, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_SUB, rvm_op_sub_double_string, RVM_DTYPE_DOUBLE, RVM_DTYPE_STRING);
-}
index 7ec1030..340decf 100644 (file)
@@ -1,8 +1,19 @@
-#ifndef _RVMOPERATORSUB_H_
-#define _RVMOPERATORSUB_H_
+#ifndef __RVMOPERATORSUB_H_
+#define __RVMOPERATORSUB_H_
 
 #include "rvmoperator.h"
+#include "rvmreg.h"
 
-void rvm_op_sub_init(rvm_opmap_t *opmap);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_sub_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_sub_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_sub_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif
index 72e188f..d139f5f 100644 (file)
@@ -2,7 +2,7 @@
 #include "rvmreg.h"
 
 
-static void rvm_op_xor_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword op2)
+void rvm_op_xor_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2)
 {
        rword r;
 
@@ -14,7 +14,7 @@ static void rvm_op_xor_unsigned(rvmcpu_t *cpu, rvmreg_t *res, rword op1, rword o
 }
 
 
-static void rvm_op_xor_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
+void rvm_op_xor_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2)
 {
        rlong r;
 
@@ -26,92 +26,7 @@ static void rvm_op_xor_long(rvmcpu_t *cpu, rvmreg_t *res, rlong op1, rlong op2)
 }
 
 
-static void rvm_op_xor_unsigned_unsigned(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
+void rvm_op_xor_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2)
 {
-       rvm_op_xor_unsigned(cpu, res, RVM_REG_GETU(arg1), RVM_REG_GETU(arg2));
-}
-
-
-static void rvm_op_xor_long_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_xor_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(arg2));
-}
-
-
-static void rvm_op_xor_double_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_xor_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(arg2));
-}
-
-
-void rvm_op_xor_long_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_xor_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_xor_double_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvm_op_xor_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_xor_string_double(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_xor_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_xor_string_long(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg1) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_xor_long(cpu, res, RVM_REG_GETL(&s), RVM_REG_GETD(arg2));
-}
-
-
-static void rvm_op_xor_double_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_xor_long(cpu, res, RVM_REG_GETD(arg1), RVM_REG_GETL(&s));
-}
-
-
-static void rvm_op_xor_long_string(rvmcpu_t *cpu, rvmreg_t *res, const rvmreg_t *arg1, const rvmreg_t *arg2)
-{
-       rvmreg_t s;
-
-       if (rvm_reg_str2long(&s, arg2) < 0)
-               RVM_ABORT(cpu, RVM_E_ILLEGAL);
-       rvm_op_xor_long(cpu, res, RVM_REG_GETL(arg1), RVM_REG_GETL(&s));
-}
-
-
-void rvm_op_xor_init(rvm_opmap_t *opmap)
-{
-       rvm_opmap_add_binary_operator(opmap, RVM_OPID_XOR);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_unsigned_unsigned, RVM_DTYPE_UNSIGNED, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_double_double, RVM_DTYPE_DOUBLE, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_long_long, RVM_DTYPE_LONG, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_long_long, RVM_DTYPE_UNSIGNED, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_long_long, RVM_DTYPE_LONG, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_long_double, RVM_DTYPE_LONG, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_long_double, RVM_DTYPE_UNSIGNED, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_double_long, RVM_DTYPE_DOUBLE, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_string_long, RVM_DTYPE_STRING, RVM_DTYPE_UNSIGNED);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_string_long, RVM_DTYPE_STRING, RVM_DTYPE_LONG);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_string_double, RVM_DTYPE_STRING, RVM_DTYPE_DOUBLE);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_long_string, RVM_DTYPE_UNSIGNED, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_long_string, RVM_DTYPE_LONG, RVM_DTYPE_STRING);
-       rvm_opmap_set_binary_handler(opmap, RVM_OPID_XOR, rvm_op_xor_double_string, RVM_DTYPE_DOUBLE, RVM_DTYPE_STRING);
+       rvm_op_xor_long(cpu, opid, res, op1, op2);
 }
diff --git a/rvm/rvmoperatorxor.h b/rvm/rvmoperatorxor.h
new file mode 100644 (file)
index 0000000..385e1f9
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __RVMOPERATORXOR_H_
+#define __RVMOPERATORXOR_H_
+
+#include "rvmoperator.h"
+#include "rvmreg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rvm_op_xor_unsigned(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rword op1, rword op2);
+void rvm_op_xor_long(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rlong op1, rlong op2);
+void rvm_op_xor_double(rvmcpu_t *cpu, rushort opid, rvmreg_t *res, rdouble op1, rdouble op2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
index f5b78be..133da91 100644 (file)
 #include "rmem.h"
 #include "rvmreg.h"
-#include "rrefreg.h"
 #include "rref.h"
 
 
-static void r_array_oncopy_rvmreg(rarray_t *array)
+static void rvm_reg_array_oncopy(rarray_t *array)
 {
        ruint index;
        rvmreg_t *r;
 
-       for (index = 0; index < array->len; index++) {
+       for (index = 0; index < r_array_length(array); index++) {
                r = (rvmreg_t *)r_array_slot(array, index);
                rvm_reg_copy(r, r);
        }
 }
 
 
-static void r_array_ondestroy_rvmreg(rarray_t *array)
+static void rvm_reg_array_oncleanup(rarray_t *array)
 {
        ruint index;
        rvmreg_t *r;
 
-       for (index = 0; index < array->len; index++) {
+       for (index = 0; index < r_array_length(array); index++) {
                r = (rvmreg_t *)r_array_slot(array, index);
                rvm_reg_cleanup(r);
        }
 }
 
 
+static void rvm_reg_carray_oncopy(rcarray_t *array)
+{
+       ruint index;
+       rvmreg_t *r;
+       ruint len = r_carray_length(array);
+
+
+       for (index = 0; index < len; index++) {
+               r = (rvmreg_t *)r_carray_slot(array, index);
+               rvm_reg_copy(r, r);
+       }
+}
+
+
+static void rvm_reg_carray_oncleanup(rcarray_t *array)
+{
+       ruint index;
+       rvmreg_t *r;
+       ruint len = r_carray_length(array);
+
+
+       for (index = 0; index < len; index++) {
+               r = (rvmreg_t *)r_carray_slot(array, index);
+               rvm_reg_cleanup(r);
+       }
+}
+
+
+/*
+ * Recursively go over array data to unref any GC managed
+ * objects. We need this because when GC is destroying arrays,
+ * array's oncleanup might try to destroy the data, that should really
+ * be destroyed by the GC. To avoid any attempts the same data
+ * to be destroyed twice we remove the references of all GC managed
+ * data from the arrays and leave the destruction of such data to
+ * the GC.
+ */
+void rvm_reg_array_unref_gcdata(robject_t *obj)
+{
+       ruint size;
+       int i;
+       rvmreg_t *r;
+
+       if (obj->type == R_OBJECT_ARRAY || obj->type == R_OBJECT_HARRAY) {
+               rarray_t *array;
+               if (obj->type == R_OBJECT_ARRAY)
+                       array = (rarray_t*)obj;
+               else
+                       array = ((rharray_t*)obj)->members;
+               if ((size = r_array_length(array)) > 0) {
+                       /*
+                        * set the size to 0, to prevent circular references to come back here
+                        */
+                       r_array_setlength(array, 0);
+                       for (i = 0; i < size; i++) {
+                               r = (rvmreg_t*) r_array_slot(array, i);
+                               if (rvm_reg_tstflag(r, RVM_INFOBIT_ROBJECT)) {
+                                       robject_t *p = RVM_REG_GETP(r);
+                                       if (!r_list_empty(&p->lnk)) {
+                                               /*
+                                                * if this entry is robject_t that is on GC
+                                                * list, it can be RVM_REG_CLEARed. It will be
+                                                * cleaned up by the GC.
+                                                */
+                                               rvm_reg_array_unref_gcdata(p);
+                                               RVM_REG_CLEAR(r);
+                                       }
+                               }
+
+                       }
+                       /*
+                        * Restore the size
+                        */
+                       r_array_setlength(array, size);
+               }
+       } else if (obj->type == R_OBJECT_CARRAY) {
+               rcarray_t *array = (rcarray_t*)obj;
+               if ((size = r_carray_length(array)) > 0) {
+                       /*
+                        * set the size to 0, to prevent circular references to come back here
+                        */
+                       array->alloc_size = 0;
+                       for (i = 0; i < size; i++) {
+                               r = (rvmreg_t*) r_carray_slot(array, i);
+                               if (rvm_reg_tstflag(r, RVM_INFOBIT_ROBJECT)) {
+                                       robject_t *p = RVM_REG_GETP(r);
+                                       if (!r_list_empty(&p->lnk)) {
+                                               /*
+                                                * if this entry is robject_t that is on GC
+                                                * list, it can be RVM_REG_CLEARed. It will be
+                                                * cleaned up by the GC.
+                                                */
+                                               rvm_reg_array_unref_gcdata(p);
+                                               RVM_REG_CLEAR(r);
+                                       }
+                               }
+
+                       }
+                       /*
+                        * Restore the size
+                        */
+                       array->alloc_size = size;
+               }
+       }
+}
+
+
+
 rarray_t *r_array_create_rvmreg()
 {
        rarray_t *array = r_array_create(sizeof(rvmreg_t));
        if (array) {
-               array->oncopy = r_array_oncopy_rvmreg;
-               array->ondestroy = r_array_ondestroy_rvmreg;
+               array->oncopy = rvm_reg_array_oncopy;
+               array->oncleanup = rvm_reg_array_oncleanup;
+       }
+       return array;
+}
+
+
+rcarray_t *r_carray_create_rvmreg()
+{
+       rcarray_t *array = r_carray_create(sizeof(rvmreg_t));
+       if (array) {
+               array->oncopy = rvm_reg_carray_oncopy;
+               array->oncleanup = rvm_reg_carray_oncleanup;
        }
        return array;
 }
@@ -43,8 +161,8 @@ rharray_t *r_harray_create_rvmreg()
 {
        rharray_t *harray = r_harray_create(sizeof(rvmreg_t));
        if (harray) {
-               harray->members->oncopy = r_array_oncopy_rvmreg;
-               harray->members->ondestroy = r_array_ondestroy_rvmreg;
+               harray->members->oncopy = rvm_reg_array_oncopy;
+               harray->members->oncleanup = rvm_reg_array_oncleanup;
        }
        return harray;
 }
@@ -71,22 +189,12 @@ rvmreg_t rvm_reg_create_string(const rstr_t *s)
        return r;
 }
 
-rvmreg_t rvm_reg_create_refreg()
-{
-       rvmreg_t r;
-       r_memset(&r, 0, sizeof(r));
-       RVM_REG_SETP(&r, r_refreg_create());
-       RVM_REG_SETTYPE(&r, RVM_DTYPE_REFREG);
-       RVM_REG_SETFLAG(&r, RVM_INFOBIT_ROBJECT);
-       return r;
-}
-
 
 rvmreg_t rvm_reg_create_array()
 {
        rvmreg_t r;
        r_memset(&r, 0, sizeof(r));
-       rvm_reg_setarray(&r, r_array_create_rvmreg());
+       rvm_reg_setarray(&r, (robject_t*)r_carray_create_rvmreg());
        return r;
 }
 
@@ -95,7 +203,7 @@ rvmreg_t rvm_reg_create_harray()
 {
        rvmreg_t r;
        r_memset(&r, 0, sizeof(r));
-       rvm_reg_setharray(&r, r_harray_create_rvmreg());
+       rvm_reg_setharray(&r, (robject_t*)r_harray_create_rvmreg());
        return r;
 }
 
@@ -107,7 +215,7 @@ void rvm_reg_setstring(rvmreg_t *r, rstring_t *ptr)
 }
 
 
-void rvm_reg_setarray(rvmreg_t *r, rarray_t *ptr)
+void rvm_reg_setarray(rvmreg_t *r, robject_t *ptr)
 {
        RVM_REG_SETP(r, ptr);
        RVM_REG_SETTYPE(r, RVM_DTYPE_ARRAY);
@@ -115,7 +223,7 @@ void rvm_reg_setarray(rvmreg_t *r, rarray_t *ptr)
 }
 
 
-void rvm_reg_setharray(rvmreg_t *r, rharray_t *ptr)
+void rvm_reg_setharray(rvmreg_t *r, robject_t *ptr)
 {
        RVM_REG_SETP(r, ptr);
        RVM_REG_SETTYPE(r, RVM_DTYPE_HARRAY);
@@ -144,9 +252,7 @@ rvmreg_t rvm_reg_create_long(rlong l)
 
 void rvm_reg_cleanup(rvmreg_t *reg)
 {
-       if (rvm_reg_gettype(reg) == RVM_DTYPE_REFREG)
-               r_ref_dec((rref_t*)RVM_REG_GETP(reg));
-       else if (rvm_reg_tstflag(reg, RVM_INFOBIT_ROBJECT)) {
+       if (rvm_reg_tstflag(reg, RVM_INFOBIT_ROBJECT)) {
                r_object_destroy((robject_t*)RVM_REG_GETP(reg));
        }
        RVM_REG_CLEAR(reg);
@@ -158,23 +264,11 @@ rvmreg_t *rvm_reg_copy(rvmreg_t *dst, const rvmreg_t *src)
        if (dst != src)
                *dst = *src;
        if (rvm_reg_tstflag(dst, RVM_INFOBIT_ROBJECT))
-               dst->v.p = r_object_copy(dst->v.p);
+               dst->v.p = r_object_v_copy(dst->v.p);
        return dst;
 }
 
 
-rvmreg_t *rvm_reg_refer(rvmreg_t *dst, const rvmreg_t *src)
-{
-       if (rvm_reg_gettype(dst) == RVM_DTYPE_REFREG) {
-               if (dst != src)
-                       *dst = *src;
-               r_ref_inc((rref_t*)RVM_REG_GETP(dst));
-               return dst;
-       }
-       return NULL;
-}
-
-
 void rvm_reg_settype(rvmreg_t *r, ruint type)
 {
        RVM_REG_SETTYPE(r, type);
@@ -183,7 +277,8 @@ void rvm_reg_settype(rvmreg_t *r, ruint type)
 
 ruint rvm_reg_gettype(const rvmreg_t *r)
 {
-       return RVM_REG_GETTYPE(r);
+       rulong type = RVM_REG_GETTYPE(r);
+       return type;
 }
 
 
@@ -230,41 +325,11 @@ void rvm_reg_setdouble(rvmreg_t *r, rdouble d)
 }
 
 
-void rvm_reg_setrefreg(rvmreg_t *r, struct rrefreg_s *ptr)
-{
-       RVM_REG_SETP(r, ptr);
-       RVM_REG_SETTYPE(r, RVM_DTYPE_REFREG);
-       RVM_REG_SETFLAG(r, RVM_INFOBIT_ROBJECT);
-}
-
-
-void rvm_reg_convert_to_refreg(rvmreg_t *reg)
-{
-       rrefreg_t * refreg = NULL;
-
-       if (rvm_reg_gettype(reg) == RVM_DTYPE_REFREG)
-               return;
-       refreg = r_refreg_create();
-       *REFREG2REGPTR(refreg) = *reg;
-       RVM_REG_CLEAR(reg);
-       rvm_reg_setrefreg(reg, refreg);
-}
-
-
-rvmreg_t *rvm_reg_unshadow(const rvmreg_t *reg)
-{
-       if (rvm_reg_gettype(reg) != RVM_DTYPE_REFREG)
-               return (rvmreg_t*)reg;
-       return REFREG2REGPTR(RVM_REG_GETP(reg));
-}
-
-
-int rvm_reg_str2num(rvmreg_t *dst, const rvmreg_t *ssrc)
+int rvm_reg_str2num(rvmreg_t *dst, const rvmreg_t *src)
 {
        rchar *dptr, *lptr;
        rdouble d;
        rlong l;
-       const rvmreg_t *src = rvm_reg_unshadow(ssrc);
 
        l = r_strtol(R_STRING2PTR(RVM_REG_GETP(src)), &lptr, 10);
        if (!lptr)
@@ -281,11 +346,10 @@ int rvm_reg_str2num(rvmreg_t *dst, const rvmreg_t *ssrc)
 }
 
 
-int rvm_reg_str2long(rvmreg_t *dst, const rvmreg_t *ssrc)
+int rvm_reg_str2long(rvmreg_t *dst, const rvmreg_t *src)
 {
        rchar *dptr;
        rdouble d;
-       const rvmreg_t *src = rvm_reg_unshadow(ssrc);
 
        d = r_strtod(R_STRING2PTR(RVM_REG_GETP(src)), &dptr);
        if (!dptr)
@@ -295,11 +359,10 @@ int rvm_reg_str2long(rvmreg_t *dst, const rvmreg_t *ssrc)
 }
 
 
-int rvm_reg_str2double(rvmreg_t *dst, const rvmreg_t *ssrc)
+int rvm_reg_str2double(rvmreg_t *dst, const rvmreg_t *src)
 {
        rchar *dptr;
        rdouble d;
-       const rvmreg_t *src = rvm_reg_unshadow(ssrc);
 
        d = r_strtod(R_STRING2PTR(RVM_REG_GETP(src)), &dptr);
        if (!dptr)
index 2f840be..75379df 100644 (file)
 #ifndef _RVMREG_H_
 #define _RVMREG_H_
 
-#include "rvmcpu.h"
+//#include "rvmcpu.h"
 #include "robject.h"
 #include "rarray.h"
 #include "rharray.h"
+#include "rcarray.h"
 #include "rstring.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#define RVM_DTYPE_NONE 0
+#define RVM_DTYPE_WORD RVM_DTYPE_NONE
+#define RVM_DTYPE_UNSIGNED RVM_DTYPE_NONE
+#define RVM_DTYPE_LONG 1
+#define RVM_DTYPE_POINTER 2                    /* Generic pointer, it can point to any memory object */
+#define RVM_DTYPE_BOOLEAN 3
+#define RVM_DTYPE_STRING 4
+#define RVM_DTYPE_ARRAY 5
+#define RVM_DTYPE_HARRAY 6
+#define RVM_DTYPE_DOUBLE 7
+#define RVM_DTYPE_RELOCPTR 14          /* Relocation, using pointers */
+#define RVM_DTYPE_RELOCINDEX 15                /* Relocation, using offsets */
+#define RVM_DTYPE_USER 16
+#define RVM_DTYPE_SIZE (1 << 5)
+#define RVM_DTYPE_MASK (RVM_DTYPE_SIZE - 1)
+#define RVM_DTYPE_MAX (RVM_DTYPE_MASK)
+#define RVM_DTYPE_USERDEF(__n__) (RVM_DTYPE_USER + (__n__))
+
+#define RVM_INFOBIT_ROBJECT (1 << 0)
+#define RVM_INFOBIT_LAST (1 << 15)
+#define RVM_INFOBIT_ALL (RVM_INFOBIT_ROBJECT | RVM_INFOBIT_LAST)
+
+#define r_carray_rvmregslot(__carray__, __index__)((rvmreg_t*)(((rchar*)r_array_index((__carray__)->array, (__index__) >> R_CARRAY_CHUNKBITS, rpointer)) + ((__index__) & R_CARRAY_CHUNKMASK) * sizeof(rvmreg_t)))
+#define RVM_STACK_ADDR(__cpu__, __off__) ((rvmreg_t*)r_carray_rvmregslot((__cpu__)->stack, (__off__) ))
+#define RVM_SPOFF_ADDR(__cpu__, __spoff__) RVM_STACK_ADDR(__cpu__, (RVM_CPUREG_GETU(__cpu__, SP) - (__spoff__)))
+
+#define RVM_CPUREG_R_PTR(__cpu__, __r__) (&(__cpu__)->r[(__r__)])
+#define RVM_CPUREG_PTR(__cpu__, __r__) RVM_CPUREG_R_PTR(__cpu__, __r__)
+#define RVM_CPUREG_GET(__cpu__, __r__) *(RVM_CPUREG_PTR(__cpu__, __r__))
+#define RVM_CPUREG_SET(__cpu__, __r__, __val__) do { *(RVM_CPUREG_PTR(__cpu__, __r__)) = (rvmreg_t)(__val__); } while (0)
+
+#define RVM_REG_GETTYPE(__r__) (__r__)->type
+#define RVM_REG_SETTYPE(__r__, __val__) do { (__r__)->type = (__val__); } while(0);
+#define RVM_CPUREG_GETTYPE(__cpu__, __r__) RVM_REG_GETTYPE(RVM_CPUREG_PTR(__cpu__, __r__))
+#define RVM_CPUREG_SETTYPE(__cpu__, __r__, __val__) RVM_REG_SETTYPE(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
+
+#define RVM_REG_TSTFLAG(__r__, __flag__) ((__r__)->flags & (__flag__)) ? TRUE : FALSE
+#define RVM_REG_SETFLAG(__r__, __flag__) do { (__r__)->flags |= (__flag__); } while (0)
+#define RVM_REG_CLRFLAG(__r__, __flag__) do { (__r__)->flags &= ~(__flag__); } while (0)
+#define RVM_REG_ASSIGNFLAGS(__r__, __flags__) do { (__r__)->flags = ~(__flags__); } while (0)
+#define RVM_CPUREG_TSTFLAG(__cpu__, __r__, __flag__) RVM_REG_TSTFLAG(RVM_CPUREG_PTR(__cpu__, __r__), __flag__)
+#define RVM_CPUREG_SETFLAG(__cpu__, __r__, __flag__) RVM_REG_SETFLAG(RVM_CPUREG_PTR(__cpu__, __r__), __flag__)
+#define RVM_CPUREG_CLRFLAG(__cpu__, __r__, __flag__) RVM_REG_CLRFLAG(RVM_CPUREG_PTR(__cpu__, __r__), __flag__)
+#define RVM_CPUREG_ASSIGNFLAGS(__cpu__, __r__, __flags__) RVM_REG_ASSIGNFLAGS(RVM_CPUREG_PTR(__cpu__, __r__), __flags__)
+
+#define RVM_REG_GETU(__r__) (__r__)->v.w
+#define RVM_REG_SETU(__r__, __val__) do { (__r__)->v.w = (rword)(__val__); } while (0)
+#define RVM_CPUREG_GETU(__cpu__, __r__) RVM_CPUREG_PTR(__cpu__, __r__)->v.w
+#define RVM_CPUREG_SETU(__cpu__, __r__, __val__) RVM_REG_SETU(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
+
+#define RVM_REG_GETL(__r__) (__r__)->v.l
+#define RVM_REG_SETL(__r__, __val__) do { (__r__)->v.l = (rlong)(__val__); } while (0)
+#define RVM_CPUREG_GETL(__cpu__, __r__) RVM_CPUREG_PTR(__cpu__, __r__)->v.l
+#define RVM_CPUREG_SETL(__cpu__, __r__, __val__) RVM_REG_SETL(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
+
+#define RVM_REG_GETP(__r__) (__r__)->v.p
+#define RVM_REG_SETP(__r__, __val__) do { (__r__)->v.p = (rpointer)(__val__); } while (0)
+#define RVM_CPUREG_GETP(__cpu__, __r__) RVM_CPUREG_PTR(__cpu__, __r__)->v.p
+#define RVM_CPUREG_SETP(__cpu__, __r__, __val__) RVM_REG_SETP(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
+
+#define RVM_REG_GETD(__r__) (__r__)->v.d
+#define RVM_REG_SETD(__r__, __val__) do { (__r__)->v.d = (rdouble)(__val__); } while (0)
+#define RVM_CPUREG_GETD(__cpu__, __r__) RVM_CPUREG_PTR(__cpu__, __r__)->v.d
+#define RVM_CPUREG_SETD(__cpu__, __r__, __val__) RVM_REG_SETD(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
+
+#define RVM_REG_GETIP(__r__) (rvm_asmins_t*)((__r__)->v.p)
+#define RVM_REG_SETIP(__r__, __val__) do { (__r__)->v.p = (rpointer)(__val__); } while (0)
+#define RVM_REG_INCIP(__r__, __val__) do {rvm_asmins_t *p = RVM_REG_GETIP(__r__); (__r__)->v.p = (rpointer)(p + (__val__)); } while (0)
+#define RVM_CPUREG_GETIP(__cpu__, __r__) ((rvm_asmins_t*)RVM_CPUREG_PTR(__cpu__, __r__)->v.p)
+#define RVM_CPUREG_SETIP(__cpu__, __r__, __val__) RVM_REG_SETIP(RVM_CPUREG_PTR(__cpu__, __r__), __val__)
+#define RVM_CPUREG_INCIP(__cpu__, __r__, __val__) do {rvm_asmins_t *p = RVM_CPUREG_GETIP(__cpu__, __r__); (RVM_CPUREG_PTR(__cpu__, __r__))->v.p = (rpointer)(p + (__val__)); } while (0)
+
+#define RVM_REG_SIZE(__r__) (__r__)->size
+#define RVM_REG_CLEAR(__r__) do { (__r__)->v.w = 0UL; (__r__)->type = 0; (__r__)->flags = 0;  } while (0)
+#define RVM_CPUREG_CLEAR(__cpu__, __r__) RVM_REG_CLEAR(RVM_CPUREG_PTR(__cpu__, __r__))
+
+
+#define RVM_MIN_REGSIZE (sizeof(rword)/8)
+
+typedef ruint16 rvmreg_type_t;
+typedef ruint16 rvmreg_flags_t;
+
+typedef struct rvmreg_s {
+       union {
+               rword w;
+               rlong l;
+               rpointer p;
+               rdouble d;
+               ruint8 c[RVM_MIN_REGSIZE];
+       } v;
+       rvmreg_type_t type;
+       rvmreg_flags_t flags;
+       ruint32 size;
+} rvmreg_t;
 
 /* Create array with rvmreg elements */
 rarray_t *r_array_create_rvmreg();
 /* Create harray with rvmreg elements */
 rharray_t *r_harray_create_rvmreg();
+/* Create carray with rvmreg elements */
+rcarray_t *r_carray_create_rvmreg();
 
 rvmreg_t rvm_reg_create_string_ansi(const rchar *s);
 rvmreg_t rvm_reg_create_string(const rstr_t *s);
 rvmreg_t rvm_reg_create_array();
 rvmreg_t rvm_reg_create_harray();
-rvmreg_t rvm_reg_create_refreg();
 rvmreg_t rvm_reg_create_double(rdouble d);
 rvmreg_t rvm_reg_create_long(rlong l);
 void rvm_reg_cleanup(rvmreg_t *reg);
 rvmreg_t *rvm_reg_copy(rvmreg_t *dst, const rvmreg_t *src);
-rvmreg_t *rvm_reg_refer(rvmreg_t *dst, const rvmreg_t *src);
+void rvm_reg_array_unref_gcdata(robject_t *obj);
 void rvm_reg_settype(rvmreg_t *r, ruint type);
 ruint rvm_reg_gettype(const rvmreg_t *r);
 rboolean rvm_reg_tstflag(const rvmreg_t *r, ruint16 flag);
@@ -36,16 +132,11 @@ void rvm_reg_setunsigned(rvmreg_t *r, rword u);
 void rvm_reg_setlong(rvmreg_t *r, rlong l);
 void rvm_reg_setdouble(rvmreg_t *r, rdouble d);
 void rvm_reg_setstring(rvmreg_t *r, rstring_t *ptr);
-void rvm_reg_setarray(rvmreg_t *r, rarray_t *ptr);
-void rvm_reg_setharray(rvmreg_t *r, rharray_t *ptr);
-void rvm_reg_convert_to_refreg(rvmreg_t *r);
+void rvm_reg_setarray(rvmreg_t *r, robject_t *ptr);
+void rvm_reg_setharray(rvmreg_t *r, robject_t *ptr);
 int rvm_reg_str2num(rvmreg_t *dst, const rvmreg_t *src);
 int rvm_reg_str2long(rvmreg_t *dst, const rvmreg_t *ssrc);
 int rvm_reg_str2double(rvmreg_t *dst, const rvmreg_t *ssrc);
-rvmreg_t *rvm_reg_unshadow(const rvmreg_t *reg);
-
-struct rrefreg_s;
-void rvm_reg_setrefreg(rvmreg_t *r, struct rrefreg_s *ptr);
 
 
 #ifdef __cplusplus
index 0d28a8e..0766759 100644 (file)
@@ -2,6 +2,7 @@
 #include "rstring.h"
 #include "rmem.h"
 
+
 rvm_scope_t *rvm_scope_create()
 {
        rvm_scope_t *scope;
@@ -21,14 +22,14 @@ rvm_scope_t *rvm_scope_create()
 void rvm_scope_destroy(rvm_scope_t *scope)
 {
        int i;
-       int len = scope->names->len;
+       int len = r_array_length(scope->names);
 
        for (i = 0; i < len; i++)
                r_free(r_array_index(scope->names, i, rchar*));
-       r_array_destroy(scope->names);
-       r_array_destroy(scope->varstack);
-       r_array_destroy(scope->scopestack);
-       r_hash_destroy(scope->nameshash);
+       r_object_destroy((robject_t*)scope->names);
+       r_object_destroy((robject_t*)scope->varstack);
+       r_object_destroy((robject_t*)scope->scopestack);
+       r_object_destroy((robject_t*)scope->nameshash);
        r_free(scope);
 }
 
@@ -53,18 +54,27 @@ rchar *rvm_scope_addstrname(rvm_scope_t *scope, const rchar *name)
 }
 
 
+ruint rvm_scope_count(rvm_scope_t* scope)
+{
+       return r_array_length(scope->scopestack);
+}
+
+
 void rvm_scope_push(rvm_scope_t* scope)
 {
-       ruint scopesize = scope->varstack->len;
-       r_array_add(scope->scopestack, &scopesize);
+       ruint scopelen = r_array_length(scope->varstack);
+//     r_printf("SCOPE FRAME: %d, PUSH: %d\n", r_array_length(scope->scopestack), scopelen);
+       r_array_add(scope->scopestack, &scopelen);
 }
 
 
 void rvm_scope_pop(rvm_scope_t* scope)
 {
-       ruint scopesize = r_array_index(scope->scopestack, scope->scopestack->len - 1, ruint);
-       r_array_setsize(scope->scopestack, scope->scopestack->len - 1);
-       r_array_setsize(scope->varstack, scopesize);
+       ruint scopelen = r_array_index(scope->scopestack, r_array_length(scope->scopestack) - 1, ruint);
+//     r_array_setlength(scope->scopestack, r_array_length(scope->scopestack));
+       r_array_remove(scope->scopestack);
+       r_array_setlength(scope->varstack, scopelen);
+//     r_printf("SCOPE FRAME: %d, POP: %d\n", r_array_length(scope->scopestack), scopelen);
 }
 
 
@@ -74,14 +84,14 @@ void rvm_scope_addoffset(rvm_scope_t *scope, const rchar *name, ruint namesize,
 
        vmap.name = rvm_scope_addname(scope, name, namesize);
        vmap.data.offset = off;
-       vmap.datatype = VARMAP_DATATYPE_OFFSET;
+       vmap.datatype = r_array_empty(scope->scopestack) ? VARMAP_DATATYPE_OFFSET : VARMAP_DATATYPE_FPOFFSET;
        r_array_add(scope->varstack, &vmap);
 }
 
 
 ruint rvm_scope_numentries(rvm_scope_t *scope)
 {
-       return r_array_size(scope->varstack);
+       return r_array_length(scope->varstack);
 }
 
 
@@ -98,16 +108,16 @@ void rvm_scope_addpointer(rvm_scope_t *scope, const rchar *name, ruint namesize,
 
 rvm_varmap_t *rvm_scope_lookup(rvm_scope_t *scope, const rchar *name, ruint namesize)
 {
-       ruint scopesize = scope->varstack->len;
+       ruint scopelen = r_array_length(scope->varstack);
        rvm_varmap_t *varmap;
        rint i;
 
-       if (!scopesize)
+       if (!scopelen)
                return NULL;
 
-       for (i = scopesize - 1; i >= 0; i--) {
+       for (i = scopelen - 1; i >= 0; i--) {
                varmap = (rvm_varmap_t*)r_array_slot(scope->varstack, i);
-               if (r_strncmp(varmap->name, name, namesize) == 0)
+               if (r_strlen(varmap->name) == namesize && r_strncmp(varmap->name, name, namesize) == 0)
                        return varmap;
        }
        return NULL;
@@ -116,16 +126,16 @@ rvm_varmap_t *rvm_scope_lookup(rvm_scope_t *scope, const rchar *name, ruint name
 
 rvm_varmap_t *rvm_scope_tiplookup(rvm_scope_t *scope, const rchar *name, ruint namesize)
 {
-       ruint scopesize = scope->varstack->len;
+       ruint scopelen = r_array_length(scope->varstack);
        ruint tipstart = r_array_empty(scope->scopestack) ? 0 : r_array_last(scope->scopestack, ruint);
        rvm_varmap_t *varmap;
        rint i;
 
-       if (!scopesize)
+       if (!scopelen)
                return NULL;
-       for (i = scopesize - 1; i >= (rint)tipstart; i--) {
+       for (i = scopelen - 1; i >= (rint)tipstart; i--) {
                varmap = (rvm_varmap_t*)r_array_slot(scope->varstack, i);
-               if (r_strncmp(varmap->name, name, namesize) == 0)
+               if (r_strlen(varmap->name) == namesize && r_strncmp(varmap->name, name, namesize) == 0)
                        return varmap;
        }
        return NULL;
index 6107d12..acdc641 100644 (file)
 extern "C" {
 #endif
 
-
 #define VARMAP_DATATYPE_OFFSET 0
-#define VARMAP_DATATYPE_PTR 1
+#define VARMAP_DATATYPE_FPOFFSET 1
+#define VARMAP_DATATYPE_PTR 2
+
 
 typedef struct rvm_varmap_s {
        const rchar *name;
@@ -40,6 +41,7 @@ void rvm_scope_addoffset(rvm_scope_t *scope, const rchar *name, ruint namesize,
 void rvm_scope_addpointer(rvm_scope_t *scope, const rchar *name, ruint namesize, rpointer ptr);
 void rvm_scope_push(rvm_scope_t* scope);
 void rvm_scope_pop(rvm_scope_t* scope);
+ruint rvm_scope_count(rvm_scope_t* scope);
 ruint rvm_scope_numentries(rvm_scope_t *scope);
 rvm_varmap_t *rvm_scope_lookup(rvm_scope_t *scope, const rchar *name, ruint namesize);
 rvm_varmap_t *rvm_scope_lookup_s(rvm_scope_t *scope, const rchar *name);
index 2f8c77f..abf8568 100644 (file)
@@ -1,5 +1,6 @@
 #include <stdio.h>
-#include "rrefreg.h"
+#include "rstring.h"
+#include "rvmreg.h"
 #include "rvmcpu.h"
 #include "common.h"
 
@@ -8,8 +9,6 @@ static void test_swi_print_r(rvmcpu_t *cpu, rvm_asmins_t *ins)
        ruint8 R = ins->op1;
        rvmreg_t *r = RVM_CPUREG_PTR(cpu, R);
 
-       if (rvm_reg_gettype(r) == RVM_DTYPE_REFREG)
-               r = REFREG2REGPTR(RVM_REG_GETP(r));
        if (rvm_reg_gettype(r) == RVM_DTYPE_WORD)
                fprintf(stdout, "R%d = %ld\n", R, RVM_REG_GETL(r));
        else if (rvm_reg_gettype(r) == RVM_DTYPE_LONG)
index 97800c9..d877a6c 100644 (file)
@@ -19,8 +19,8 @@ int main(int argc, char *argv[])
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asmp(RVM_LDRR, R1, DA, XX, &d1s);
        vmcode[off++] = rvm_asm(RVM_EADD, R0, R0, R1, 0);
-       VMTEST_REGD(vmcode, off, 0, 3.0, "ADD");
-       VMTEST_STATUS(vmcode, off, 0, "ADD STATUS");
+       VMTEST_REGD(vmcode, off, 0, 3.0, "1: EADD");
+       VMTEST_STATUS(vmcode, off, 0, "1: EADD STATUS");
        vmcode[off++] = rvm_asm(RVM_PRN, R0, XX, XX, 0);
        vmcode[off++] = rvm_asm(RVM_PRN, R1, XX, XX, 0);
 
@@ -28,32 +28,54 @@ int main(int argc, char *argv[])
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asmp(RVM_LDRR, R1, DA, XX, &d1s);
        vmcode[off++] = rvm_asm(RVM_EADD, R0, R1, R0, 0);
-       VMTEST_REGP(vmcode, off, 0, &d2, "ADD");
-       VMTEST_STATUS(vmcode, off, 0, "ADD STATUS");
+       VMTEST_REGP(vmcode, off, 0, &d2, "2: EADD");
+       VMTEST_STATUS(vmcode, off, 0, "2: EADD STATUS");
 
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asm(RVM_MOV, R1, DA, XX, 2);
        vmcode[off++] = rvm_asm(RVM_EADD, R0, R1, R0, 0);
-       VMTEST_REG(vmcode, off, 0, 3, "ADD");
-       VMTEST_STATUS(vmcode, off, 0, "ADD STATUS");
+       VMTEST_REG(vmcode, off, 0, 3, "3: EADD");
+       VMTEST_STATUS(vmcode, off, 0, "3: EADD STATUS");
 
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asmd(RVM_MOV, R1, DA, XX, 2.0);
+//     vmcode[off++] = rvm_asm(RVM_SETTYPE, R1, DA, XX, RVM_DTYPE_DOUBLE);
+
        vmcode[off++] = rvm_asm(RVM_EADD, R0, R1, R0, 0);
-       VMTEST_REGP(vmcode, off, 0, &d2, "ADD");
-       VMTEST_STATUS(vmcode, off, 0, "ADD STATUS");
+       vmcode[off++] = rvm_asm(RVM_PRN, R0, XX, XX, 0);
+       VMTEST_REGP(vmcode, off, 0, &d2, "4: EADD");
+       VMTEST_STATUS(vmcode, off, 0, "4: EADD STATUS");
 
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asmp(RVM_LDRR, R1, DA, XX, &d1);
        vmcode[off++] = rvm_asm(RVM_EADD, R0, R0, R1, 0);
-       VMTEST_REGP(vmcode, off, 0, &d2, "ADD");
-       VMTEST_STATUS(vmcode, off, 0, "ADD STATUS");
+       VMTEST_REGP(vmcode, off, 0, &d2, "5: EADD");
+       VMTEST_STATUS(vmcode, off, 0, "5: EADD STATUS");
 
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asml(RVM_MOV, R1, DA, XX, -2);
        vmcode[off++] = rvm_asm(RVM_EADD, R0, R1, R0, 0);
-       VMTEST_REGL(vmcode, off, 0, -1, "ADD");
-       VMTEST_STATUS(vmcode, off, 0, "ADD STATUS");
+       VMTEST_REGL(vmcode, off, 0, -1, "6: EADD");
+       VMTEST_STATUS(vmcode, off, RVM_STATUS_N, "6: EADD STATUS");
+
+       vmcode[off++] = rvm_asmb(RVM_MOV, R1, DA, XX, 1);
+       vmcode[off++] = rvm_asmb(RVM_MOV, R2, DA, XX, 1);
+       vmcode[off++] = rvm_asm(RVM_EADD, R0, R1, R2, 0);
+       VMTEST_REGL(vmcode, off, 0, 2, "7: EADD");
+       VMTEST_STATUS(vmcode, off, 0, "7: EADD STATUS");
+
+       vmcode[off++] = rvm_asmb(RVM_MOV, R1, DA, XX, 1);
+       vmcode[off++] = rvm_asml(RVM_MOV, R2, DA, XX, -2);
+       vmcode[off++] = rvm_asm(RVM_EADD, R0, R1, R2, 0);
+       VMTEST_REGL(vmcode, off, 0, -1, "8: EADD");
+       VMTEST_STATUS(vmcode, off, RVM_STATUS_N, "8: EADD STATUS");
+
+       vmcode[off++] = rvm_asmb(RVM_MOV, R1, DA, XX, 1);
+       vmcode[off++] = rvm_asmd(RVM_MOV, R2, DA, XX, -3.0);
+       vmcode[off++] = rvm_asm(RVM_EADD, R0, R1, R2, 0);
+       VMTEST_REGD(vmcode, off, 0, -2.0, "8: EADD");
+       VMTEST_STATUS(vmcode, off, RVM_STATUS_N, "8: EADD STATUS");
+
 
        vmcode[off++] = rvm_asm(RVM_EXT, R0, XX, XX, 0);
 #ifdef EXECDEBUG
index 41446ee..ff119ed 100644 (file)
@@ -20,38 +20,43 @@ int main(int argc, char *argv[])
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asmp(RVM_LDRR, R1, DA, XX, &d1s);
        vmcode[off++] = rvm_asm(RVM_ESUB, R0, R0, R1, 0);
-       VMTEST_REGP(vmcode, off, 0, &d2, "SUB");
-       VMTEST_STATUS(vmcode, off, 0, "SUB STATUS");
+       vmcode[off++] = rvm_asm(RVM_PRN, R0, XX, XX, 0);
+       VMTEST_REGD(vmcode, off, 0, 3.0, "1:ESUB");
+       VMTEST_STATUS(vmcode, off, 0, "1:ESUB STATUS");
 
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asmp(RVM_LDRR, R1, DA, XX, &d1s);
        vmcode[off++] = rvm_asm(RVM_ESUB, R0, R1, R0, 0);
-       VMTEST_REGP(vmcode, off, 0, &d3, "SUB");
-       VMTEST_STATUS(vmcode, off, 0, "SUB STATUS");
+       VMTEST_REGD(vmcode, off, 0, -3, "2:ESUB");
+       VMTEST_STATUS(vmcode, off, RVM_STATUS_N, "2:ESUB STATUS");
 
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asm(RVM_MOV, R1, DA, XX, 2);
        vmcode[off++] = rvm_asm(RVM_ESUB, R0, R1, R0, 0);
-       VMTEST_REG(vmcode, off, 0, 1, "SUB");
-       VMTEST_STATUS(vmcode, off, 0, "SUB STATUS");
+       vmcode[off++] = rvm_asm(RVM_PRN, R0, XX, XX, 0);
+       VMTEST_REG(vmcode, off, 0, 1, "3:ESUB");
+       VMTEST_STATUS(vmcode, off, RVM_STATUS_C, "3:ESUB STATUS");
 
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asmp(RVM_LDRR, R1, DA, XX, &d1);
        vmcode[off++] = rvm_asm(RVM_ESUB, R0, R1, R0, 0);
-       VMTEST_REGP(vmcode, off, 0, &d3, "SUB");
-       VMTEST_STATUS(vmcode, off, 0, "SUB STATUS");
+       vmcode[off++] = rvm_asm(RVM_PRN, R0, XX, XX, 0);
+       VMTEST_REGP(vmcode, off, 0, &d3, "4:ESUB");
+       VMTEST_STATUS(vmcode, off, RVM_STATUS_N|RVM_STATUS_C, "4:ESUB STATUS");
 
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asmp(RVM_LDRR, R1, DA, XX, &d1);
        vmcode[off++] = rvm_asm(RVM_ESUB, R0, R0, R1, 0);
-       VMTEST_REGP(vmcode, off, 0, &d2, "SUB");
-       VMTEST_STATUS(vmcode, off, 0, "SUB STATUS");
+       vmcode[off++] = rvm_asm(RVM_PRN, R0, XX, XX, 0);
+       VMTEST_REGP(vmcode, off, 0, &d2, "5:ESUB");
+       VMTEST_STATUS(vmcode, off, RVM_STATUS_C, "5:ESUB STATUS");
 
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 1);
        vmcode[off++] = rvm_asml(RVM_MOV, R1, DA, XX, 2);
        vmcode[off++] = rvm_asm(RVM_ESUB, R0, R1, R0, 0);
-       VMTEST_REGL(vmcode, off, 0, 1, "SUB");
-       VMTEST_STATUS(vmcode, off, 0, "SUB STATUS");
+       vmcode[off++] = rvm_asm(RVM_PRN, R0, XX, XX, 0);
+       VMTEST_REGL(vmcode, off, 0, 1, "6:ESUB");
+       VMTEST_STATUS(vmcode, off, RVM_STATUS_C, "6:ESUB STATUS");
 
        vmcode[off++] = rvm_asm(RVM_EXT, R0, XX, XX, 0);
 #ifdef EXECDEBUG
index ad2384b..f9cfc71 100644 (file)
@@ -45,12 +45,12 @@ int main(int argc, char *argv[])
        vmcode[off++] = rvm_asm(RVM_MOV, R1, DA, XX, 1);
        vmcode[off++] = rvm_asm(RVM_MOV, R2, DA, XX, 2);
        vmcode[off++] = rvm_asm(RVM_MOV, R5, DA, XX, 5);
-       vmcode[off++] = rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(0)|BIT(1)|BIT(2)|BIT(5));
+       vmcode[off++] = rvm_asm(RVM_PUSHM, DA, XX, XX, BIT(0)|BIT(1)|BIT(2)|BIT(5)|BIT(SP));
        vmcode[off++] = rvm_asm(RVM_MOV, R0, DA, XX, 0);
        vmcode[off++] = rvm_asm(RVM_MOV, R1, DA, XX, 0);
        vmcode[off++] = rvm_asm(RVM_MOV, R2, DA, XX, 0);
        vmcode[off++] = rvm_asm(RVM_MOV, R5, DA, XX, 0);
-       vmcode[off++] = rvm_asm(RVM_POPM, DA, XX, XX, BIT(0)|BIT(1)|BIT(2)|BIT(5));
+       vmcode[off++] = rvm_asm(RVM_POPM, DA, XX, XX, BIT(0)|BIT(1)|BIT(2)|BIT(5)|BIT(SP));
        VMTEST_REG(vmcode, off, 5, 5, "PUSHM/POPM");
        VMTEST_REG(vmcode, off, 1, 1, "PUSHM/POPM");
 
index da7787e..f91b46b 100644 (file)
@@ -8,7 +8,7 @@ LIBS =  -L$(ROBJECT_SRCDIR)/build/$(OS)/$(ARCHDIR)/out
 LIBS += -L$(RLIB_SRCDIR)/build/$(OS)/$(ARCHDIR)/out 
 LIBS += -L$(RVM_SRCDIR)/build/$(OS)/$(ARCHDIR)/out 
 LIBS += -L$(RPA_SRCDIR)/build/$(OS)/$(ARCHDIR)/out 
-LIBS += -lrvm -lrpa -lrpasx -lrlib -lpthread --static
+LIBS += -lrvm -lrpa -lrpasx -lrlib -lpthread -lm --static
 
 
 
@@ -21,6 +21,7 @@ TESTS   += $(OUTDIR)/opmap-test
 TESTS   += $(OUTDIR)/string-test
 TESTS   += $(OUTDIR)/rlock-test
 TESTS   += $(OUTDIR)/rarray-test
+TESTS   += $(OUTDIR)/rcarray-test
 TESTS   += $(OUTDIR)/rharray-test
 TESTS   += $(OUTDIR)/scope-test
 TESTS   += $(OUTDIR)/rhash-test
@@ -49,10 +50,20 @@ TESTS   += $(OUTDIR)/asm-eadd
 
 all : $(OUTDIR) $(TESTS)
 
+$(OUTDIR)/%.o: $(TESTS_SRCDIR)/%.c
+       + $(CC) $(CFLAGS) -c -o $(OUTDIR)/$*.o $(TESTS_SRCDIR)/$*.c $(INCLUDE)
+
+$(OUTDIR)/rpagen-test : $(OUTDIR)/ecma262.o $(OUTDIR)/rpagen-test.o
+       $(CC) $(CFLAGS)  -o $@ $^ $(LIBS)
+
 $(OUTDIR)/%: $(TESTS_SRCDIR)/%.c
        + $(CC) $(CFLAGS) -o $(OUTDIR)/$* $(TESTS_SRCDIR)/$*.c $(LIBS) $(INCLUDE)
 
 
+$(OUTDIR)/%.o: $(TESTS_SRCDIR)/%.rpa
+       $(LD) -r -b binary -o $(OUTDIR)/$*.o $(TESTS_SRCDIR)/$*.rpa
+
+
 $(OUTDIR):
        @mkdir $(OUTDIR)
 
index 567d3a9..4d68867 100644 (file)
@@ -8,33 +8,42 @@
 #define VMTEST_REG(code, index, reg, val, msg) \
        do { code[index++] = rvm_asm(RVM_MOV, R8, DA, XX, reg); \
                 code[index++] = rvm_asm(RVM_MOV, R9, DA, XX, val); \
+                code[index++] = rvm_asm(RVM_PRN, reg, XX, XX, 0); \
                 code[index++] = rvm_asmp(RVM_MOV, R10, DA, XX, msg); \
-                code[index++] = rvm_asm(RVM_OPSWI(rvm_cpu_getswi(vm, "rvm_vmtest_check_reg")), XX, XX, R0, 0); } while (0)
+                code[index++] = rvm_asm(RVM_OPSWI(rvm_cpu_getswi(vm, "rvm_vmtest_check_reg")), XX, XX, R0, 0); \
+                code[index++] = rvm_asm(RVM_NOP, XX, XX, XX, 0); } while (0)
 
 #define VMTEST_REGL(code, index, reg, val, msg) \
        do { code[index++] = rvm_asm(RVM_MOV, R8, DA, XX, reg); \
                 code[index++] = rvm_asml(RVM_MOV, R9, DA, XX, val); \
+                code[index++] = rvm_asm(RVM_PRN, reg, XX, XX, 0); \
                 code[index++] = rvm_asmp(RVM_MOV, R10, DA, XX, msg); \
-                code[index++] = rvm_asm(RVM_OPSWI(rvm_cpu_getswi(vm, "rvm_vmtest_check_reg")), XX, XX, R0, 0); } while (0)
+                code[index++] = rvm_asm(RVM_OPSWI(rvm_cpu_getswi(vm, "rvm_vmtest_check_reg")), XX, XX, R0, 0); \
+                code[index++] = rvm_asm(RVM_NOP, XX, XX, XX, 0); } while (0)
 
 #define VMTEST_REGD(code, index, reg, val, msg) \
        do { code[index++] = rvm_asm(RVM_MOV, R8, DA, XX, reg); \
                 code[index++] = rvm_asmd(RVM_MOV, R9, DA, XX, val); \
+                code[index++] = rvm_asm(RVM_PRN, reg, XX, XX, 0); \
                 code[index++] = rvm_asmp(RVM_MOV, R10, DA, XX, msg); \
-                code[index++] = rvm_asm(RVM_OPSWI(rvm_cpu_getswi(vm, "rvm_vmtest_check_reg")), XX, XX, R0, 0); } while (0)
+                code[index++] = rvm_asm(RVM_OPSWI(rvm_cpu_getswi(vm, "rvm_vmtest_check_reg")), XX, XX, R0, 0); \
+                code[index++] = rvm_asm(RVM_NOP, XX, XX, XX, 0); } while (0)
 
 
 #define VMTEST_REGP(code, index, reg, pval, msg) \
        do { code[index++] = rvm_asm(RVM_MOV, R8, DA, XX, reg); \
                 code[index++] = rvm_asmp(RVM_LDRR, R9, DA, XX, pval); \
+                code[index++] = rvm_asm(RVM_PRN, R9, XX, XX, 0); \
                 code[index++] = rvm_asmp(RVM_MOV, R10, DA, XX, msg); \
-                code[index++] = rvm_asm(RVM_OPSWI(rvm_cpu_getswi(vm, "rvm_vmtest_check_reg")), XX, XX, R0, 0); } while (0)
+                code[index++] = rvm_asm(RVM_OPSWI(rvm_cpu_getswi(vm, "rvm_vmtest_check_reg")), XX, XX, R0, 0); \
+                code[index++] = rvm_asm(RVM_NOP, XX, XX, XX, 0); } while (0)
 
 
 #define VMTEST_STATUS(code, index, val, msg) \
        do { code[index++] = rvm_asm(RVM_MOV, R9, DA, XX, val); \
                 code[index++] = rvm_asmp(RVM_MOV, R10, DA, XX, msg); \
-                code[index++] = rvm_asm(RVM_OPSWI(rvm_cpu_getswi(vm, "rvm_vmtest_check_status")), XX, XX, R0, 0); } while (0)
+                code[index++] = rvm_asm(RVM_OPSWI(rvm_cpu_getswi(vm, "rvm_vmtest_check_status")), XX, XX, R0, 0); \
+                code[index++] = rvm_asm(RVM_NOP, XX, XX, XX, 0); } while (0)
 
 
 /*
diff --git a/tests/ecma262.rpa b/tests/ecma262.rpa
new file mode 100644 (file)
index 0000000..cc7b40b
--- /dev/null
@@ -0,0 +1,368 @@
+# Temporary staff
+NewKeyword                             ::= 'new'
+ArrayKeyword                   ::= 'Array'
+NewArrayNoSize                 ::= <S>? <:NewKeyword:> <S> <:ArrayKeyword:> <S>? '(' <S>? ')'
+NewArraySize                   ::= <S>? <:NewKeyword:> <S> <:ArrayKeyword:> <S>? '(' <S>? <:AssignmentExpression:> <S>? ')'
+NewArrayExpression             ::= <:NewArraySize:> | <:NewArrayNoSize:>
+
+# 6 Source Text
+SourceCharacter                ::= .
+
+# 7.2 White space
+WhiteSpace                             ::= [#0x0009] | [#0x000B] | [#0x000C] | [#0x0020] | [#0x00A0] | [#0xFEFF]
+
+# 7.3 Line Terminators
+LineTerminator                 ::= [#0x000D] [#0x000A] | [#0x000A] | [#0x000D] | [#0x2028] | [#0x2029]
+LineTerminatorSequence ::= [#0x000D] [#0x000A] | [#0x000A] | [#0x000D] | [#0x2028] | [#0x2029]
+S                                              ::= ( <WhiteSpace> | <LineTerminator> )+
+SC                                             ::= <S>? ';' <S>?
+COMMA                                  ::= <S>? ',' <S>?
+EQ                                             ::= <S>? '=' <S>?
+
+# 7.4 Comments
+Comment                                ::= <:MultiLineComment:> | <:SingleLineComment:>
+MultiLineComment               ::= '/*' <:MultiLineCommentChar:>* '*/'
+MultiLineCommentChar   ::= . - '*/'
+SingleLineComment              ::= '#' <:SingleLineCommentChar:>*
+SingleLineCommentChar  ::= <:SourceCharacter:> - <:LineTerminator:>
+
+# 7.5 Tokens
+Token                                  ::= <:IdentifierName:> |
+                                               <:Punctuator:> |
+                                               <:NumericLiteral:> |
+                                               <:StringLiteral:>
+
+# 7.6 Identifier Names and Identifiers
+
+Identifier                             ::= <IdentifierName> - <ReservedWord> - <ReservedWord> <IdentifierPart>
+IdentifierName                 ::= <IdentifierStart> <IdentifierPart>*
+IdentifierStart                ::= <UnicodeLetter> | '$' | '_' | '\' <:UnicodeEscapeSequence:>
+UnicodeLetter                  ::= <Lu> |
+                       <Ll> |
+                       <Lt> |
+                       <Lm> |
+                       <Lo> |
+                       <Nl>
+
+Lu                                             ::= [#0x0041-#0x005A] | [#0x00C0-#0x00DE] | [#0x0100-#0x0232]   # TBD
+Ll                                             ::= [#0x0061-#0x007A] | [#0x00C0-#0x00DE]                                               # TBD
+IdentifierPart                 ::= <IdentifierStart> | 
+                                                       <:UnicodeCombiningMark:> |
+                                                       <:UnicodeDigit:> | 
+                                                       <:UnicodeConnectorPunctuation:>                                                         # TBD
+UnicodeDigit           ::= [0-9] | [#0x0660-#0x0669]                                   # TBD
+
+ReservedWord                   ::= <:Keyword:>
+                                                       <:FutureReservedWord:> |
+                                                       <:NullLiteral:> |
+                                                       <:BooleanLiteral:>
+
+Keyword                                ::= 'instanceof' | 'typeof'     | 'break' | 
+                                               'do' | 'new' | 'var' |
+                                               'case' | 'else' | 'return' | 'void' | 
+                                               'catch' | 'finally' | 'continue' | 'for' | 
+                                               'switch' | 'while' | 'this' | 'with' | 
+                                               'debugger' | 'function' | 'throw' | 'default' |  
+                                               'if' | 'try' | 'delete' | 'in'
+
+FutureReservedWord                     ::= 'class' | 'enum' | 'extends' | 'import' | 'const' | 'export' |
+                                                       'implements' | 'let' | 'private' | 'public' |
+                               'static' | 'interface' | 'package' | 'protected'
+
+NullLiteral                            ::= 'null'
+BooleanLiteral                         ::= 'true' | 'false'
+Literal                                        ::= <:NullLiteral:> |
+                                                       <:BooleanLiteral:> |
+                                                       <:NumericLiteral:> |
+                                                       <:StringLiteral:> |
+                                                       <:RegularExpressionLiteral:>
+
+# 7.8.3 Numeric Literals
+
+NumericLiteral                                 ::= <:HexIntegerLiteral:> | <:DecimalNonIntegerLiteral:> | <:DecimalIntegerLiteral:>
+DecimalNonIntegerLiteral               ::= ('0' | <:NonZeroDigit:> <DecimalDigits>?) '.' <DecimalDigits>? <:ExponentPart:>? |
+                                                               '.' <:DecimalDigits:> <:ExponentPart:>? 
+DecimalIntegerLiteral                  ::= '0' | <:NonZeroDigit:> <:DecimalDigits:>? <:ExponentPart:>?
+DecimalDigits                                  ::= <:DecimalDigit:>+
+DecimalDigit                                   ::= [0-9]
+NonZeroDigit                                   ::= [1-9]
+ExponentPart                                   ::= <:ExponentIndicator:> <:SignedInteger:>
+ExponentIndicator                              ::= [eE]
+SignedInteger                                  ::= '-' <:DecimalDigits:> |
+                                                               '+' <:DecimalDigits:> |
+                                                               <:DecimalDigits:>
+HexIntegerLiteral                              ::= '0' [xX] <:HexDigit:>+
+HexDigit                                               ::= [0-9a-fA-F]
+
+# 7.8.4 String Literals
+StringLiteral                                  ::= '\"' <:DoubleStringCharacters:>? '\"' |
+                                                               ['] <:SingleStringCharacters:>? [']
+
+DoubleStringCharacters                 ::= <:DoubleStringCharacter:>+
+SingleStringCharacters                 ::= <:SingleStringCharacter:>+
+
+DoubleStringCharacter                  ::= '\\' <:EscapeSequence:> |
+                                                               <:LineContinuation:> |
+                                                               <:SourceCharacter:> - ('\"' | '\\' | <:LineTerminator:>)
+
+SingleStringCharacter                  ::= '\\' <:EscapeSequence:> |
+                                                               <:LineContinuation:> |
+                                                               <:SourceCharacter:> - (['] | '\\' | <:LineTerminator:>)
+
+PrimaryExpression                              ::= 'this' | 
+                                                               '(' <S>? <:Expression:> <S>? ')' |
+                                                               <:IdentifierOp:> |
+                                                               <:Literal:>
+
+# The next line is mine
+IdentifierOp                                   ::= <:Identifier:> 
+
+
+ArrayLiteral                                   ::= '[' <S>? <:Elision:>? <S>? ']' |
+                                                               '[' <S>? <:ElementList:> <S>? ']' |
+                                                               '[' <S>? <:ElementList:> <S>? ',' <S>? <:Elision:> <S>? ']'
+ElementList                                    ::= <:Elision:>? <S>? <:AssignmentExpression:> (<S>? ',' <S>? <:Elision:>? <S>? <:AssignmentExpression:> )*
+Elision                                                ::= ',' <S>? <:Elision:> | <S>? ','
+
+#ArrayElementValue                             ::= <:IdentifierValue:> <:S:>? <:ArrayLiteral:>
+#term                                                  ::= <:Literal:> | 
+#                                                                      <:ArrayElementValue:> | 
+#                                                              '(' <S>? <:Expression:> <S>? ')' |
+#                                                              <:IdentifierValue:> 
+
+
+# 11.2 Left-Hand-Side Expressions
+NewKeyword                                             ::= 'new' - 'new' <IdentifierPart>
+
+MemberExpressionIndexBaseOp            ::= <:MemberExpression:>
+MemberExpressionIndexOp                        ::= <:MemberExpressionIndexBaseOp:> <S>? '[' <:S:>? <:AssignmentExpression:> <:S:>? ']'
+MemberExpression                               ::= <:MemberExpressionIndexOp:>  |
+                                                                       <:MemberExpression:> '.' <:IdentifierName:> |
+                                                                       <:NewKeyword:> <S>? <:MemberExpression:> <S>? <:Arguments:> |
+                                                                       <:FunctionExpression:> |
+                                                                       <:PrimaryExpression:>
+
+
+NewExpression                                  ::= <:NewArrayExpression:> |
+                                                                       <:NewKeyword:> <S>? <:NewExpression:> |
+                                                                       <:MemberExpression:>
+
+
+FunctionCallName                               ::= <:CallExpression:> | <:MemberExpression:>
+CallExpressionOp                               ::= <:FunctionCallName:> <S>? <:Arguments:>
+CallExpressionIndexBaseOp              ::= <:CallExpression:>
+CallExpressionIndexOp                  ::= <:CallExpressionIndexBaseOp:> <S>? '[' <S>? <:AssignmentExpression:> <S>? ']'
+
+CallExpression                                 ::= <:CallExpressionIndexOp:> |
+                                                                       <:CallExpression:> '.' <:IdentifierName:> |
+                                                                       <:CallExpressionOp:>
+
+Arguments                                              ::= '(' <S>? ')' |
+                                                               '(' <S>? <:ArgumentList:> <S>? ')'
+ArgumentList                                   ::= <:ArgumentList:> <S>? ',' <S>? <:AssignmentExpression:> |
+                                                                       <:AssignmentExpression:>
+LeftHandSideExpression                 ::= <:CallExpression:> | <:NewExpression:>
+
+# The next lines are mine
+LeftHandSideExpressionDeref            ::= <:LeftHandSideExpression:>
+LeftHandSideExpressionValue            ::= <:NewArrayExpression:> |
+                                                                       <:LeftHandSideExpressionDeref:> |
+                                                                       <:Literal:>
+ArgumentList                                   ::= <:ArgumentList:> <S>? ',' <S>? <:FunctionCallParameter:> |
+                                                                       <:FunctionCallParameter:>
+FunctionCallParameter                  ::= <:AssignmentExpression:>
+
+
+
+# 11.3 Postfix Expressions
+# RULE: LeftHandSideExpression always ends up in R0 (Let see if this would work)
+PostfixOperator                ::= '++' | '--'
+PostfixExpressionOp    ::= <:LeftHandSideExpression:> <:PostfixOperator:>
+PostfixExpression              ::= <:PostfixExpressionOp:> |
+                                                       <:LeftHandSideExpression:>
+
+# 11.4 Unary Operators
+UnaryOperator              ::= 'delete' | 'void' | 'typeof' | '++' | '--' | '+' | '-' | '~' | '!'
+UnaryExpressionOp          ::= <S>? <:UnaryOperator:> <S>? <:UnaryExpression:>
+UnaryExpression                    ::= <:UnaryExpressionOp:> | <:PostfixExpression:>
+
+
+# 11.5 Multiplicative Operators
+MultiplicativeOperator                 ::= '*' | '/' | '%' # Not used
+MultiplicativeExpressionOp             ::= <:MultiplicativeExpression:> <S>? <:MultiplicativeOperator:> <S>? <:UnaryExpression:>
+MultiplicativeExpression               ::= <:MultiplicativeExpressionOp:> | 
+                                                                       <:UnaryExpression:>
+
+# 11.6 Additive Operators
+AdditiveOperator                               ::= '+' | '-'
+AdditiveExpressionOp                   ::= <:AdditiveExpression:> <S>? <:AdditiveOperator:> <S>? <:MultiplicativeExpression:>
+AdditiveExpression                             ::= <:AdditiveExpressionOp:> | 
+                                                                       <:MultiplicativeExpression:>
+
+
+11.7 Bitwise Shift Operators
+ShiftOperator                                  ::= '>>>' | '<<' | '>>'
+ShiftExpressionOp                              ::= <:ShiftExpression:> <S>? <:ShiftOperator:> <S>? <:AdditiveExpression:>
+ShiftExpression                                ::= <:ShiftExpressionOp:> |
+                                                               <:AdditiveExpression:> 
+
+
+# 11.8 Relational Operators
+RelationalOperator                             ::= '<=' | '>=' | '<' | '>' | 'instanceof'
+RelationalExpressionOp                 ::= <:RelationalExpression:> <S>? <:RelationalOperator:> <S>? <:ShiftExpression:>
+RelationalExpression                   ::= <:RelationalExpressionOp:> |
+                                                               <:ShiftExpression:>
+
+# 11.9 Equality Operators
+EqualityOperator                               ::= '===' | '==' | '!==' | '!='
+EqualityExpressionOp                   ::= <:EqualityExpression:> <S>? <:EqualityOperator:> <S>? <:RelationalExpression:> 
+EqualityExpression                     ::= <:EqualityExpressionOp:> |
+                                                               <:RelationalExpression:>
+
+BitwiseANDOperator                     ::= '&' - '&&'
+BitwiseANDOp                                   ::= <:BitwiseANDExpression:> <S>? <:BitwiseANDOperator:> <S>? <:EqualityExpression:>
+BitwiseANDExpression                   ::= <:BitwiseANDOp:> |
+                                                               <:EqualityExpression:>
+
+BitwiseXOROperator                     ::= '^'
+BitwiseXOROp                                   ::= <:BitwiseXORExpression:> <S>? <:BitwiseXOROperator:> <S>? <:BitwiseANDExpression:>
+BitwiseXORExpression                   ::= <:BitwiseXOROp:> |
+                                                               <:BitwiseANDExpression:>
+
+BitwiseOROperator                              ::= '|' - '||'
+BitwiseOROp                                    ::= <:BitwiseORExpression:> <S>? <:BitwiseOROperator:> <S>? <:BitwiseXORExpression:>
+BitwiseORExpression                    ::= <:BitwiseOROp:> |
+                                                               <:BitwiseXORExpression:>
+
+# 11.11 Binary Logical Operators
+LogicalANDOperator                     ::= '&&'
+LogicalANDOp                                   ::= <:LogicalANDExpression:> <S>? <:LogicalANDOperator:>  <S>? <:BitwiseORExpression:>
+LogicalANDExpression                   ::= <:LogicalANDOp:> |
+                                                               <:BitwiseORExpression:>
+
+LogicalOROperator                              ::= '||'
+LogicalOROp                                            ::= <:LogicalORExpression:> <S>? <:LogicalOROperator:> <S>? <:LogicalANDExpression:>
+LogicalORExpression                    ::= <:LogicalOROp:> |
+                                                               <:LogicalANDExpression:>
+
+#Expression                                            ::= <:LogicalORExpression:>
+
+
+# 12.6 Iteration Statements
+WhileKeyword                                           ::= 'while'
+WhileExpression                                        ::= <:WhileKeyword:> <S>? '(' <S>? <:ValueOfExpression:> <S>? ')'
+IterationWhile                                         ::= <:WhileKeyword:> '(' <S>? <:Expression:> <S>? ')' <S>? <:Statement:>
+DoKeyword                                                      ::= 'do'
+IterationDo                                            ::= <:DoKeyword:> <S>? <:Statement:> <S>? <:WhileExpression:> (<S>? ';')
+IterationStatement                             ::= <:IterationWhile:> |
+                                                                       <:IterationDo:>
+
+
+## 11.12 Conditional Operator ( ? : )
+#ConditionalExpression                         ::= <:LogicalORExpression:> ( <S>? '?' <S>? <:AssignmentExpression:> <S>? ':' <S>? <:AssignmentExpression:> )?
+#ValueOfExpression                             ::= <:NewArrayExpression:> |
+#                                                                      <:Expression:>
+## 11.13 Assignment Operators
+#ArrayElementAddress                   ::= <:IdentifierValue:> <:S:>? <:ArrayLiteral:>
+#IdentifierAddress                             ::= <:Identifier:>
+#Address                                               ::= <:ArrayElementAddress:> | <:IdentifierAddress:>
+#IdentifierValue                               ::= <:Identifier:>
+#AssignmetLHS                                  ::= <:LeftHandSideExpression:>
+#AssignmentEq                                  ::= <:AssignmetLHS:> <:S:>? '=' <:S:>? <:AssignmentExpression:> 
+#AssignmentAddEq                               ::= <:AssignmetLHS:> <:S:>? '+=' <:S:>? <:AssignmentExpression:> 
+#AssignmentMulEq                               ::= <:AssignmetLHS:> <:S:>? '*=' <:S:>? <:AssignmentExpression:> 
+#
+#AssignmentExpression                  ::= <:AssignmentEq:> | 
+#                                                                      <:AssignmentAddEq:> | 
+#                                                                      <:AssignmentMulEq:> | 
+#                                                                      <:CallExpression:> |
+#                                                                      <:ValueOfExpression:>
+
+
+# 11.12 Conditional Operator ( ? : )
+#ConditionalExpression         ::= <:LogicalORExpression:> ( <S>? '?' <S>? <:AssignmentExpression:> <S>? ':' <S>? <:AssignmentExpression:> )?
+#ConditionalExpressionNoIn::=<:LogicalORExpressionNoIn:> ( <S>? '?' <S>? <:AssignmentExpression:> <S>? ':' <S>? <:AssignmentExpressionNoIn:> )?
+#
+ConditionalExpression  ::= <:LogicalORExpression:>
+
+# 11.13 Assignment Operators
+LeftHandSideExpressionPush             ::= <:LeftHandSideExpression:>
+AssignmentExpressionOp                         ::= <:LeftHandSideExpressionPush:> <S>? <:AssignmentOperator:> <S>? <:AssignmentExpression:>
+AssignmentExpression                   ::= <:AssignmentExpressionOp:> | <:ConditionalExpression:>
+
+AssignmentExpressionNoIn::= <:LeftHandSideExpression:> <S>? <:AssignmentOperator:> <S>? <:AssignmentExpressionNoIn:> | <:ConditionalExpressionNoIn:>
+AssignmentOperator     ::= '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '>>>=' | '&=' | '^=' | '|='
+
+
+# 11.14 Comma Operator         ( , )
+Expression             ::= <:AssignmentExpression:> ( <S>? ',' <S>? <:AssignmentExpression:> )*
+ExpressionNoIn         ::= <:AssignmentExpressionNoIn:> ( <S>? ',' <S>? <:AssignmentExpressionNoIn:> )*
+
+
+
+
+# 12.3 Empty Statement
+EmptyStatement                                 ::= <:SC:>
+
+# 12.4 Expression Statement
+#ExpressionStatement                   ::= (<:Expression:> - ('function' | '{')) (<S>? ';')
+ExpressionStatement                    ::= <:AssignmentExpression:> <:SC:>
+
+# 12 Statements
+Statement                                              ::= <:Block:> |
+                                                               <:Comment:> |
+                                                               <:VariableStatement:> |
+                                                               <:EmptyStatement:> |
+                                                               <:ExpressionStatement:> |
+                                                               <:IfStatement:> |
+                                                               <:IterationStatement:> |
+                                                               <:ContinueStatement:> |
+                                                               <:BreakStatement:> |
+                                                               <:ReturnStatement:> |
+                                                               <:ImportStatement:> |
+                                                               <:WithStatement:> |
+                                                               <:LabelledStatement:> |
+                                                               <:SwitchStatement:> |
+                                                               <:ThrowStatement:> |
+                                                               <:TryStatement:> |
+                                                               <:DebuggerStatement:>
+
+# 12.1 Block
+BlockBegin                                                     ::= <S>? '{' <S>?
+BlockEnd                                                       ::= <S>? '}' <S>?
+Block                                                          ::= <:BlockBegin:> <:StatementList:>? <:BlockEnd:>
+StatementList                                          ::= (<S>? <:Statement:>)+
+
+# 12.2 Variable Statement
+VariableStatement                                      ::= 'var' <S>? <:VariableDeclarationList:> <:SC:>
+VariableDeclarationList                        ::= <:VariableDeclaration:> (<:COMMA:> <:VariableDeclaration:> )*
+VariableAllocate                                       ::= <:Identifier:>
+VariableAllocateAndInit                                ::= <:Identifier:>
+VariableDeclaration                                    ::= <:VariableAllocateAndInit:> <:Initialiser:> | <:VariableAllocate:>
+Initialiser                                                    ::= <:EQ:> <:AssignmentExpression:>
+
+# 12.9 The return Statement
+ReturnOp                                               ::= ('return' - 'return' <:IdentifierPart:>) <WhiteSpace>* <:AssignmentExpression:>? (<S>? ';')
+ReturnStatement                                        ::= <:ReturnOp:>
+
+
+# 13 Function Definition
+FunctionName                                           ::= <:Identifier:>
+FunctionDefinition                                     ::= ('function' - 'function' <IdentifierPart>)<S>?<:FunctionName:><S>?'('<S>?<:FormalParameterList:>?<S>?')'
+FunctionDeclaration                                    ::= <:FunctionDefinition:><S>?'{'<S>?<:FunctionBody:>?<S>?'}'
+FunctionExpression                                     ::= ('function' - 'function'<IdentifierPart>)<S>?<:FunctionName:>?<S>?'('<S>?<:FormalParameterList:>?<S>?')'<S>?'{'<S>?<:FunctionBody:>?<S>?'}'
+FunctionParameter                                      ::= <:Identifier:>
+FormalParameterList                            ::= <:FunctionParameter:> ( <S>? ',' <S>? <:FunctionParameter:> )*
+FunctionBody                                           ::= <:SourceElements:>
+
+
+# 14 Program
+SourceElements                                         ::= (<S>? <:SourceElement:>)+
+SourceElement                                          ::= <:FunctionDeclaration:> |
+                                                                       <:Statement:>
+Program                                                        ::= <:SourceElements:>
+ProgramInit                                            ::= <:SourceCharacter:>
+# The root rule, it is anonymous
+<:Program:>
+       
+
diff --git a/tests/ecma262org.rpa b/tests/ecma262org.rpa
new file mode 100644 (file)
index 0000000..3d30ffb
--- /dev/null
@@ -0,0 +1,443 @@
+# 6 Source Text
+SourceCharacter                ::= .
+
+# 7.2 White space
+WhiteSpace             ::= [#0x0009] | [#0x000B] | [#0x000C] | [#0x0020] | [#0x00A0] | [#0xFEFF]
+
+# 7.3 Line Terminators
+LineTerminator         ::= [#0x000D] [#0x000A] | [#0x000A] | [#0x000D] | [#0x2028] | [#0x2029]
+LineTerminatorSequence ::= [#0x000D] [#0x000A] |
+                           [#0x000A] | 
+                           [#0x000D] | 
+                           [#0x2028] | 
+                           [#0x2029]
+
+S                      ::= ( <WhiteSpace> | <LineTerminator> )+
+
+# 7.4 Comments
+Comment                        ::= <:MultiLineComment:> | <:SingleLineComment:>
+MultiLineComm