# (C) 2002 Ximian, Inc.
#
+stmt: CEE_STIND_I8 (OP_REGVAR, reg) {
+ MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->left->tree->dreg, state->right->reg1);
+}
+
+reg: CEE_LDIND_I8 (OP_REGVAR) {
+ MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->tree->dreg);
+}
+
stmt: CEE_STIND_I8 (OP_REGVAR, lreg) {
/* this should only happen for methods returning a long */
MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->left->tree->dreg, state->right->reg2);
MONO_EMIT_UNALU (s, tree, OP_FMOVE, state->reg1, state->left->reg1);
}
+freg: CEE_LDIND_R8 (OP_REGVAR) {
+ MONO_EMIT_UNALU (s, tree, OP_FMOVE, state->reg1, state->left->tree->dreg);
+}
+
+freg: CEE_LDIND_R4 (OP_REGVAR) {
+ MONO_EMIT_UNALU (s, tree, OP_FMOVE, state->reg1, state->left->tree->dreg);
+}
+
reg: OP_LOCALLOC (reg) {
tree->sreg1 = state->left->reg1;
tree->dreg = state->reg1;
}
stmt: OP_OUTARG (OP_LDADDR (reg)) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
tree->opcode = OP_SETREG;
- tree->dreg = tree->unused;
+ tree->dreg = mono_regstate_next_int (s->rs);
tree->sreg1 = state->left->left->tree->dreg;
mono_bblock_add_inst (s->cbb, tree);
+
+ mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE);
}
stmt: OP_SETRET (reg) {
}
stmt: OP_OUTARG (reg) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
tree->opcode = OP_SETREG;
- tree->dreg = tree->unused;
+ tree->dreg = mono_regstate_next_int (s->rs);
tree->sreg1 = state->left->reg1;
mono_bblock_add_inst (s->cbb, tree);
+
+ mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE);
}
stmt: OP_OUTARG (OP_REGVAR) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
tree->opcode = OP_SETREG;
- tree->dreg = tree->unused;
+ tree->dreg = mono_regstate_next_int (s->rs);
tree->sreg1 = state->left->tree->dreg;
mono_bblock_add_inst (s->cbb, tree);
-}
-stmt: OP_OUTARG (freg) {
- /* floating-point <-> integer transfer must go through memory */
- MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, tree->inst_basereg,
- tree->inst_imm, state->left->reg1);
- MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
+ mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE);
}
stmt: OP_OUTARG (OP_ICONST) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
+ tree->opcode = OP_SETREGIMM;
+ tree->dreg = mono_regstate_next_int (s->rs);
+ tree->inst_c0 = state->left->tree->inst_c0;
+ mono_bblock_add_inst (s->cbb, tree);
+
+ mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE);
+}
+
+stmt: OP_OUTARG (OP_I8CONST) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
tree->opcode = OP_SETREGIMM;
- tree->dreg = tree->unused;
+ tree->dreg = mono_regstate_next_int (s->rs);
tree->inst_c0 = state->left->tree->inst_c0;
mono_bblock_add_inst (s->cbb, tree);
+
+ mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE);
+} cost {
+ MBCOND (sizeof (gpointer) == 8);
+
+ return 0;
}
stmt: OP_OUTARG (CEE_LDIND_R4 (base)) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
tree->opcode = OP_LOADI4_MEMBASE;
- tree->dreg = tree->unused;
+ tree->dreg = mono_regstate_next_int (s->rs);
tree->inst_basereg = state->left->left->tree->inst_basereg;
tree->inst_offset = state->left->left->tree->inst_offset;
mono_bblock_add_inst (s->cbb, tree);
+
+ mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE);
+}
+
+stmt: OP_SPARC_OUTARG_FLOAT (freg) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+ int dreg = mono_regstate_next_int (s->rs);
+ /* floating-point <-> integer transfer must go through memory */
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, tree->inst_right->inst_basereg,
+ tree->inst_right->inst_imm, state->left->reg1);
+ MONO_EMIT_NEW_LOAD_MEMBASE (s, dreg, tree->inst_right->inst_basereg, tree->inst_right->inst_imm);
+
+ mono_call_inst_add_outarg_reg (call, dreg, tree->unused, FALSE);
}
stmt: OP_SPARC_OUTARG_REGPAIR (lreg) {
- MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+ int dreg = mono_regstate_next_int (s->rs);
+ int dreg2 = mono_regstate_next_int (s->rs);
+
+ MONO_EMIT_NEW_UNALU (s, OP_SETREG, dreg, state->left->reg2);
tree->opcode = OP_SETREG;
- tree->dreg = tree->unused + 1;
+ tree->dreg = dreg2;
tree->sreg1 = state->left->reg1;
mono_bblock_add_inst (s->cbb, tree);
+
+ mono_call_inst_add_outarg_reg (call, dreg, tree->unused, FALSE);
+ mono_call_inst_add_outarg_reg (call, dreg2, tree->unused + 1, FALSE);
}
-stmt: OP_SPARC_OUTARG_REGPAIR (freg) {
- MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
- tree->inst_imm, state->left->reg1);
+stmt: OP_SPARC_OUTARG_REGPAIR_FLOAT (freg) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+ int dreg = mono_regstate_next_int (s->rs);
+ int dreg2 = mono_regstate_next_int (s->rs);
+
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_right->inst_basereg,
+ tree->inst_right->inst_imm, state->left->reg1);
/* floating-point <-> integer transfer must go through memory */
/* Load into a register pair */
- MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
- MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused + 1, tree->inst_basereg, tree->inst_imm + 4);
+ MONO_EMIT_NEW_LOAD_MEMBASE (s, dreg, tree->inst_right->inst_basereg, tree->inst_right->inst_imm);
+ MONO_EMIT_NEW_LOAD_MEMBASE (s, dreg2, tree->inst_right->inst_basereg, tree->inst_right->inst_imm + 4);
+
+ mono_call_inst_add_outarg_reg (call, dreg, tree->unused, FALSE);
+ mono_call_inst_add_outarg_reg (call, dreg2, tree->unused + 1, FALSE);
}
stmt: OP_SPARC_OUTARG_MEM (reg) {
- if (tree->inst_imm & 0x1)
- tree->opcode = OP_STOREI1_MEMBASE_REG;
- else if (tree->inst_imm & 0x2)
- tree->opcode = OP_STOREI2_MEMBASE_REG;
- else
- tree->opcode = OP_STOREI4_MEMBASE_REG;
- tree->inst_destbasereg = tree->inst_basereg;
- tree->inst_offset = tree->inst_imm;
+ guint32 offset = tree->inst_right->inst_imm;
+ if (mono_sparc_is_sparc64 ()) {
+ guint32 real_offset = tree->inst_right->inst_imm - MONO_SPARC_STACK_BIAS;
+ /* Correct for the additions in get_call_info () */
+ offset = MONO_SPARC_STACK_BIAS + (real_offset & ~(7));
+ tree->opcode = OP_STOREI8_MEMBASE_REG;
+ }
+ else {
+ if (offset & 0x1)
+ tree->opcode = OP_STOREI1_MEMBASE_REG;
+ else if (offset & 0x2)
+ tree->opcode = OP_STOREI2_MEMBASE_REG;
+ else
+ tree->opcode = OP_STOREI4_MEMBASE_REG;
+ }
+ tree->inst_destbasereg = tree->inst_right->inst_basereg;
+ tree->inst_offset = offset;
tree->sreg1 = state->left->reg1;
mono_bblock_add_inst (s->cbb, tree);
}
stmt: OP_SPARC_OUTARG_MEM (freg) {
- MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, tree->inst_basereg,
- tree->inst_imm, state->left->reg1);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, tree->inst_right->inst_basereg,
+ tree->inst_right->inst_imm, state->left->reg1);
}
stmt: OP_SPARC_OUTARG_MEMPAIR (lreg) {
- MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, tree->inst_basereg,
- tree->inst_imm, state->left->reg2);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, tree->inst_right->inst_basereg,
+ tree->inst_right->inst_imm, state->left->reg2);
tree->opcode = OP_STOREI4_MEMBASE_REG;
- tree->inst_destbasereg = tree->inst_basereg;
- tree->inst_offset = tree->inst_imm + 4;
+ tree->inst_destbasereg = tree->inst_right->inst_basereg;
+ tree->inst_offset = tree->inst_right->inst_imm + 4;
tree->sreg1 = state->left->reg1;
mono_bblock_add_inst (s->cbb, tree);
}
stmt: OP_SPARC_OUTARG_MEMPAIR (freg) {
- MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
- tree->inst_imm, state->left->reg1);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_right->inst_basereg,
+ tree->inst_right->inst_imm, state->left->reg1);
}
stmt: OP_SPARC_OUTARG_SPLIT_REG_STACK (lreg) {
- MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
+ int dreg = mono_regstate_next_int (s->rs);
+ MONO_EMIT_NEW_UNALU (s, OP_SETREG, dreg, state->left->reg2);
tree->opcode = OP_STOREI4_MEMBASE_REG;
- tree->inst_destbasereg = tree->inst_basereg;
- tree->inst_offset = tree->inst_imm + 4;
+ tree->inst_destbasereg = tree->inst_right->inst_basereg;
+ tree->inst_offset = tree->inst_right->inst_imm + 4;
tree->sreg1 = state->left->reg1;
mono_bblock_add_inst (s->cbb, tree);
+
+ mono_call_inst_add_outarg_reg (call, dreg, tree->unused, FALSE);
}
stmt: OP_SPARC_OUTARG_SPLIT_REG_STACK (freg) {
- MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_basereg,
- tree->inst_imm, state->left->reg1);
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
+ int dreg = mono_regstate_next_int (s->rs);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, tree->inst_right->inst_basereg,
+ tree->inst_right->inst_imm, state->left->reg1);
/* floating-point <-> integer transfer must go through memory */
/* Load most significant word into register */
- MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, tree->inst_basereg, tree->inst_imm);
+ MONO_EMIT_NEW_LOAD_MEMBASE (s, dreg, tree->inst_right->inst_basereg, tree->inst_right->inst_imm);
+
+ mono_call_inst_add_outarg_reg (call, dreg, tree->unused, FALSE);
}
+stmt: OP_SPARC_OUTARG_FLOAT_REG (freg) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
+ tree->opcode = OP_SPARC_SETFREG_FLOAT;
+ tree->dreg = mono_regstate_next_int (s->rs);
+ tree->sreg1 = state->left->reg1;
+ mono_bblock_add_inst (s->cbb, tree);
+
+ mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, TRUE);
+}
+
+stmt: OP_SPARC_OUTARG_DOUBLE_REG (freg) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
+ tree->opcode = OP_SETFREG;
+ tree->dreg = mono_regstate_next_int (s->rs);
+ tree->sreg1 = state->left->reg1;
+ mono_bblock_add_inst (s->cbb, tree);
+
+ mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, TRUE);
+}
+
# Handles scalar valuetypes like RuntimeTypeHandle
reg: OP_OUTARG_VT (OP_ICONST) {
MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, sparc_sp, tree->inst_c1, state->left->tree->inst_c0);
MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
}
+reg: OP_OUTARG_VT (OP_AOTCONST) {
+ MONO_EMIT_NEW_AOTCONST (s, state->reg1, state->left->tree->inst_p0, state->left->tree->inst_c1);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, sparc_sp, tree->inst_c1, state->reg1);
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
+}
+
+# FIXME: Unify this with the previous rule
+reg: OP_OUTARG_VT (OP_REFANYTYPE (reg)) {
+ MONO_EMIT_NEW_LOAD_MEMBASE (s, state->reg1, state->left->left->reg1, G_STRUCT_OFFSET (MonoTypedRef, type));
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, sparc_sp, tree->inst_c1, state->reg1);
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, sparc_sp, tree->inst_c1);
+}
+
reg: OP_OUTARG_VT (base) {
int size = tree->unused;
mini_emit_memcpy (s, sparc_sp, tree->inst_c1, state->left->tree->inst_basereg, state->left->tree->inst_offset, size, 0);
}
stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
tree->opcode = OP_SETREG;
tree->sreg1 = state->left->left->tree->dreg;
- tree->dreg = tree->unused;
+ 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);
}
stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGOFFSET)) {
- MONO_EMIT_NEW_LOAD_MEMBASE (s, tree->unused, state->left->left->tree->inst_basereg,
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
+ int dreg = mono_regstate_next_int (s->rs);
+ MONO_EMIT_NEW_LOAD_MEMBASE (s, dreg, state->left->left->tree->inst_basereg,
state->left->left->tree->inst_offset);
+
+ mono_call_inst_add_outarg_reg (call, dreg, tree->unused, FALSE);
}
stmt: OP_OUTARG_VT (OP_ICONST) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
tree->opcode = OP_SETREGIMM;
- tree->dreg = tree->unused;
+ tree->dreg = mono_regstate_next_int (s->rs);
tree->inst_imm = state->left->tree->inst_c0;
mono_bblock_add_inst (s->cbb, tree);
+
+ mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE);
}
stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
# Optimizations
#
+reg: CEE_LDIND_REF (OP_REGVAR),
+reg: CEE_LDIND_I (OP_REGVAR),
+reg: CEE_LDIND_I4 (OP_REGVAR),
+reg: CEE_LDIND_U4 (OP_REGVAR) "0" {
+ /* This rule might not work on all archs, hence it is sparc only */
+ state->reg1 = state->left->tree->dreg;
+ tree->dreg = state->reg1;
+}
+
stmt: CEE_STIND_I1 (OP_REGVAR, OP_ICONST) {
tree->opcode = OP_ICONST;
tree->dreg = state->left->tree->dreg;
mono_bblock_add_inst (s->cbb, tree);
}
-stmt: OP_SETRET (CEE_LDIND_REF(base)) {
- MONO_EMIT_LOAD_MEMBASE (s, tree, sparc_i0, state->left->left->tree->inst_basereg,
- state->left->left->tree->inst_offset);
+stmt: CEE_STIND_I4 (OP_REGVAR, CEE_ADD (reg, OP_ICONST)) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->left->tree->dreg, state->right->left->reg1, state->right->right->tree->inst_c0);
+}
+
+stmt: CEE_STIND_REF (OP_REGVAR, CEE_ADD (reg, OP_ICONST)) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->left->tree->dreg, state->right->left->reg1, state->right->right->tree->inst_c0);
+}
+
+stmt: CEE_STIND_I4 (OP_REGVAR, CEE_SUB (reg, OP_ICONST)) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_SUB_IMM, state->left->tree->dreg, state->right->left->reg1, state->right->right->tree->inst_c0);
+}
+
+stmt: CEE_STIND_REF (OP_REGVAR, CEE_SUB (reg, OP_ICONST)) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_SUB_IMM, state->left->tree->dreg, state->right->left->reg1, state->right->right->tree->inst_c0);
+}
+
+stmt: CEE_STIND_I4 (OP_REGVAR, CEE_ADD (reg, reg)) {
+ MONO_EMIT_BIALU (s, tree, CEE_ADD, state->left->tree->dreg, state->right->left->reg1, state->right->right->reg1);
+}
+
+stmt: CEE_STIND_REF (OP_REGVAR, CEE_ADD (reg, reg)) {
+ MONO_EMIT_BIALU (s, tree, CEE_ADD, state->left->tree->dreg, state->right->left->reg1, state->right->right->reg1);
+}
+
+stmt: CEE_STIND_I4 (OP_REGVAR, CEE_LDIND_I4(base)) {
+ MONO_EMIT_LOAD_MEMBASE (s, tree, state->left->tree->dreg, state->right->left->tree->inst_basereg,
+ state->right->left->tree->inst_offset);
mono_bblock_add_inst (s->cbb, tree);
}
-stmt: OP_SETRET (CEE_LDIND_I4(base)) {
- MONO_EMIT_LOAD_MEMBASE (s, tree, sparc_i0, state->left->left->tree->inst_basereg,
- state->left->left->tree->inst_offset);
+stmt: CEE_STIND_REF (OP_REGVAR, CEE_LDIND_REF(base)) {
+ MONO_EMIT_LOAD_MEMBASE (s, tree, state->left->tree->dreg, state->right->left->tree->inst_basereg,
+ state->right->left->tree->inst_offset);
mono_bblock_add_inst (s->cbb, tree);
}
-stmt: OP_SETRET (CEE_LDIND_I(base)) {
- MONO_EMIT_LOAD_MEMBASE (s, tree, sparc_i0, state->left->left->tree->inst_basereg,
- state->left->left->tree->inst_offset);
+stmt: OP_SETRET (CEE_LDIND_I1(base)),
+stmt: OP_SETRET (CEE_LDIND_U1(base)),
+stmt: OP_SETRET (CEE_LDIND_I2(base)),
+stmt: OP_SETRET (CEE_LDIND_U2(base)),
+stmt: OP_SETRET (CEE_LDIND_I(base)),
+stmt: OP_SETRET (CEE_LDIND_REF(base)),
+stmt: OP_SETRET (CEE_LDIND_I4(base)),
+stmt: OP_SETRET (CEE_LDIND_U4(base)) {
+ MONO_EMIT_LOAD_MEMBASE_OP (s, tree, ldind_to_load_membase (state->left->tree->opcode),
+ sparc_i0, state->left->left->tree->inst_basereg, state->left->left->tree->inst_offset);
mono_bblock_add_inst (s->cbb, tree);
}
mono_bblock_add_inst (s->cbb, tree);
}
-stmt: OP_OUTARG (CEE_LDIND_I (OP_REGVAR)) {
+stmt: OP_OUTARG (CEE_LDIND_I (OP_REGVAR)),
+stmt: OP_OUTARG (CEE_LDIND_I4 (OP_REGVAR)) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
tree->opcode = OP_SETREG;
- tree->dreg = tree->unused;
+ tree->dreg = mono_regstate_next_int (s->rs);
tree->sreg1 = state->left->left->tree->dreg;
mono_bblock_add_inst (s->cbb, tree);
+
+ mono_call_inst_add_outarg_reg (call, tree->dreg, tree->unused, FALSE);
}
-stmt: OP_OUTARG (CEE_LDIND_I4 (OP_REGVAR)) {
- tree->opcode = OP_SETREG;
- tree->dreg = tree->unused;
- tree->sreg1 = state->left->left->tree->dreg;
+stmt: OP_OUTARG (CEE_LDIND_REF(base)) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
+ int dreg = mono_regstate_next_int (s->rs);
+ MONO_EMIT_LOAD_MEMBASE (s, tree, dreg, state->left->left->tree->inst_basereg,
+ state->left->left->tree->inst_offset);
+ mono_bblock_add_inst (s->cbb, tree);
+
+ mono_call_inst_add_outarg_reg (call, dreg, tree->unused, FALSE);
+}
+
+stmt: OP_OUTARG (CEE_LDIND_I4(base)) {
+ MonoCallInst *call = (MonoCallInst*)tree->inst_right->inst_left;
+
+ int dreg = mono_regstate_next_int (s->rs);
+ MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADI4_MEMBASE, dreg, state->left->left->tree->inst_basereg,
+ state->left->left->tree->inst_offset);
mono_bblock_add_inst (s->cbb, tree);
+
+ mono_call_inst_add_outarg_reg (call, dreg, tree->unused, FALSE);
}
reg: OP_LDADDR (OP_REGOFFSET) "1" {
mono_bblock_add_inst (s->cbb, tree);
}
+lreg: OP_LNEG (lreg) "3" {
+ /* The one in inssel.brg doesn't work, this one is based on gcc code */
+ MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, 0, state->left->reg1);
+ MONO_EMIT_NEW_BIALU (s, OP_SBB, state->reg2, 0, state->left->reg2);
+}
+
# FIXME: This rule was commented out in inssel.brg, why ?
reg: CEE_REM (reg, OP_ICONST) {
MONO_EMIT_BIALU_IMM (s, tree, OP_REM_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
}
+# This one too
+reg: CEE_DIV (reg, OP_ICONST) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_DIV_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
reg: OP_LOCALLOC (OP_ICONST) {
tree->opcode = OP_SPARC_LOCALLOC_IMM;
tree->inst_c0 = state->left->tree->inst_c0;
mono_bblock_add_inst (s->cbb, tree);
}
+# FIXME: Optimized MEMCPY for copying valuetypes
+
# Optimized version for initializing valuetypes on the stack
stmt: OP_MEMSET (OP_LDADDR(OP_REGOFFSET)) "0" {
int size = tree->unused;
/* Target address must be dword aligned */
if ((tree->inst_imm == 0) && (size >= 8) &&
- (destreg == sparc_fp) && ((offset % 8) == 0)) {
+ (destreg == sparc_fp) && (((offset - MONO_SPARC_STACK_BIAS) % 8) == 0)) {
if (!mono_sparc_is_v9 ()) {
/* Use STD */
MONO_EMIT_NEW_ICONST (s, sparc_g1, 0);
}
}
+
+stmt: CEE_STIND_R8 (base, OP_R8CONST) {
+ /* fp constants are pricy on SPARC */
+ guint64 d = *(guint64*)state->right->tree->inst_p0;
+
+ if (d == 0) {
+ if (sizeof (gpointer) == 8) {
+ MONO_EMIT_STORE_MEMBASE (s, tree, OP_STOREI8_MEMBASE_REG, state->left->tree->inst_basereg, state->left->tree->inst_offset, sparc_g0);
+ }
+ else {
+ /* STOREI8 would write %g1 as well */
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg, state->left->tree->inst_offset, sparc_g0);
+ MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg, state->left->tree->inst_offset + 4, sparc_g0);
+ }
+ }
+ else {
+ state->right->tree->dreg = state->reg1;
+ mono_bblock_add_inst (s->cbb, state->right->tree);
+ MONO_EMIT_STORE_MEMBASE (s, tree, OP_STORER8_MEMBASE_REG, state->left->tree->inst_basereg,
+ state->left->tree->inst_offset, state->reg1);
+ }
+}
+
%%