[Mono-list] jit patch: array support
Dietmar Maurer
dietmar@ximian.com
09 Nov 2001 11:25:03 +0100
Index: mono/jit/ChangeLog
===================================================================
RCS file: /cvs/public/mono/mono/jit/ChangeLog,v
retrieving revision 1.37
diff -u -r1.37 ChangeLog
--- mono/jit/ChangeLog 2001/11/08 21:38:32 1.37
+++ mono/jit/ChangeLog 2001/11/09 06:26:26
@@ -1,3 +1,14 @@
+2001-11-09 Dietmar Maurer <dietmar@ximian.com>
+
+ * testjit.c (mono_analyze_stack): finished array support
+
+2001-11-08 Dietmar Maurer <dietmar@ximian.com>
+
+ * testjit.c (MAKE_STELEM, MAKE_LDELEM): we build a tree which
+ represents the address of the element. This way we can emit highly
+ optimized x86 instructions to access ellements (using base+index+offset
+ adressing mode)
+
2001-11-07 Miguel de Icaza <miguel@ximian.com>
* mempool.c: Include string.h to kill warning.
Index: mono/jit/emit-x86.c
===================================================================
RCS file: /cvs/public/mono/mono/jit/emit-x86.c,v
retrieving revision 1.15
diff -u -r1.15 emit-x86.c
--- mono/jit/emit-x86.c 2001/11/08 21:38:32 1.15
+++ mono/jit/emit-x86.c 2001/11/09 06:26:27
@@ -37,7 +37,7 @@
if (method->signature->hasthis) {
o = *((MonoObject **)ebp);
class = o->klass;
- printf ("%p[%s.%s], ", o, class->name_space, class->name);
+ printf ("this:%p[%s.%s], ", o, class->name_space, class->name);
ebp += sizeof (gpointer);
}
@@ -431,8 +431,11 @@
break;
}
+ //printf ("RALLOC START %d %p %d\n", tree->op, rs->free_mask, goal);
+
for (i = 0; nts [i]; i++)
- tree_allocate_regs (kids [i], nts [i], rs);
+ if (kids [i] != tree) /* don't allocate regs for chain rules */
+ tree_allocate_regs (kids [i], nts [i], rs);
for (i = 0; nts [i]; i++) {
if (kids [i] != tree) { /* we do not free register for chain rules */
@@ -448,7 +451,6 @@
g_warning ("register allocation failed %d 0x%08x 0x%08x\n", tree->reg1, rs->free_mask, tree->exclude_mask);
g_assert_not_reached ();
}
-
break;
case MB_NTERM_lreg:
@@ -464,15 +466,17 @@
case MB_NTERM_freg:
/* fixme: allocate floating point registers */
break;
-
- /*
+
case MB_NTERM_addr:
if (tree->op == MB_TERM_ADD) {
tree->reg1 = mono_regset_alloc_reg (rs, tree->left->reg1, tree->exclude_mask);
tree->reg2 = mono_regset_alloc_reg (rs, tree->right->reg1, tree->exclude_mask);
}
+ if (tree->op == MB_TERM_CALL_I4) {
+ tree->reg1 = mono_regset_alloc_reg (rs, tree->left->reg1, tree->exclude_mask);
+ }
break;
- */
+
case MB_NTERM_base:
if (tree->op == MB_TERM_ADD) {
tree->reg1 = mono_regset_alloc_reg (rs, tree->left->reg1, tree->exclude_mask);
@@ -490,6 +494,7 @@
/* do nothing */
}
+ //printf ("RALLOC END %d %p\n", tree->op, rs->free_mask);
tree->emit = mono_burg_func [ern];
}
@@ -507,6 +512,7 @@
//printf ("AREGSTART %d:%d %p\n", i, j, cfg->rs->free_mask);
tree_allocate_regs (t1, 1, cfg->rs);
//printf ("AREGENDT %d:%d %p\n", i, j, cfg->rs->free_mask);
+ g_assert (cfg->rs->free_mask == 0xffffffff);
}
}
}
@@ -610,7 +616,6 @@
g_assert (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL));
//g_assert (!method->addr);
-
printf ("Start JIT compilation %p %p\n", method, method->addr);
printf ("Start JIT compilation of %s.%s:%s\n", method->klass->name_space,
method->klass->name, method->name);
Index: mono/jit/testjit.c
===================================================================
RCS file: /cvs/public/mono/mono/jit/testjit.c,v
retrieving revision 1.39
diff -u -r1.39 testjit.c
--- mono/jit/testjit.c 2001/11/08 21:38:32 1.39
+++ mono/jit/testjit.c 2001/11/09 06:26:27
@@ -10,6 +10,7 @@
#include <config.h>
#include <glib.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <string.h>
#include <mono/metadata/assembly.h>
@@ -91,8 +92,13 @@
case CEE_##name: { \
++ip; \
sp -= 2; \
- t1 = mono_ctree_new (mp, MB_TERM_LDELEMA, sp [0], sp [1]); \
- t1->data.i = s; \
+ t1 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4); \
+ t1->data.i = s; \
+ t1 = mono_ctree_new (mp, MB_TERM_MUL, sp [1], t1); \
+ t2 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4); \
+ t2->data.i = G_STRUCT_OFFSET (MonoArray, vector); \
+ t2 = mono_ctree_new (mp, MB_TERM_ADD, sp [0], t2); \
+ t1 = mono_ctree_new (mp, MB_TERM_ADD, t1, t2); \
t1 = mono_ctree_new (mp, op, t1, NULL); \
PUSH_TREE (t1, svt); \
break; \
@@ -106,7 +112,8 @@
ADD_TREE (t1); \
break; \
}
-
+
+/*
#define MAKE_STELEM(name, op, s) \
case CEE_##name: { \
++ip; \
@@ -117,6 +124,23 @@
ADD_TREE (t1); \
break; \
}
+*/
+
+#define MAKE_STELEM(name, op, s) \
+case CEE_##name: { \
+ ++ip; \
+ sp -= 3; \
+ t1 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4); \
+ t1->data.i = s; \
+ t1 = mono_ctree_new (mp, MB_TERM_MUL, sp [1], t1); \
+ t2 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4); \
+ t2->data.i = G_STRUCT_OFFSET (MonoArray, vector); \
+ t2 = mono_ctree_new (mp, MB_TERM_ADD, sp [0], t2); \
+ t1 = mono_ctree_new (mp, MB_TERM_ADD, t1, t2); \
+ t1 = mono_ctree_new (mp, op, t1, sp [2]); \
+ ADD_TREE (t1); \
+ break; \
+}
/* Whether to dump the assembly code after genreating it */
gboolean mono_jit_dump_asm = FALSE;
@@ -142,6 +166,24 @@
return g_malloc0 (size);
}
+static int
+map_store_svt_type (int svt)
+{
+ switch (svt) {
+ case VAL_I32:
+ case VAL_POINTER:
+ return MB_TERM_STIND_I4;
+ case VAL_I64:
+ return MB_TERM_STIND_I8;
+ case VAL_DOUBLE:
+ return MB_TERM_STIND_R8;
+ default:
+ g_assert_not_reached ();
+ }
+
+ return 0;
+}
+
/**
* map_stind_type:
* @type: the type to map
@@ -172,6 +214,7 @@
case MONO_TYPE_STRING:
case MONO_TYPE_PTR:
case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
return MB_TERM_STIND_I4;
case MONO_TYPE_I8:
case MONO_TYPE_U8:
@@ -244,6 +287,7 @@
case MONO_TYPE_STRING:
case MONO_TYPE_PTR:
case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_ARRAY:
*svt = VAL_POINTER;
return MB_TERM_LDIND_U4;
case MONO_TYPE_I8:
@@ -525,6 +569,7 @@
t->svt = VAL_POINTER;
return t;
default:
+ g_warning ("unknown tree opcode %d", s->op);
g_assert_not_reached ();
}
@@ -542,38 +587,38 @@
case MB_TERM_STIND_I1:
case MB_TERM_LDIND_I1:
t = ctree_dup_address (mp, s->left);
- t->svt = VAL_I32;
t = mono_ctree_new (mp, MB_TERM_LDIND_I1, t, NULL);
+ t->svt = VAL_I32;
break;
case MB_TERM_STIND_I2:
case MB_TERM_LDIND_I2:
t = ctree_dup_address (mp, s->left);
- t->svt = VAL_I32;
t = mono_ctree_new (mp, MB_TERM_LDIND_I2, t, NULL);
+ t->svt = VAL_I32;
break;
case MB_TERM_STIND_I4:
case MB_TERM_LDIND_I4:
t = ctree_dup_address (mp, s->left);
- t->svt = VAL_I32;
t = mono_ctree_new (mp, MB_TERM_LDIND_I4, t, NULL);
+ t->svt = VAL_I32;
break;
case MB_TERM_STIND_I8:
case MB_TERM_LDIND_I8:
t = ctree_dup_address (mp, s->left);
- t->svt = VAL_I64;
t = mono_ctree_new (mp, MB_TERM_LDIND_I8, t, NULL);
+ t->svt = VAL_I64;
break;
case MB_TERM_STIND_R4:
case MB_TERM_LDIND_R4:
t = ctree_dup_address (mp, s->left);
- t->svt = VAL_DOUBLE;
t = mono_ctree_new (mp, MB_TERM_LDIND_R4, t, NULL);
+ t->svt = VAL_DOUBLE;
break;
case MB_TERM_STIND_R8:
case MB_TERM_LDIND_R8:
t = ctree_dup_address (mp, s->left);
- t->svt = VAL_DOUBLE;
t = mono_ctree_new (mp, MB_TERM_LDIND_R8, t, NULL);
+ t->svt = VAL_DOUBLE;
break;
default: {
g_assert (s->svt != VAL_UNKNOWN);
@@ -589,20 +634,8 @@
t = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
t->data.i = vnum;
- switch (s->svt) {
- case VAL_I32:
- case VAL_POINTER:
- t = mono_ctree_new (mp, MB_TERM_STIND_I4, t, s);
- break;
- case VAL_I64:
- t = mono_ctree_new (mp, MB_TERM_STIND_I8, t, s);
- break;
- case VAL_DOUBLE:
- t = mono_ctree_new (mp, MB_TERM_STIND_R8, t, s);
- break;
- default:
- g_assert_not_reached ();
- }
+ t = mono_ctree_new (mp, map_store_svt_type (s->svt), t, s);
+ t->svt = s->svt;
}
}
@@ -1055,6 +1088,70 @@
return NULL;
}
+/**
+ * ves_array_element_address:
+ * @this: a pointer to the array object
+ *
+ * Returns: the address of an array element.
+ */
+static gpointer
+ves_array_element_address (MonoArray *this, ...)
+{
+ MonoClass *class;
+ va_list ap;
+ int i, ind, esize;
+ gpointer ea;
+
+ g_assert (this != NULL);
+
+ va_start(ap, this);
+
+ class = this->obj.klass;
+
+ ind = va_arg(ap, int) - this->bounds [0].lower_bound;
+ for (i = 1; i < class->rank; i++) {
+ ind = ind*this->bounds [i].length + va_arg(ap, int) -
+ this->bounds [i].lower_bound;;
+ }
+
+ esize = mono_array_element_size (class);
+ ea = (gpointer*)((char*)this->vector + (ind * esize));
+
+ va_end(ap);
+
+ return ea;
+}
+
+static MonoArray *
+mono_array_new_va (MonoMethod *cm, ...)
+{
+ va_list ap;
+ guint32 *lengths;
+ guint32 *lower_bounds;
+ int pcount = cm->signature->param_count;
+ int rank = cm->klass->rank;
+ int i, d;
+
+ va_start (ap, cm);
+
+ lengths = alloca (sizeof (guint32) * pcount);
+ for (i = 0; i < pcount; ++i)
+ lengths [i] = d = va_arg(ap, int);
+
+ if (rank == pcount) {
+ /* Only lengths provided. */
+ lower_bounds = NULL;
+ } else {
+ g_assert (pcount == (rank * 2));
+ /* lower bounds are first. */
+ lower_bounds = lengths;
+ lengths += rank;
+ }
+ va_end(ap);
+
+ return mono_array_new_full (cm->klass, lengths, lower_bounds);
+}
+
#define ADD_TREE(t) do { g_ptr_array_add (forest, (t)); } while (0)
#define PUSH_TREE(t,k) do { *sp = t; sp++; t->svt = k; } while (0)
@@ -1089,7 +1186,7 @@
MonoMethodSignature *signature;
MonoImage *image;
MonoValueType svt;
- MBTree **sp, **stack, *t1, *t2;
+ MBTree **sp, **stack, **arg_sp, *t1, *t2;
register const unsigned char *ip, *end;
GPtrArray *forest;
int i, j, depth, repeat_count;
@@ -1498,16 +1595,13 @@
break;
}
- case CEE_NEWOBJ:
- case CEE_CALL:
- case CEE_CALLVIRT: {
+ case CEE_NEWOBJ: {
MonoMethodSignature *csig;
MonoMethod *cm;
- MBTree *nobj, *this = NULL;
+ MBTree *this = NULL;
guint32 token;
- int i, nargs, align, size, args_size = 0;
- int virtual = *ip == CEE_CALLVIRT;
- int newobj = *ip == CEE_NEWOBJ;
+ int i, align, size, args_size = 0;
+ int newarr = FALSE;
++ip;
token = read32 (ip);
@@ -1515,114 +1609,208 @@
cm = mono_get_method (image, token, NULL);
g_assert (cm);
+ g_assert (!strcmp (cm->name, ".ctor"));
- if ((cm->flags & METHOD_ATTRIBUTE_FINAL) ||
- !(cm->flags & METHOD_ATTRIBUTE_VIRTUAL))
- virtual = 0;
-
- // fixme: virtual does not work
- //virtual = 0;
-
csig = cm->signature;
g_assert (csig->call_convention == MONO_CALL_DEFAULT);
+ g_assert (csig->hasthis);
+
+ arg_sp = sp -= csig->param_count;
- if (newobj) {
- int n;
+ if (cm->klass->parent == mono_defaults.array_class) {
- for (i = 0; i < csig->param_count; i++)
- sp [-i] = sp [-i - 1];
-
- n = arch_allocate_var (cfg, sizeof (gpointer), sizeof (gpointer),
- MONO_TEMPVAR, VAL_UNKNOWN);
-
- nobj = mono_ctree_new_leaf (mp, MB_TERM_NEWOBJ);
- nobj->data.p = cm->klass;
- nobj->svt = VAL_POINTER;
-
- nobj = ctree_create_store (mp, MB_TERM_ADDR_L, nobj,
- &cm->klass->this_arg, (gpointer)n);
- ADD_TREE (nobj);
- sp [-i] = ctree_create_dup (mp, nobj);
- sp++;
- }
-
- nargs = csig->param_count;
- if (csig->hasthis || virtual || newobj) {
- nargs++;
- sp = sp - nargs;
- this = *sp;
+ newarr = TRUE;
+ this = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4);
+ this->data.p = cm;
+
} else {
- sp = sp - nargs;
+
+ this = mono_ctree_new_leaf (mp, MB_TERM_NEWOBJ);
+ this->data.p = cm->klass;
+ this->svt = VAL_POINTER;
+
+ t1 = mono_store_tree (cfg, -1, this, &this);
+ ADD_TREE (t1);
+
}
- //printf ("MINFO %s.%s::%s %d %d\n", cm->klass->name_space,
- //cm->klass->name, cm->name, cm->flags & METHOD_ATTRIBUTE_VIRTUAL, virtual);
-
- if (virtual) {
- t2 = ctree_create_dup (mp, this);
-
- if (!cm->klass->metadata_inited)
- mono_class_metadata_init (cm->klass);
+ for (i = csig->param_count - 1; i >= 0; i--) {
+ t1 = mono_ctree_new (mp, MB_TERM_ARG, arg_sp [i], NULL);
+ ADD_TREE (t1);
+ size = mono_type_size (cm->signature->params [i], &align);
+ args_size += (size + 3) & ~3;
+ }
- if (cm->klass->flags & TYPE_ATTRIBUTE_INTERFACE)
- t2 = mono_ctree_new (mp, MB_TERM_INTF_ADDR, t2, NULL);
- else
- t2 = mono_ctree_new (mp, MB_TERM_VFUNC_ADDR, t2, NULL);
-
- t2->data.m = cm;
+ t1 = mono_ctree_new (mp, MB_TERM_ARG, this, NULL);
+ ADD_TREE (t1);
+ args_size += sizeof (gpointer);
+
+ if (newarr) {
+
+ t2 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4);
+ t2->data.p = mono_array_new_va;
+
+ t1 = mono_ctree_new (mp, MB_TERM_CALL_I4, t2, NULL);
+ t1->data.i = args_size;
+ t1->svt = VAL_I32;
+
} else {
+
if (!cm->addr)
cm->addr = arch_create_simple_jit_trampoline (cm);
t2 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_G);
t2->data.p = (char *)cm + G_STRUCT_OFFSET (MonoMethod, addr);
+ t2 = mono_ctree_new (mp, MB_TERM_LDIND_I4, t2, NULL);
+ }
+
+ t1 = mono_ctree_new (mp, map_call_type (csig->ret, &svt), t2, NULL);
+ t1->data.i = args_size;
+ t1->svt = svt;
+
+ if (newarr) {
+
+ t1 = mono_store_tree (cfg, -1, t1, &t2);
+ ADD_TREE (t1);
+ PUSH_TREE (t2, t2->svt);
+
+ } else {
+ ADD_TREE (t1);
+ t1 = ctree_create_dup (mp, this);
+ PUSH_TREE (t1, t1->svt);
}
+ break;
+ }
+ case CEE_CALL:
+ case CEE_CALLVIRT: {
+ MonoMethodSignature *csig;
+ MonoMethod *cm;
+ MBTree *this = NULL;
+ guint32 token;
+ int i, align, size, args_size = 0;
+ int virtual = *ip == CEE_CALLVIRT;
+ gboolean array_set = FALSE;
+ gboolean array_get = FALSE;
+ int nargs;
- if (nargs) {
+ ++ip;
+ token = read32 (ip);
+ ip += 4;
-#ifdef ARCH_ARGS_RIGHT_TO_LEFT
- for (i = nargs - 1; i >= 0; i--) {
-#else
- for (i = 0; i < nargs; i++) {
-#endif
- t1 = mono_ctree_new (mp, MB_TERM_ARG, sp [i], NULL);
- ADD_TREE (t1);
+ cm = mono_get_method (image, token, NULL);
+ g_assert (cm);
+
+ if ((cm->flags & METHOD_ATTRIBUTE_FINAL) ||
+ !(cm->flags & METHOD_ATTRIBUTE_VIRTUAL))
+ virtual = 0;
- if (!i && this)
- size = mono_type_size (&cm->klass->this_arg, &align);
- else
- size = mono_type_size (cm->signature->params [i - (this != NULL)], &align);
+ csig = cm->signature;
+ g_assert (csig->call_convention == MONO_CALL_DEFAULT);
+ g_assert (!virtual || csig->hasthis);
- // fixme: does this really work ?
- args_size += (size + 3) & ~3;
- }
+ nargs = csig->param_count;
+ arg_sp = sp -= nargs;
+
+ if ((cm->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) &&
+ (cm->klass->parent == mono_defaults._rray_class)) {
+ if (!strcmp (cm->name, "Set")) {
+ array_set = TRUE;
+ nargs--;
+ } else if (!strcmp (cm->name, "Get"))
+ array_get = TRUE;
}
- t1 = mono_ctree_new (mp, map_call_type (csig->ret, &svt), t2, NULL);
- t1->data.i = args_size;
- t1->svt = svt;
+ for (i = nargs - 1; i >= 0; i--) {
+ t1 = mono_ctree_new (mp, MB_TERM_ARG, arg_sp [i], NULL);
+ ADD_TREE (t1);
+ size = mono_type_size (cm->signature->params [i], &align);
+ args_size += (size + 3) & ~3;
+ }
- if (csig->ret->type != MONO_TYPE_VOID) {
- int n;
+ if (csig->hasthis) {
+ this = *(--sp);
+ t1 = mono_ctree_new (mp, MB_TERM_ARG, this, NULL);
+ ADD_TREE (t1);
+ args_size += sizeof (gpointer);
+ }
- size = mono_type_size (csig->ret, &align);
- n = arch_allocate_var (cfg, size, align, MONO_TEMPVAR, VAL_UNKNOWN);
+ if (array_get) {
+ int size, align, vnum;
- t2 = ctree_create_store (mp, MB_TERM_ADDR_L, t1, csig->ret, (gpointer)n);
- ADD_TREE (t2);
+ t2 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4);
+ t2->data.p = ves_array_element_address;
- t1 = ctree_create_dup (mp, t2);
- PUSH_TREE (t1, svt);
+ t1 = mono_ctree_new (mp, MB_TERM_CALL_I4, t2, NULL);
+ t1->data.i = args_size;
+
+ t1 = mono_ctree_new (mp, map_ldind_type (csig->ret, &svt), t1, NULL);
+ t1->svt = svt;
+
+ mono_get_val_sizes (t1->svt, &size, &align);
+ vnum = arch_allocate_var (cfg, size, align, MONO_TEMPVAR, svt);
+
+ t2 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_L);
+ t2->data.i = vnum;
+ t1 = mono_ctree_new (mp, map_store_svt_type (svt), t2, t1);
+ t1->svt = svt;
+
+ ADD_TREE (t1);
+ t1 = ctree_create_dup (mp, t1);
+ PUSH_TREE (t1, t1->svt);
+
+ } else if (array_set) {
+
+ t2 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4);
+ t2->data.p = ves_array_element_address;
+
+ t1 = mono_ctree_new (mp, MB_TERM_CALL_I4, t2, NULL);
+ t1->data.i = args_size;
+
+ t1 = mono_ctree_new (mp, map_stind_type (csig->params [nargs]), t1, arg_sp [nargs]);
+ ADD_TREE (t1);
+
} else {
- if (newobj) {
- ADD_TREE (t1);
- t1 = ctree_create_dup (mp, nobj);
- PUSH_TREE (t1, t1->svt);
+
+ if (virtual) {
+
+ t2 = ctree_create_dup (mp, this);
+
+ if (!cm->klass->metadata_inited)
+ mono_class_metadata_init (cm->klass);
+
+ if (cm->klass->flags & TYPE_ATTRIBUTE_INTERFACE)
+ t2 = mono_ctree_new (mp, MB_TERM_INTF_ADDR, t2, NULL);
+ else
+ t2 = mono_ctree_new (mp, MB_TERM_VFUNC_ADDR, t2, NULL);
+
+ t2->data.m = cm;
+
} else {
- ADD_TREE (t1);
+
+ if (!cm->addr)
+ cm->addr = arch_create_simple_jit_trampoline (cm);
+
+ t2 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_G);
+ t2->data.p = (char *)cm + G_STRUCT_OFFSET (MonoMethod, addr);
+ t2 = mono_ctree_new (mp, MB_TERM_LDIND_I4, t2, NULL);
}
+
+ t1 = mono_ctree_new (mp, map_call_type (csig->ret, &svt), t2, NULL);
+ t1->data.i = args_size;
+ t1->svt = svt;
+
+ if (csig->ret->type != MONO_TYPE_VOID) {
+
+ t1 = mono_store_tree (cfg, -1, t1, &t2);
+ ADD_TREE (t1);
+ PUSH_TREE (t2, t2->svt);
+
+ } else
+ ADD_TREE (t1);
+
}
+
break;
}
case CEE_ISINST:
@@ -2091,8 +2279,22 @@
} while (repeat);
+
+ //printf ("FINISHED\n");
+}
+
+/* this function is never called */
+static void
+ves_array_set (MonoArray *this, ...)
+{
+ g_assert_not_reached ();
+}
- //printf ("FINISHED\n");
+/* this function is never called */
+static void
+ves_array_get (MonoArray *this, ...)
+{
+ g_assert_not_reached ();
}
/**
@@ -2212,6 +2414,8 @@
mono_init ();
mono_init_icall ();
+ mono_add_internal_call ("__array_Set", ves_array_set);
+ mono_add_internal_call ("__array_Get", ves_array_get);
assembly = mono_assembly_open (file, NULL, NULL);
if (!assembly){
Index: mono/jit/x86.brg
===================================================================
RCS file: /cvs/public/mono/mono/jit/x86.brg,v
retrieving revision 1.32
diff -u -r1.32 x86.brg
--- mono/jit/x86.brg 2001/11/08 21:38:32 1.32
+++ mono/jit/x86.brg 2001/11/09 06:26:27
@@ -26,8 +26,6 @@
#define MBCOST_DATA MonoFlowGraph
#define MBALLOC_STATE mono_mempool_alloc (data->mp, sizeof (MBState))
-#define ARCH_ARGS_RIGHT_TO_LEFT
-
typedef enum {
AMImmediate = 0, // ptr
AMBase = 1, // V[REG]
@@ -121,7 +119,7 @@
%term CEQ
%term CONV_I4 CONV_I1 CONV_I2 CONV_I8 CONV_R8
%term INTF_ADDR VFUNC_ADDR NOP BOX NEWARR NEWOBJ POP
-%term LDLEN LDELEMA
+%term LDLEN
#
# we start at stmt
@@ -268,6 +266,29 @@
}
}
+reg: LDIND_U4 (addr) {
+ switch (tree->left->data.ainfo.amode) {
+
+ case AMImmediate:
+ x86_mov_reg_mem (s->code, tree->reg1, tree->left->data.ainfo.offset, 4);
+ break;
+
+ case AMBase:
+ x86_mov_reg_membase (s->code, tree->reg1, tree->left->data.ainfo.basereg,
+ tree->left->data.ainfo.offset, 4);
+ break;
+ case AMIndex:
+ x86_mov_reg_memindex (s->code, tree->reg1, X86_NOBASEREG, tree->left->data.ainfo.offset,
+ tree->left->data.ainfo.indexreg, tree->left->data.ainfo.shift, 4);
+ break;
+ case AMBaseIndex:
+ x86_mov_reg_memindex (s->code, tree->reg1, tree->left->data.ainfo.basereg,
+ tree->left->data.ainfo.offset, tree->left->data.ainfo.indexreg,
+ tree->left->data.ainfo.shift, 4);
+ break;
+ }
+}
+
locaddr: ADDR_L 10 {
tree->data.i = g_array_index (s->varinfo, MonoVarInfo, tree->data.i).offset;
}
@@ -493,8 +514,23 @@
}
reg: BOX (reg) {
- // fixme: implement me
- //g_assert_not_reached ();
+ if (tree->reg1 != X86_EAX)
+ x86_push_reg (s->code, X86_EAX);
+ x86_push_reg (s->code, X86_ECX);
+ x86_push_reg (s->code, X86_EDX);
+
+ x86_push_reg (s->code, tree->left->reg1); //save it to memory
+ x86_push_reg (s->code, X86_ESP); // push address to saved value
+ x86_push_imm (s->code, tree->data.p);
+ x86_call_code (s->code, mono_value_box);
+ x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, 12);
+
+ x86_pop_reg (s->code, X86_EDX);
+ x86_pop_reg (s->code, X86_ECX);
+ if (tree->reg1 != X86_EAX) {
+ x86_mov_reg_reg (s->code, tree->reg1, X86_EAX, 4);
+ x86_pop_reg (s->code, X86_EAX);
+ }
}
# array support
@@ -505,12 +541,11 @@
G_STRUCT_OFFSET (MonoArrayBounds, length), 4);
}
-reg: LDELEMA (reg, reg) {
- x86_mov_reg_membase (s->code, tree->reg1, tree->left->reg1,
- G_STRUCT_OFFSET (MonoArray, vector), 4);
- x86_imul_reg_reg_imm (s->code, tree->right->reg1, tree->right->reg1, tree->data.i);
- x86_alu_reg_reg (s->code, X86_ADD, tree->reg1, tree->right->reg1);
-}
+#reg: LDELEMA (reg, reg) {
+# x86_imul_reg_reg_imm (s->code, tree->right->reg1, tree->right->reg1, tree->data.i);
+# x86_alu_reg_reg (s->code, X86_ADD, tree->reg1, tree->right->reg1);
+# x86_alu_reg_imm (s->code, X86_ADD, tree->reg1, G_STRUCT_OFFSET (MonoArray, vector));
+#}
reg: NEWARR (reg) {
if (tree->reg1 != X86_EAX)
@@ -526,7 +561,7 @@
x86_pop_reg (s->code, X86_EDX);
x86_pop_reg (s->code, X86_ECX);
if (tree->reg1 != X86_EAX) {
- x86_mov_reg_reg (s->code, X86_EAX, tree->reg1, 4);
+ x86_mov_reg_reg (s->code, tree->reg1, X86_EAX, 4);
x86_pop_reg (s->code, X86_EAX);
}
}
@@ -544,7 +579,7 @@
x86_pop_reg (s->code, X86_EDX);
x86_pop_reg (s->code, X86_ECX);
if (tree->reg1 != X86_EAX) {
- x86_mov_reg_reg (s->code, X86_EAX, tree->reg1, 4);
+ x86_mov_reg_reg (s->code, tree->reg1, X86_EAX, 4);
x86_pop_reg (s->code, X86_EAX);
}
}
@@ -828,12 +863,22 @@
stmt: ARG (LDIND_OBJ (reg)) {
// fixme:
- //g_assert_not_reached ();
+ g_assert_not_reached ();
+}
+
+reg: CALL_I4 (CONST_I4) {
+
+ x86_call_code (s->code, tree->left->data.p);
+
+ if (tree->data.i)
+ x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.i);
+
+ g_assert (tree->reg1 == X86_EAX);
}
-reg: CALL_I4 (ADDR_G) {
+reg: CALL_I4 (LDIND_I4 (ADDR_G)) {
- x86_call_mem (s->code, tree->left->data.p);
+ x86_call_mem (s->code, tree->left->left->data.p);
if (tree->data.i)
x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.i);
@@ -869,8 +914,8 @@
g_assert (tree->reg1 == X86_EAX);
}
-stmt: CALL_I4 (ADDR_G) {
- x86_call_mem (s->c_de, tree->left->data.p);
+stmt: CALL_I4 (LDIND_I4 (ADDR_G)) {
+ x86_call_mem (s->code, tree->left->left->data.p);
if (tree->data.i)
x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.i);
@@ -900,13 +945,6 @@
x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.i);
}
-stmt: CALL_I4 (ADDR_G) {
- x86_call_mem (s->code, tree->left->data.p);
-
- if (tree->data.i)
- x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.i);
-}
-
stmt: SWITCH (reg) {
guint32 offset;
guint32 *jt = (guint32 *)tree->data.p;
@@ -1155,19 +1193,9 @@
x86_pop_reg (s->code, X86_ECX);
}
-lreg: CALL_I8 (addr) {
-
- switch (tree->left->data.ainfo.amode) {
- case AMImmediate:
- x86_call_mem (s->code, tree->left->data.ainfo.offset);
- break;
- case AMBase:
- x86_call_membase (s->code, tree->left->data.ainfo.basereg,
- tree->left->data.ainfo.offset);
- break;
- default:
- g_assert_not_reached ();
- }
+lreg: CALL_I8 (LDIND_I4 (ADDR_G)) {
+
+ x86_call_mem (s->code, tree->left->left->data.p);
if (tree->data.i)
x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.i);
@@ -1416,11 +1444,26 @@
}
freg: CONST_R4 {
- x86_fld (s->code, tree->data.p, FALSE);
+ float f = *(float *)tree->data.p;
+
+ if (f == 0.0)
+ x86_fldz (s->code);
+ else if (f == 1.0)
+ x86_fld1(s->code);
+ else
+ x86_fld (s->code, tree->data.p, FALSE);
}
freg: CONST_R8 {
- x86_fld (s->code, tree->data.p, TRUE);
+ double d = *(double *)tree->data.p;
+ printf ("TEST %f\n", d);
+
+ if (d == 0.0)
+ x86_fldz (s->code);
+ else if (d == 1.0)
+ x86_fld1(s->code);
+ else
+ x86_fld (s->code, tree->data.p, TRUE);
}
freg: LDIND_R4 (locaddr) {
@@ -1493,21 +1536,31 @@
x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500);
x86_alu_reg_imm (s->code, X86_CMP, X86_EAX, 0x4000);
offset = 6 + s->code - s->start;
- x86_branch32 (s->code, X86_CC_NE, tree->data.bb->addr - offset, TRUE);
+ x86_branch32 (s->code, X86_CC_NE, tree->data.bb->addr - offset, FALSE);
}
-stmt: BLT_UN (freg, freg) {
+stmt: BLT (freg, freg) {
gint32 offset;
tree->is_jump = 1;
x86_fcompp (s->code);
x86_fnstsw (s->code);
x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500);
- x86_alu_reg_imm (s->code, X86_CMP, X86_EAX, 0x0100);
offset = 6 + s->code - s->start;
x86_branch32 (s->code, X86_CC_EQ, tree->data.bb->addr - offset, TRUE);
}
+stmt: BLT_UN (freg, freg) {
+ gint32 offset;
+
+ tree->is_jump = 1;
+ x86_fcompp (s->code);
+ x86_fnstsw (s->code);
+ x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500);
+ offset = 6 + s->code - s->start;
+ x86_branch32 (s->code, X86_CC_EQ, tree->data.bb->addr - offset, FALSE);
+}
+
stmt: BGE_UN (freg, freg) {
gint32 offset;
@@ -1515,9 +1568,8 @@
x86_fcompp (s->code);
x86_fnstsw (s->code);
x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500);
- x86_alu_reg_imm (s->code, X86_CMP, X86_EAX, 0x0100);
offset = 6 + s->code - s->start;
- x86_branch32 (s->code, X86_CC_NE, tree->data.bb->addr - offset, TRUE);
+ x86_branch32 (s->code, X86_CC_NE, tree->data.bb->addr - offset, FALSE);
}
stmt: BGT_UN (freg, freg) {
@@ -1527,8 +1579,9 @@
x86_fcompp (s->code);
x86_fnstsw (s->code);
x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500);
+ x86_alu_reg_imm (s->code, X86_CMP, X86_EAX, 0x0100);
offset = 6 + s->code - s->start;
- x86_branch32 (s->code, X86_CC_EQ, tree->data.bb->addr - offset, TRUE);
+ x86_branch32 (s->code, X86_CC_EQ, tree->data.bb->addr - offset, FALSE);
}
stmt: BLE_UN (freg, freg) {
@@ -1539,22 +1592,12 @@
x86_fnstsw (s->code);
x86_alu_reg_imm (s->code, X86_AND, X86_EAX, 0x4500);
offset = 6 + s->code - s->start;
- x86_branch32 (s->code, X86_CC_NE, tree->data.bb->addr - offset, TRUE);
+ x86_branch32 (s->code, X86_CC_NE, tree->data.bb->addr - offset, FALSE);
}
-freg: CALL_R8 (addr) {
-
- switch (tree->left->data.ainfo.amode) {
- case AMImmediate:
- x86_call_mem (s->code, tree->left->data.ainfo.offset);
- break;
- case AMBase:
- x86_call_membase (s->code, tree->left->data.ainfo.basereg,
- tree->left->data.ainfo.offset);
- break;
- default:
- g_assert_not_reached ();
- }
+freg: CALL_R8 (LDIND_I4 (ADDR_G)) {
+
+ x86_call_mem (s->code, tree->left->left->data.p);
if (tree->data.i)
x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->data.i);
Index: mono/tests/array.cs
===================================================================
RCS file: /cvs/public/mono/mono/tests/array.cs,v
retrieving revision 1.5
diff -u -r1.5 array.cs
--- mono/tests/array.cs 2001/08/28 10:47:36 1.5
+++ mono/tests/array.cs 2001/11/09 06:26:27
@@ -97,7 +97,7 @@
public static int Main () {
-
+
if (atest () != 0)
return 1;