X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Finssel-ia64.brg;h=decc72c06903aede70a08d48e9c93dabb7a43519;hb=6644c191b8292d9a07227f182be9ce689c1848e2;hp=69fa21f81f2e5a61b8dc4ae269269a990e713017;hpb=cc6ba78383baff197d1ce3a8404de46fb5ff660a;p=mono.git diff --git a/mono/mini/inssel-ia64.brg b/mono/mini/inssel-ia64.brg index 69fa21f81f2..decc72c0690 100644 --- a/mono/mini/inssel-ia64.brg +++ b/mono/mini/inssel-ia64.brg @@ -1,5 +1,6 @@ int size_to_ia64_load_u_membase_inc (int size); +int size_to_store_membase_reg (int size); int size_to_ia64_store_membase_inc_reg (int size); %% @@ -135,7 +136,56 @@ stmt: OP_OUTARG_REG (reg) { tree->dreg = mono_regstate_next_int (s->rs); mono_bblock_add_inst (s->cbb, tree); - mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE); + mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->unused, FALSE); +} + +stmt: OP_OUTARG_REG (CEE_LDIND_I (base)), +stmt: OP_OUTARG_REG (CEE_LDIND_REF (base)), +stmt: OP_OUTARG_REG (CEE_LDIND_I1 (base)), +stmt: OP_OUTARG_REG (CEE_LDIND_U1 (base)), +stmt: OP_OUTARG_REG (CEE_LDIND_I2 (base)), +stmt: OP_OUTARG_REG (CEE_LDIND_U2 (base)), +stmt: OP_OUTARG_REG (CEE_LDIND_I4 (base)), +stmt: OP_OUTARG_REG (CEE_LDIND_U4 (base)), +stmt: OP_OUTARG_REG (CEE_LDIND_I8 (base)) { + /* FIXME: Move this to inssel.brg or inssel-long.brg */ + MonoCallInst *call = (MonoCallInst*)tree->inst_right; + guint32 dreg; + MonoInst *base = state->left->left->tree; + + dreg = mono_regstate_next_int (s->rs); + MONO_EMIT_LOAD_MEMBASE_OP (s, tree, ldind_to_load_membase (state->left->tree->opcode), + dreg, base->inst_basereg, base->inst_offset); + + mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->unused, FALSE); +} + +stmt: OP_OUTARG_REG (OP_I8CONST), +stmt: OP_OUTARG_REG (OP_ICONST) { + /* FIXME: Move this to inssel.brg or inssel-long.brg */ + MonoCallInst *call = (MonoCallInst*)tree->inst_right; + + tree->opcode = OP_ICONST; + tree->inst_c0 = state->left->tree->inst_c0; + tree->dreg = mono_regstate_next_int (s->rs); + mono_bblock_add_inst (s->cbb, tree); + + mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->unused, FALSE); +} + +stmt: OP_OUTARG_REG (CEE_LDIND_I (OP_REGVAR)), +stmt: OP_OUTARG_REG (CEE_LDIND_I8 (OP_REGVAR)), +stmt: OP_OUTARG_REG (CEE_LDIND_I4 (OP_REGVAR)), +stmt: OP_OUTARG_REG (CEE_LDIND_U4 (OP_REGVAR)), +stmt: OP_OUTARG_REG (CEE_LDIND_REF (OP_REGVAR)) { + MonoCallInst *call = (MonoCallInst*)tree->inst_right; + + tree->opcode = OP_MOVE; + tree->sreg1 = state->left->left->tree->dreg; + tree->dreg = mono_regstate_next_int (s->rs); + mono_bblock_add_inst (s->cbb, tree); + + mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->unused, FALSE); } stmt: OP_OUTARG_FREG (freg) { @@ -146,7 +196,7 @@ stmt: OP_OUTARG_FREG (freg) { tree->dreg = mono_regstate_next_float (s->rs); mono_bblock_add_inst (s->cbb, tree); - mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, TRUE); + mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->unused, TRUE); } stmt: OP_OUTARG (reg) { @@ -172,7 +222,7 @@ stmt: OP_OUTARG_REG (CEE_LDOBJ (OP_REGOFFSET)) { tree->dreg = mono_regstate_next_int (s->rs); mono_bblock_add_inst (s->cbb, tree); - mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE); + mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->unused, FALSE); } stmt: OP_SETRET (reg) { @@ -254,10 +304,17 @@ reg: OP_ATOMIC_ADD_NEW_I8 (base, OP_ICONST) { tree->inst_offset = state->left->tree->inst_offset; mono_bblock_add_inst (s->cbb, tree); +} cost { + int imm = state->right->tree->inst_imm; + + MBCOND (imm == 1 || imm == 4 || imm == 8 || imm == 16 || imm == -1 || imm == -4 || imm == -8 || imm == -16); + return 1; } reg: OP_ATOMIC_EXCHANGE_I4 (base, reg), -reg: OP_ATOMIC_EXCHANGE_I8 (base, reg) { +reg: OP_ATOMIC_EXCHANGE_I8 (base, reg), +reg: OP_ATOMIC_ADD_NEW_I4 (base, reg), +reg: OP_ATOMIC_ADD_NEW_I8 (base, reg) { tree->opcode = tree->opcode; tree->dreg = state->reg1; tree->sreg2 = state->right->reg1; @@ -290,23 +347,29 @@ stmt: OP_MEMSET (base) "0" { MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, dest_reg, state->left->tree->inst_basereg, state->left->tree->inst_offset); - /* FIXME: Alignment */ for (unit = align; unit >= 1; unit = unit >> 1) { dest_reg2 = mono_regstate_next_int (s->rs); /* Use two destination regs to increase paralellism */ if (size >= 2 * unit) { - MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, dest_reg2, state->left->tree->inst_basereg, state->left->tree->inst_offset + unit); + int diff = (size / (2 * unit)) * unit; + MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, dest_reg2, state->left->tree->inst_basereg, state->left->tree->inst_offset + diff); while (size >= (2 * unit)) { MONO_EMIT_NEW_STORE_MEMBASE (s, size_to_ia64_store_membase_inc_reg (unit), dest_reg, 0, val_reg); MONO_EMIT_NEW_STORE_MEMBASE (s, size_to_ia64_store_membase_inc_reg (unit), dest_reg2, 0, val_reg); size -= 2 * unit; } + + if (size > 0) + MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, dest_reg, dest_reg, diff); } while (size >= unit) { - MONO_EMIT_NEW_STORE_MEMBASE (s, size_to_ia64_store_membase_inc_reg (unit), dest_reg, 0, val_reg); + if (size == unit) + MONO_EMIT_NEW_STORE_MEMBASE (s, size_to_store_membase_reg (unit), dest_reg, 0, val_reg); + else + MONO_EMIT_NEW_STORE_MEMBASE (s, size_to_ia64_store_membase_inc_reg (unit), dest_reg, 0, val_reg); size -= unit; } } @@ -332,9 +395,7 @@ stmt: OP_MEMCPY (base, base) "0" { MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, dest_reg, state->left->tree->inst_basereg, state->left->tree->inst_offset); MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, src_reg, state->right->tree->inst_basereg, state->right->tree->inst_offset); - /* FIXME: Alignment */ for (unit = align; unit >= 1; unit = unit >> 1) { - while (size >= unit) { cur_reg = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, size_to_ia64_load_u_membase_inc (unit), cur_reg, src_reg, 0); @@ -364,6 +425,24 @@ size_to_ia64_load_u_membase_inc (int size) } } +int +size_to_store_membase_reg (int size) +{ + switch (size) { + case 1: + return OP_STOREI1_MEMBASE_REG; + case 2: + return OP_STOREI2_MEMBASE_REG; + case 4: + return OP_STOREI4_MEMBASE_REG; + case 8: + return OP_STOREI8_MEMBASE_REG; + default: + g_assert_not_reached (); + return -1; + } +} + int size_to_ia64_store_membase_inc_reg (int size) {