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);
%%
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)),
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 (call, tree->dreg, tree->unused, FALSE);
+ mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->unused, FALSE);
}
stmt: OP_OUTARG_REG (OP_I8CONST),
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 (OP_REGVAR)),
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_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) {
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) {
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;
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;
}
}
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);
}
}
+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)
{