[Mono-list] jit patch: LDELEM/STELEM impl.
Dietmar Maurer
dietmar@ximian.com
02 Nov 2001 18:27:49 +0100
Index: mono/jit/ChangeLog
===================================================================
RCS file: /cvs/public/mono/mono/jit/ChangeLog,v
retrieving revision 1.31
diff -u -r1.31 ChangeLog
--- mono/jit/ChangeLog 2001/10/15 09:50:03 1.31
+++ mono/jit/ChangeLog 2001/11/02 13:27:16
@@ -1,3 +1,10 @@
+2001-11-02 Dietmar Maurer <dietmar@ximian.com>
+
+ * testjit.c: impl. STELEM_XX, STELEM_XX
+
+ * x86.brg: impl. LDLEN, LDELEMA
+
+
2001-10-15 Dietmar Maurer <dietmar@ximian.com>
* x86.brg: added some experimental code for CALL
Index: mono/jit/emit-x86.c
===================================================================
RCS file: /cvs/public/mono/mono/jit/emit-x86.c,v
retrieving revision 1.9
diff -u -r1.9 emit-x86.c
--- mono/jit/emit-x86.c 2001/11/02 10:12:24 1.9
+++ mono/jit/emit-x86.c 2001/11/02 13:27:16
@@ -164,7 +164,7 @@
tree->reg1 = X86_EAX;
break;
case MB_TERM_CALL_I8:
- case MB_TERM_MUL:
+ //case MB_TERM_MUL:
tree->reg1 = X86_EAX;
tree->reg2 = X86_EDX;
break;
@@ -201,7 +201,7 @@
case MB_NTERM_reg:
if ((tree->reg1 =
mono_regset_alloc_reg (rs, tree->reg1, tree->exclude_mask)) == -1) {
- g_warning ("register allocation failed\n");
+ g_warning ("register allocation failed %d %p %p\n", tree->reg1, rs->free_mask, tree->exclude_mask);
g_assert_not_reached ();
}
@@ -260,7 +260,9 @@
for (j = 0; j < top; j++) {
MBTree *t1 = (MBTree *) g_ptr_array_index (forest, j);
+ //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);
}
}
}
Index: mono/jit/testjit.c
===================================================================
RCS file: /cvs/public/mono/mono/jit/testjit.c,v
retrieving revision 1.33
diff -u -r1.33 testjit.c
--- mono/jit/testjit.c 2001/11/02 10:12:24 1.33
+++ mono/jit/testjit.c 2001/11/02 13:27:16
@@ -86,6 +86,17 @@
break; \
}
+#define MAKE_LDELEM(name, op, svt, s) \
+case CEE_##name: { \
+ ++ip; \
+ sp -= 2; \
+ t1 = mono_ctree_new (mp, MB_TERM_LDELEMA, sp [0], sp [1]); \
+ t1->size = s; \
+ t1 = mono_ctree_new (mp, op, t1, NULL); \
+ PUSH_TREE (t1, svt); \
+ break; \
+}
+
#define MAKE_STIND(name, op) \
case CEE_##name: { \
++ip; \
@@ -95,6 +106,17 @@
break; \
}
+#define MAKE_STELEM(name, op, s) \
+case CEE_##name: { \
+ ++ip; \
+ sp -= 3; \
+ t1 = mono_ctree_new (mp, MB_TERM_LDELEMA, sp [0], sp [1]); \
+ t1->size = s; \
+ 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;
@@ -145,6 +167,7 @@
case MONO_TYPE_OBJECT:
case MONO_TYPE_STRING:
case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY:
return MB_TERM_STIND_I4;
case MONO_TYPE_I8:
case MONO_TYPE_U8:
@@ -216,6 +239,7 @@
case MONO_TYPE_OBJECT:
case MONO_TYPE_STRING:
case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY:
*svt = VAL_POINTER;
return MB_TERM_LDIND_U4;
case MONO_TYPE_I8:
@@ -584,26 +608,6 @@
return t;
}
-/* fixme: this is to clumsy :-( */
-static MBTree *
-ctree_create_newobj (MonoMemPool *mp, MonoClass *klass)
-{
- MBTree *t1, *t2;
- static gpointer newobj_func = mono_object_new;
-
- t1 = mono_ctree_new_leaf (mp, MB_TERM_ARG_END);
- t2 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4);
- t2->data.p = klass;
- t1 = mono_ctree_new (mp, MB_TERM_ARG, t1, t2);
-
- t2 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_G);
- t2->data.p = &newobj_func;
- t1 = mono_ctree_new (mp, MB_TERM_CALL_I4, t1, t2);
- t1->size = sizeof (gpointer);
-
- return t1;
-}
-
/**
* Create a duplicate of the value of a tree. This is
* easy for trees starting with LDIND/STIND, since the
@@ -842,6 +846,26 @@
case CEE_STIND_R4:
case CEE_STIND_R8:
case CEE_STIND_REF:
+ case CEE_STELEM_I:
+ case CEE_STELEM_I1:
+ case CEE_STELEM_I2:
+ case CEE_STELEM_I4:
+ case CEE_STELEM_I8:
+ case CEE_STELEM_R4:
+ case CEE_STELEM_R8:
+ case CEE_STELEM_REF:
+ case CEE_LDLEN:
+ case CEE_LDELEM_I1:
+ case CEE_LDELEM_U1:
+ case CEE_LDELEM_I2:
+ case CEE_LDELEM_U2:
+ case CEE_LDELEM_I4:
+ case CEE_LDELEM_U4:
+ case CEE_LDELEM_I8:
+ case CEE_LDELEM_I:
+ case CEE_LDELEM_R4:
+ case CEE_LDELEM_R8:
+ case CEE_LDELEM_REF:
ip++;
break;
case CEE_RET:
@@ -1194,6 +1218,15 @@
PUSH_TREE (t1, VAL_POINTER);
break;
}
+ case CEE_LDLEN: {
+ ip++;
+ sp--;
+
+ t1 = mono_ctree_new (mp, MB_TERM_LDLEN, *sp, NULL);
+ PUSH_TREE (t1, VAL_I32);
+ break;
+ }
+
case CEE_LDOBJ: {
guint32 token;
MonoClass *c;
@@ -1448,6 +1481,7 @@
ip += 4;
t1 = mono_ctree_new (mp, MB_TERM_NEWARR, *sp, NULL);
+ t1->data.p = class;
PUSH_TREE (t1, VAL_POINTER);
break;
@@ -1491,8 +1525,11 @@
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_newobj (mp, cm->klass);
nobj = ctree_create_store (mp, MB_TERM_ADDR_L, nobj,
&cm->klass->this_arg, (gpointer)n);
ADD_TREE (nobj);
@@ -1529,8 +1566,6 @@
t2->data.p = (char *)cm + G_STRUCT_OFFSET (MonoMethod, addr);
}
- t1 = mono_ctree_new_leaf (mp, MB_TERM_ARG_END);
-
if (nargs) {
#ifdef ARCH_ARGS_RIGHT_TO_LEFT
@@ -1538,8 +1573,9 @@
#else
for (i = 0; i < nargs; i++) {
#endif
- t1 = mono_ctree_new (mp, MB_TERM_ARG, t1, sp [i]);
-
+ t1 = mono_ctree_new (mp, MB_TERM_ARG, sp [i], NULL);
+ ADD_TREE (t1);
+
if (!i && this)
size = mono_type_size (&cm->klass->this_arg, &align);
else
@@ -1550,7 +1586,7 @@
}
}
- t1 = mono_ctree_new (mp, map_call_type (csig->ret, &svt), t1, t2);
+ t1 = mono_ctree_new (mp, map_call_type (csig->ret, &svt), t2, NULL);
t1->size = args_size;
t1->svt = svt;
@@ -1747,6 +1783,27 @@
MAKE_STIND (STIND_R4, MB_TERM_STIND_R4)
MAKE_STIND (STIND_R8, MB_TERM_STIND_R8)
MAKE_STIND (STIND_REF, MB_TERM_STIND_I4)
+
+ MAKE_LDELEM (LDELEM_I1, MB_TERM_LDIND_I1, VAL_I32, 1)
+ MAKE_LDELEM (LDELEM_U1, MB_TERM_LDIND_U1, VAL_I32, 1)
+ MAKE_LDELEM (LDELEM_I2, MB_TERM_LDIND_I2, VAL_I32, 2)
+ MAKE_LDELEM (LDELEM_U2, MB_TERM_LDIND_U2, VAL_I32, 2)
+ MAKE_LDELEM (LDELEM_I, MB_TERM_LDIND_I4, VAL_I32, 4)
+ MAKE_LDELEM (LDELEM_I4, MB_TERM_LDIND_I4, VAL_I32, 4)
+ MAKE_LDELEM (LDELEM_REF, MB_TERM_LDIND_U4, VAL_I32, 4)
+ MAKE_LDELEM (LDELEM_U4, MB_TERM_LDIND_U4, VAL_I32, 4)
+ MAKE_LDELEM (LDELEM_I8, MB_TERM_LDIND_I8, VAL_I64, 8)
+ MAKE_LDELEM (LDELEM_R4, MB_TERM_LDIND_R4, VAL_DOUBLE, 4)
+ MAKE_LDELEM (LDELEM_R8, MB_TERM_LDIND_R8, VAL_DOUBLE, 8)
+
+ MAKE_STELEM (STELEM_I1, MB_TERM_STIND_I1, 1)
+ MAKE_STELEM (STELEM_I2, MB_TERM_STIND_I2, 2)
+ MAKE_STELEM (STELEM_I4, MB_TERM_STIND_I4, 4)
+ MAKE_STELEM (STELEM_I, MB_TERM_STIND_I4, 4)
+ MAKE_STELEM (STELEM_REF, MB_TERM_STIND_I4, 4)
+ M_KE_STELEM (STELEM_I8, MB_TERM_STIND_I8, 8)
+ MAKE_STELEM (STELEM_R4, MB_TERM_STIND_R4, 4)
+ MAKE_STELEM (STELEM_R8, MB_TERM_STIND_R8, 8)
case CEE_NEG: {
ip++;
Index: mono/jit/x86.brg
===================================================================
RCS file: /cvs/public/mono/mono/jit/x86.brg,v
retrieving revision 1.26
diff -u -r1.26 x86.brg
--- mono/jit/x86.brg 2001/11/02 10:12:24 1.26
+++ mono/jit/x86.brg 2001/11/02 13:27:16
@@ -104,13 +104,14 @@
%term LDIND_I1 LDIND_U1 LDIND_I2 LDIND_U2 LDIND_I4 LDIND_I8 LDIND_R4 LDIND_R8
%term LDIND_U4 LDIND_OBJ
%term STIND_I1 STIND_I2 STIND_I4 STIND_I8 STIND_R4 STIND_R8 STIND_OBJ
-%term ADDR_L ADDR_G ARG ARG_END CALL_I4 CALL_I8 CALL_R8
+%term ADDR_L ADDR_G ARG CALL_I4 CALL_I8 CALL_R8
%term BREAK SWITCH BR RET RETV
%term ADD SUB MUL DIV DIV_UN REM REM_UN AND OR XOR SHL SHR SHR_UN NEG NOT
%term BLT BLT_UN BEQ BNE_UN BRTRUE BRFALSE BGE BGE_UN BLE BLE_UN BGT BGT_UN
%term CEQ
%term CONV_I4 CONV_I1 CONV_I2 CONV_I8 CONV_R8
-%term INTF_ADDR VFUNC_ADDR NOP BOX NEWARR POP
+%term INTF_ADDR VFUNC_ADDR NOP BOX NEWARR NEWOBJ POP
+%term LDLEN LDELEMA
#
# we start at stmt
@@ -481,9 +482,53 @@
//g_assert_not_reached ();
}
+# array support
+reg: LDLEN (reg) {
+ x86_mov_reg_membase (s->code, tree->reg1, tree->left->reg1, G_STRUCT_OFFSET (MonoArray, bounds), 4);
+ x86_mov_reg_membase (s->code, tree->reg1, tree->reg1, 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->size);
+ x86_alu_reg_reg (s->code, X86_ADD, tree->reg1, tree->right->reg1);
+}
+
reg: NEWARR (reg) {
- // fixme: implement me
+ 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);
+ x86_push_imm (s->code, tree->data.p);
+ x86_call_code (s->code, mono_array_new);
+ x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, sizeof (gpointer) + 4);
+
+ 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_pop_reg (s->code, X86_EAX);
+ }
+}
+reg: NEWOBJ {
+ 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_imm (s->code, tree->data.p);
+ x86_call_code (s->code, mono_object_new);
+ x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, sizeof (gpointer));
+
+ 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_pop_reg (s->code, X86_EAX);
+ }
}
stmt: NOP
@@ -750,29 +795,27 @@
x86_jump32 (s->code, s->epilog - 5);
}
}
-
-argl: ARG_END
-argl: ARG (argl, reg) {
- x86_push_reg (s->code, tree->right->reg1);
+stmt: ARG (reg) {
+ x86_push_reg (s->code, tree->left->reg1);
}
-argl: ARG (argl, ADDR_G) {
- x86_push_imm (s->code, tree->right->data.p);
+stmt: ARG (ADDR_G) {
+ x86_push_imm (s->code, tree->left->data.p);
}
-argl: ARG (argl, CONST_I4) "MB_USE_OPT1(0)" {
- x86_push_imm (s->code, tree->right->data.i);
+stmt: ARG (CONST_I4) "MB_USE_OPT1(0)" {
+ x86_push_imm (s->code, tree->left->data.i);
}
-argl: ARG (argl, LDIND_OBJ (reg)) {
+stmt: ARG (LDIND_OBJ (reg)) {
// fixme:
//g_assert_not_reached ();
}
-reg: CALL_I4 (argl, ADDR_G) {
+reg: CALL_I4 (ADDR_G) {
- x86_call_mem (s->code, tree->right->data.p);
+ x86_call_mem (s->code, tree->left->data.p);
if (tree->size)
x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
@@ -780,13 +823,13 @@
g_assert (tree->reg1 == X86_EAX);
}
-reg: CALL_I4 (argl, INTF_ADDR (reg)) {
- int reg1 = tree->right->left->reg1;
+reg: CALL_I4 (INTF_ADDR (reg)) {
+ int reg1 = tree->left->left->reg1;
x86_mov_reg_membase (s->code, reg1, reg1, 0, 4);
x86_mov_reg_membase (s->code, reg1, reg1, G_STRUCT_OFFSET (MonoClass, interface_offsets), 4);
- x86_mov_reg_membase (s->code, reg1, reg1, tree->right->data.i, 4);
- x86_call_membase (s->code, reg1, tree->right->size);
+ x86_mov_reg_membase (s->code, reg1, reg1, tree->left->data.i, 4);
+ x86_call_membase (s->code, reg1, tree->left->size);
if (tree->size)
x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
@@ -794,11 +837,11 @@
g_assert (tree->reg1 == X86_EAX);
}
-reg: CALL_I4 (argl, VFUNC_ADDR (reg)) {
- int reg1 = tree->right->left->reg1;
+reg: CALL_I4 (VFUNC_ADDR (reg)) {
+ int reg1 = tree->left->left->reg1;
x86_mov_reg_membase (s->code, reg1, reg1, 0, 4);
- x86_call_membase (s->code, reg1, G_STRUCT_OFFSET (MonoClass, vtable + tree->right->data.i));
+ x86_call_membase (s->code, reg1, G_STRUCT_OFFSET (MonoClass, vtable + tree->left->data.i));
if (tree->size)
x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
@@ -806,37 +849,37 @@
g_assert (tree->reg1 == X86_EAX);
}
-stmt: CALL_I4 (argl, ADDR_G) {
- x86_call_mem (s->code, tree->right->data.p);
+stmt: CALL_I4 (ADDR_G) {
+ x86_call_mem (s->code, tree->left->data.p);
if (tree->size)
x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
}
-stmt: CALL_I4 (argl, INTF_ADDR (reg)) {
- int reg1 = tree->right->left->reg1;
+stmt: CALL_I4 (INTF_ADDR (reg)) {
+ int reg1 = tree->left->left->reg1;
x86_mov_reg_membase (s->code, reg1, reg1, 0, 4);
x86_mov_reg_membase (s->code, reg1, reg1, G_STRUCT_OFFSET (MonoClass, interface_offsets), 4);
- x86_mov_reg_membase (s->code, reg1, reg1, tree->right->data.i, 4);
- x86_call_membase (s->code, reg1, tree->right->size);
+ x86_mov_reg_membase (s->code, reg1, reg1, tree->left->data.i, 4);
+ x86_call_membase (s->code, reg1, tree->left->size);
if (tree->size)
x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
}
-stmt: CALL_I4 (argl, VFUNC_ADDR (reg)) {
- int reg1 = tree->right->left->reg1;
+stmt: CALL_I4 (VFUNC_ADDR (reg)) {
+ int reg1 = tree->left->left->reg1;
x86_mov_reg_membase (s->code, reg1, reg1, 0, 4);
- x86_call_membase (s->code, reg1, G_STRUCT_OFFSET (MonoClass, vtable + tree->right->data.i));
+ x86_call_membase (s->code, reg1, G_STRUCT_OFFSET (MonoClass, vtable + tree->left->data.i));
if (tree->size)
x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
}
-stmt: CALL_I4 (argl, ADDR_G) {
- x86_call_mem (s->code, tree->right->data.p);
+stmt: CALL_I4 (ADDR_G) {
+ x86_call_mem (s->code, tree->left->data.p);
if (tree->size)
x86_alu_reg_imm (s->code, X86_ADD, X86_ESP, tree->size);
@@ -1090,15 +1133,15 @@
x86_pop_reg (s->code, X86_ECX);
}
-lreg: CALL_I8 (argl, addr) {
+lreg: CALL_I8 (addr) {
- switch (tree->right->data.ainfo.amode) {
+ switch (tree->left->data.ainfo.amode) {
case AMImmediate:
- x86_call_mem (s->code, tree->right->data.ainfo.offset);
+ x86_call_mem (s->code, tree->left->data.ainfo.offset);
break;
case AMBase:
- x86_call_membase (s->code, tree->right->data.ainfo.basereg,
- tree->right->data.ainfo.offset);
+ x86_call_membase (s->code, tree->left->data.ainfo.basereg,
+ tree->left->data.ainfo.offset);
break;
default:
g_assert_not_reached ();
@@ -1133,9 +1176,9 @@
}
-argl: ARG (argl, lreg) {
- x86_push_reg (s->code, tree->right->reg2);
- x86_push_reg (s->code, tree->right->reg1);
+stmt: ARG (lreg) {
+ x86_push_reg (s->code, tree->left->reg2);
+ x86_push_reg (s->code, tree->left->reg1);
}
stmt: BEQ (lreg, lreg) {
@@ -1392,7 +1435,7 @@
x86_fst_membase (s->code, X86_EBP, tree->left->data.i, TRUE, TRUE);
}
-argl: ARG (argl, freg) {
+stmt: ARG (freg) {
x86_alu_reg_imm (s->code, X86_SUB, X86_ESP, 8);
x86_fst_membase (s->code, X86_ESP, 0, TRUE, TRUE);
}
@@ -1467,15 +1510,15 @@
x86_branch32 (s->code, X86_CC_NE, tree->data.bb->addr - offset, TRUE);
}
-freg: CALL_R8 (argl, addr) {
+freg: CALL_R8 (addr) {
- switch (tree->right->data.ainfo.amode) {
+ switch (tree->left->data.ainfo.amode) {
case AMImmediate:
- x86_call_mem (s->code, tree->right->data.ainfo.offset);
+ x86_call_mem (s->code, tree->left->data.ainfo.offset);
break;
case A_Base:
- x86_call_membase (s->code, tree->right->data.ainfo.basereg,
- tree->right->data.ainfo.offset);
+ x86_call_membase (s->code, tree->left->data.ainfo.basereg,
+ tree->left->data.ainfo.offset);
break;
default:
g_assert_not_reached ();