};
#undef OPDEF
-#define SET_VARINFO(vi,t,k,o,s) do { vi.type=t; vi.kind=k; vi.offset=o; vi.size=s; } while (0)
+#define SET_VARINFO(vi,t,k,o,s) do { vi.type=t; vi.kind=k; vi.offset=o; vi.size=s; } while (0)
#define MAKE_CJUMP(name) \
case CEE_##name: \
break; \
}
-#define MAKE_CMP(name) \
-case CEE_##name: { \
+#define MAKE_CMP(cname) \
+case CEE_##cname: { \
++ip; \
sp -= 2; \
- t1 = mono_ctree_new (mp, MB_TERM_##name, sp [0], sp [1]); \
+ t1 = mono_ctree_new (mp, MB_TERM_##cname, sp [0], sp [1]); \
g_assert (sp [0]->svt == sp [1]->svt); \
PUSH_TREE (t1, VAL_I32); \
break; \
t1->svt = sp [0]->svt; \
t1 = mono_store_tree (cfg, -1, t1, &t2); \
g_assert (t1); \
- ADD_TREE (t1, cli_addr); \
+ ADD_TREE (t1, cli_addr); \
PUSH_TREE (t2, t2->svt); \
break; \
}
{
switch (svt) {
case VAL_I32:
- case VAL_POINTER:
return MB_TERM_STIND_I4;
+ case VAL_POINTER:
+ return MB_TERM_STIND_REF;
case VAL_I64:
return MB_TERM_STIND_I8;
case VAL_DOUBLE:
map_stind_type (MonoType *type)
{
if (type->byref)
- return MB_TERM_STIND_I4;
+ return MB_TERM_STIND_REF;
switch (type->type) {
case MONO_TYPE_I1:
case MONO_TYPE_I:
case MONO_TYPE_I4:
case MONO_TYPE_U4:
+ return MB_TERM_STIND_I4;
case MONO_TYPE_CLASS:
case MONO_TYPE_OBJECT:
case MONO_TYPE_STRING:
case MONO_TYPE_PTR:
case MONO_TYPE_SZARRAY:
case MONO_TYPE_ARRAY:
- return MB_TERM_STIND_I4;
+ return MB_TERM_STIND_REF;
case MONO_TYPE_I8:
case MONO_TYPE_U8:
return MB_TERM_STIND_I8;
map_starg_type (MonoType *type)
{
if (type->byref)
- return MB_TERM_STIND_I4;
+ return MB_TERM_STIND_REF;
switch (type->type) {
case MONO_TYPE_I1:
case MONO_TYPE_I:
case MONO_TYPE_I4:
case MONO_TYPE_U4:
+ return MB_TERM_STIND_I4;
case MONO_TYPE_CLASS:
case MONO_TYPE_OBJECT:
case MONO_TYPE_STRING:
case MONO_TYPE_PTR:
case MONO_TYPE_SZARRAY:
case MONO_TYPE_ARRAY:
- return MB_TERM_STIND_I4;
+ return MB_TERM_STIND_REF;
case MONO_TYPE_I8:
case MONO_TYPE_U8:
return MB_TERM_STIND_I8;
{
if (type->byref) {
*svt = VAL_POINTER;
- return MB_TERM_LDIND_I4;
+ return MB_TERM_LDIND_REF;
}
switch (type->type) {
case MONO_TYPE_SZARRAY:
case MONO_TYPE_ARRAY:
*svt = VAL_POINTER;
- return MB_TERM_LDIND_U4;
+ return MB_TERM_LDIND_REF;
case MONO_TYPE_I8:
case MONO_TYPE_U8:
*svt = VAL_I64;
{
if (type->byref) {
*svt = VAL_POINTER;
- return MB_TERM_LDIND_I4;
+ return MB_TERM_LDIND_REF;
}
switch (type->type) {
case MONO_ARGVAR: {
int arg_start = 8 + cfg->has_vtarg*4;
+ /* fixme: we need to align stack values somehow
+ int opos, cpos, padding;
+ opos = cpos = arg_start + cfg->args_size;
+ cpos += align - 1;
+ cpos &= ~(align - 1);
+ padding = cpos - opos;
+ cfg->args_size += padding;
+ */
+
SET_VARINFO (vi, type, kind, cfg->args_size + arg_start, size);
g_array_append_val (cfg->varinfo, vi);
-
- cfg->args_size += align - 1;
- cfg->args_size &= ~(align - 1);
+
cfg->args_size += size;
break;
}
t = mono_ctree_new (mp, MB_TERM_LDIND_I2, t, NULL);
t->svt = VAL_I32;
break;
+ case MB_TERM_STIND_REF:
+ case MB_TERM_LDIND_REF:
+ t = ctree_dup_address (mp, s->left);
+ t = mono_ctree_new (mp, MB_TERM_LDIND_REF, t, NULL);
+ t->svt = VAL_POINTER;
+ break;
case MB_TERM_STIND_I4:
case MB_TERM_LDIND_I4:
t = ctree_dup_address (mp, s->left);
case MB_TERM_LDIND_I2:
case MB_TERM_STIND_I4:
case MB_TERM_LDIND_I4:
+ case MB_TERM_STIND_REF:
+ case MB_TERM_LDIND_REF:
case MB_TERM_STIND_I8:
case MB_TERM_LDIND_I8:
case MB_TERM_STIND_R4:
int align, size;
for (i = 0; i < signature->param_count; ++i) {
- size = mono_type_size (signature->params [i], &align);
- if (size < 4) {
- size = 4;
- align = 4;
- }
+ size = mono_type_stack_size (signature->params [i], &align);
arch_allocate_var (cfg, size, align, MONO_ARGVAR, VAL_UNKNOWN);
}
}
g_assert (t1);
ADD_TREE (t1, cli_addr);
}
+
+ args_size += sizeof (gpointer); /* this argument */
for (i = csig->param_count - 1; i >= 0; i--) {
MonoType *type = cm->signature->params [i];
+
+ size = mono_type_stack_size (type, &align);
t1 = mono_ctree_new (mp, map_arg_type (type, FALSE), arg_sp [i], NULL);
- size = mono_type_size (type, &align);
t1->data.i = size;
ADD_TREE (t1, cli_addr);
- args_size += (size + 3) & ~3;
+ args_size += size;
}
- args_size += sizeof (gpointer); /* this argument */
ci->args_size = args_size;
if (newarr) {
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);
+ t2 = mono_ctree_new (mp, MB_TERM_LDIND_REF, t2, NULL);
t1 = mono_ctree_new (mp, map_call_type (csig->ret, &svt), this, t2);
t1->data.p = ci;
for (i = nargs - 1; i >= 0; i--) {
MonoType *type = cm->signature->params [i];
t1 = mono_ctree_new (mp, map_arg_type (type, pinvoke), arg_sp [i], NULL);
- size = mono_type_size (type, &align);
+ size = mono_type_stack_size (type, &align);
t1->data.i = size;
ADD_TREE (t1, cli_addr);
- args_size += (size + 3) & ~3;
-
+ args_size += size;
// fixme: align value type arguments to 8 byte boundary on the stack
}
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);
+ t2 = mono_ctree_new (mp, MB_TERM_LDIND_REF, t2, NULL);
}
t1 = mono_ctree_new (mp, map_call_type (csig->ret, &svt), this, t2);
t1 = mono_ctree_new (mp, MB_TERM_ISINST, *sp, NULL);
t1->data.klass = c;
- PUSH_TREE (t1, VAL_I32);
+ PUSH_TREE (t1, VAL_POINTER);
ip += 4;
break;
t1 = mono_ctree_new (mp, MB_TERM_CASTCLASS, *sp, NULL);
t1->data.klass = c;
- PUSH_TREE (t1, VAL_I32);
+ PUSH_TREE (t1, VAL_POINTER);
ip += 4;
break;
++ip;
t1 = mono_ctree_new_leaf (mp, MB_TERM_CONST_I4);
t1->data.i = 0;
- PUSH_TREE (t1, VAL_I32);
+ PUSH_TREE (t1, VAL_POINTER);
break;
}
case CEE_LDC_I8: {
MAKE_LDIND (LDIND_U2, MB_TERM_LDIND_U2, VAL_I32)
MAKE_LDIND (LDIND_I, MB_TERM_LDIND_I4, VAL_I32)
MAKE_LDIND (LDIND_I4, MB_TERM_LDIND_I4, VAL_I32)
- MAKE_LDIND (LDIND_REF, MB_TERM_LDIND_U4, VAL_I32)
+ MAKE_LDIND (LDIND_REF, MB_TERM_LDIND_REF, VAL_POINTER)
MAKE_LDIND (LDIND_U4, MB_TERM_LDIND_U4, VAL_I32)
MAKE_LDIND (LDIND_I8, MB_TERM_LDIND_I8, VAL_I64)
MAKE_LDIND (LDIND_R4, MB_TERM_LDIND_R4, VAL_DOUBLE)
MAKE_STIND (STIND_I8, MB_TERM_STIND_I8)
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_STIND (STIND_REF, MB_TERM_STIND_REF)
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_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_REF, MB_TERM_LDIND_REF, VAL_POINTER, sizeof (gpointer))
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_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)
+ MAKE_STELEM (STELEM_REF, MB_TERM_STIND_REF, sizeof (gpointer))
MAKE_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)
t1 = mono_ctree_new_leaf (mp, MB_TERM_ADDR_G);
t1->data.p = (char *)cm + G_STRUCT_OFFSET (MonoMethod, addr);
- t1 = mono_ctree_new (mp, MB_TERM_LDIND_I4, t1, NULL);
+ t1 = mono_ctree_new (mp, MB_TERM_LDIND_REF, t1, NULL);
PUSH_TREE (t1, VAL_POINTER);
break;
}
# constatnts
%term CONST_I4 CONST_I8 CONST_R4 CONST_R8
-%term LDIND_I1 LDIND_U1 LDIND_I2 LDIND_U2 LDIND_I4 LDIND_I8 LDIND_R4 LDIND_R8
+%term LDIND_I1 LDIND_U1 LDIND_I2 LDIND_U2 LDIND_I4 LDIND_REF 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 STIND_I1 STIND_I2 STIND_I4 STIND_REF STIND_I8 STIND_R4 STIND_R8 STIND_OBJ
%term ADDR_L ADDR_G ARG_I4 ARG_I8 ARG_R4 ARG_R8 ARG_OBJ ARG_STRING CALL_I4 CALL_I8 CALL_R8 CALL_VOID
%term BREAK SWITCH BR RET_VOID RET RET_OBJ ENDFINALLY
%term ADD ADD_OVF ADD_OVF_UN SUB SUB_OVF SUB_OVF_UN MUL MUL_OVF MUL_OVF_UN
}
}
+stmt: STIND_REF (addr, reg) {
+ PRINT_REG ("STIND_REF", tree->right->reg1);
+
+ switch (tree->left->data.ainfo.amode) {
+
+ case AMImmediate:
+ x86_mov_mem_reg (s->code, tree->left->data.ainfo.offset, tree->right->reg1, 4);
+ break;
+
+ case AMBase:
+ x86_mov_membase_reg (s->code, tree->left->data.ainfo.basereg,
+ tree->left->data.ainfo.offset, tree->right->reg1, 4);
+ break;
+ case AMIndex:
+ x86_mov_memindex_reg (s->code, X86_NOBASEREG, tree->left->data.ainfo.offset,
+ tree->left->data.ainfo.indexreg, tree->left->data.ainfo.shift,
+ tree->right->reg1, 4);
+ break;
+ case AMBaseIndex:
+ x86_mov_memindex_reg (s->code, tree->left->data.ainfo.basereg, tree->left->data.ainfo.offset,
+ tree->left->data.ainfo.indexreg, tree->left->data.ainfo.shift,
+ tree->right->reg1, 4);
+ break;
+ }
+}
+
stmt: STIND_I1 (addr, reg) {
PRINT_REG ("STIND_I1", tree->right->reg1);
PRINT_REG ("LDIND_I4", tree->reg1);
}
+reg: LDIND_REF (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;
+ }
+
+
+ PRINT_REG ("LDIND_REF", tree->reg1);
+}
+
reg: LDIND_I1 (addr) {
switch (tree->left->data.ainfo.amode) {
g_assert (tree->reg1 == X86_EAX);
}
-reg: CALL_I4 (this, LDIND_I4 (ADDR_G)) {
+reg: CALL_I4 (this, LDIND_REF (ADDR_G)) {
MethodCallInfo *ci = tree->data.ci;
int lreg = tree->left->reg1;
int treg = X86_EAX;
g_assert (tree->reg1 == X86_EAX);
}
-stmt: CALL_VOID (this, LDIND_I4 (ADDR_G)) {
+stmt: CALL_VOID (this, LDIND_REF (ADDR_G)) {
MethodCallInfo *ci = tree->data.ci;
int lreg = tree->left->reg1;
int treg = X86_EAX;
tree->reg2 == X86_EDX);
}
-lreg: CALL_I8 (this, LDIND_I4 (ADDR_G)) {
+lreg: CALL_I8 (this, LDIND_REF (ADDR_G)) {
MethodCallInfo *ci = tree->data.ci;
int lreg = tree->left->reg1;
int treg = X86_EAX;
x86_branch32 (s->code, X86_CC_NE, tree->data.bb->addr - offset, FALSE);
}
-freg: CALL_R8 (this, LDIND_I4 (ADDR_G)) {
+freg: CALL_R8 (this, LDIND_REF (ADDR_G)) {
MethodCallInfo *ci = tree->data.ci;
int lreg = tree->left->reg1;
int treg = X86_EAX;