X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Finssel-ppc.brg;h=26d63f92f563f02e507c0b031fd4071459ce174e;hb=eb28197c2ac3141c730eb4d37585ee4f44bcb820;hp=b803bc4a36b49c209ae7826c58c140376726db48;hpb=055f687e8059575b7a1e04ce461a050d7f38a441;p=mono.git diff --git a/mono/mini/inssel-ppc.brg b/mono/mini/inssel-ppc.brg index b803bc4a36b..26d63f92f56 100644 --- a/mono/mini/inssel-ppc.brg +++ b/mono/mini/inssel-ppc.brg @@ -31,6 +31,30 @@ stmt: OP_ENDFILTER (reg) { mono_bblock_add_inst (s->cbb, tree); } +lreg: OP_LADD_OVF (lreg, lreg) "0" { + /* ADC sets the condition code */ + MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1); + MONO_EMIT_NEW_BIALU (s, OP_ADD_OVF_CARRY, state->reg2, state->left->reg2, state->right->reg2); +} + +lreg: OP_LADD_OVF_UN (lreg, lreg) "0" { + /* ADC sets the condition code */ + MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1); + MONO_EMIT_NEW_BIALU (s, OP_ADD_OVF_UN_CARRY, state->reg2, state->left->reg2, state->right->reg2); +} + +lreg: OP_LSUB_OVF (lreg, lreg) "0" { + /* SBB sets the condition code */ + MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1); + MONO_EMIT_NEW_BIALU (s, OP_SUB_OVF_CARRY, state->reg2, state->left->reg2, state->right->reg2); +} + +lreg: OP_LSUB_OVF_UN (lreg, lreg) "0" { + /* SBB sets the condition code */ + MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1); + MONO_EMIT_NEW_BIALU (s, OP_SUB_OVF_UN_CARRY, state->reg2, state->left->reg2, state->right->reg2); +} + stmt: CEE_STIND_I8 (OP_REGVAR, lreg) { /* this should only happen for methods returning a long */ MONO_EMIT_NEW_UNALU (s, OP_MOVE, ppc_r3, state->right->reg1); @@ -105,89 +129,109 @@ stmt: OP_SETRET (OP_ICONST) { mono_bblock_add_inst (s->cbb, tree); } +stmt: CEE_STIND_I (OP_REGVAR, CEE_SUB (CEE_LDIND_I (OP_REGVAR), OP_ICONST)), +stmt: CEE_STIND_I4 (OP_REGVAR, CEE_SUB (CEE_LDIND_I4 (OP_REGVAR), OP_ICONST)), +stmt: CEE_STIND_I (OP_REGVAR, CEE_ADD (CEE_LDIND_I (OP_REGVAR), OP_ICONST)), +stmt: CEE_STIND_I4 (OP_REGVAR, CEE_ADD (CEE_LDIND_I4 (OP_REGVAR), OP_ICONST)) { + int con = state->right->right->tree->inst_c0; + int dreg = state->left->tree->dreg; + int sreg = state->right->left->left->tree->dreg; + + if (state->right->op == CEE_ADD) + tree->opcode = OP_ADD_IMM; + else if (state->right->op == CEE_SUB) + tree->opcode = OP_SUB_IMM; + else + g_assert_not_reached (); + tree->inst_imm = con; + tree->sreg1 = sreg; + tree->dreg = dreg; + mono_bblock_add_inst (s->cbb, tree); +} + +stmt: OP_OUTARG_MEMBASE (reg) { + MonoPPCArgInfo *ai = tree->backend.data; + MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, ppc_r1, ai->offset, state->left->reg1); +} + +stmt: OP_OUTARG_MEMBASE (OP_REGVAR) { + MonoPPCArgInfo *ai = tree->backend.data; + MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, ppc_r1, ai->offset, state->left->tree->dreg); +} + +stmt: OP_OUTARG_MEMBASE (lreg) { + MonoPPCArgInfo *ai = tree->backend.data; + MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, ppc_r1, ai->offset, state->left->reg2); + MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, ppc_r1, ai->offset + 4, state->left->reg1); +} + +stmt: OP_OUTARG_MEMBASE (OP_ICONST) { + MonoPPCArgInfo *ai = tree->backend.data; + MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, ppc_r1, ai->offset, state->left->tree->inst_c0); +} + +stmt: OP_OUTARG_MEMBASE (CEE_LDIND_REF (OP_REGVAR)) { + MonoPPCArgInfo *ai = tree->backend.data; + MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, ppc_r1, ai->offset, state->left->left->tree->dreg); +} + +stmt: OP_OUTARG_MEMBASE (freg) { + MonoPPCArgInfo *ai = tree->backend.data; + int opcode = ai->size == 4? OP_STORER4_MEMBASE_REG: OP_STORER8_MEMBASE_REG; + MONO_EMIT_NEW_STORE_MEMBASE (s, opcode, ppc_r1, ai->offset, state->left->reg1); +} + stmt: OP_OUTARG (reg) { - if (tree->inst_imm) { - MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1); - return; - } + MonoCallInst *call = tree->inst_call; + 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 (s, call, tree->dreg, tree->backend.reg3, FALSE); } stmt: OP_OUTARG (OP_REGVAR) { - if (tree->inst_imm) { - MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->tree->dreg); - return; - } + MonoCallInst *call = tree->inst_call; + 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); + mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE); } stmt: OP_OUTARG (lreg) { - if (tree->inst_imm) { - MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg2); - MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm + 4, state->left->reg1); - return; - } - MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2); + MonoCallInst *call = tree->inst_call; + int tdreg = mono_regstate_next_int (s->rs); + + MONO_EMIT_NEW_UNALU (s, OP_SETREG, tdreg, state->left->reg2); + mono_call_inst_add_outarg_reg (s, call, tdreg, tree->backend.reg3, FALSE); tree->opcode = OP_SETREG; - tree->dreg = tree->unused + 1; + 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 (s, call, tree->dreg, tree->backend.reg3 + 1, FALSE); } stmt: OP_OUTARG (OP_ICONST) { - if (tree->inst_imm) { - MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, s->frame_reg, tree->inst_imm, state->left->tree->inst_c0); - return; - } + MonoCallInst *call = tree->inst_call; + 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 (s, call, tree->dreg, tree->backend.reg3, FALSE); } -#stmt: OP_OUTARG (CEE_LDIND_I4 (base)) { -# tree->opcode = OP_X86_PUSH_MEMBASE; -# 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); -#} - -#stmt: OP_OUTARG (CEE_LDIND_U4 (base)) { -# tree->opcode = OP_X86_PUSH_MEMBASE; -# 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); -#} - -#stmt: OP_OUTARG (CEE_LDIND_I (base)) { -# tree->opcode = OP_X86_PUSH_MEMBASE; -# 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); -#} - -#stmt: OP_OUTARG (CEE_LDIND_REF (base)) { -# tree->opcode = OP_X86_PUSH_MEMBASE; -# 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); -#} - stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) { - if (tree->inst_imm) { - MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->left->tree->dreg); - return; - } + MonoCallInst *call = tree->inst_call; + tree->opcode = OP_SETREG; + tree->dreg = mono_regstate_next_int (s->rs); tree->sreg1 = state->left->left->tree->dreg; - tree->dreg = tree->unused; mono_bblock_add_inst (s->cbb, tree); + mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, FALSE); } #stmt: OP_OUTARG (CEE_LDOBJ (reg)) { @@ -196,81 +240,99 @@ stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) { # mono_bblock_add_inst (s->cbb, tree); #} +stmt: OP_OUTARG_R8 (freg), stmt: OP_OUTARG (freg) { - if (tree->inst_imm) { - MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1); - return; - } - tree->opcode = OP_SETFREG; - tree->sreg1 = state->left->reg1; - tree->dreg = tree->unused; - mono_bblock_add_inst (s->cbb, tree); -} + MonoCallInst *call = tree->inst_call; -stmt: OP_OUTARG_R4 (freg) { - if (tree->inst_imm) { - MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1); - return; - } tree->opcode = OP_SETFREG; + tree->dreg = mono_regstate_next_float (s->rs); tree->sreg1 = state->left->reg1; - tree->dreg = tree->unused; mono_bblock_add_inst (s->cbb, tree); + mono_call_inst_add_outarg_reg (s, call, tree->dreg, tree->backend.reg3, TRUE); } -stmt: OP_OUTARG_R8 (freg) { - if (tree->inst_imm) { - MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1); - return; - } - tree->opcode = OP_SETFREG; - tree->sreg1 = state->left->reg1; - tree->dreg = tree->unused; - mono_bblock_add_inst (s->cbb, tree); +stmt: OP_OUTARG_R8 (CEE_LDOBJ (base)) { + /* small struct with fp value goes in a fp register */ + MonoInst *vt = state->left->left->tree; + int tmpr, soffset, dreg; + MonoCallInst *call = tree->inst_call; + + soffset = vt->inst_offset; + tmpr = mono_regstate_next_float (s->rs); + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADR4_MEMBASE, tmpr, vt->inst_basereg, soffset); + dreg = mono_regstate_next_float (s->rs); + MONO_EMIT_NEW_UNALU (s, OP_SETFREG, dreg, tmpr); + mono_call_inst_add_outarg_reg (s, call, dreg, tree->backend.reg3, TRUE); } stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) { + MonoCallInst *call = tree->inst_call; + MonoPPCArgInfo *ai = tree->backend.data; MonoInst *vt = state->left->left->tree; - int start_reg = tree->unused & 0xff; - int nregs = (tree->unused >> 8) & 0xff; - int ovf_size = (tree->unused >> 16) & 0xffff; - int i, tmpr, soffset; + int start_reg = ai->reg; + int nregs = ai->size; + int ovf_size = ai->vtsize; + int i, tmpr, soffset, dreg; + int size = 0; soffset = vt->inst_offset; +/* + Darwin needs some special handling for 1 and 2 byte arguments +*/ +#ifdef __APPLE__ + if (vt->inst_vtype && MONO_TYPE_ISSTRUCT (vt->inst_vtype) && vt->inst_vtype->type != MONO_TYPE_TYPEDBYREF) + size = mono_class_native_size (mono_class_from_mono_type (vt->inst_vtype), NULL); + if (size == 2 || size == 1) { + tmpr = mono_regstate_next_int (s->rs); + if (size == 1) + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI1_MEMBASE, tmpr, vt->inst_basereg, soffset); + else + MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI2_MEMBASE, tmpr, vt->inst_basereg, soffset); + dreg = mono_regstate_next_int (s->rs); + MONO_EMIT_NEW_UNALU (s, OP_SETREG, dreg, tmpr); + mono_call_inst_add_outarg_reg (s, call, dreg, start_reg, FALSE); + } else +#endif for (i = 0; i < nregs; ++i) { tmpr = mono_regstate_next_int (s->rs); MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, vt->inst_basereg, soffset); - MONO_EMIT_NEW_UNALU (s, OP_SETREG, start_reg + i, tmpr); + dreg = mono_regstate_next_int (s->rs); + MONO_EMIT_NEW_UNALU (s, OP_SETREG, dreg, tmpr); + mono_call_inst_add_outarg_reg (s, call, dreg, start_reg + i, FALSE); soffset += sizeof (gpointer); } - //g_print ("vt size: %d at R%d + %d\n", tree->inst_imm, vt->inst_basereg, vt->inst_offset); + //g_print ("vt size: %d at R%d + %d\n", ai->offset, vt->inst_basereg, vt->inst_offset); if (ovf_size != 0) { - mini_emit_memcpy (s, s->frame_reg, tree->inst_imm + (soffset - vt->inst_offset), vt->inst_basereg, soffset, ovf_size * sizeof (gpointer), 0); + mini_emit_memcpy (s, ppc_r1, ai->offset + (soffset - vt->inst_offset), vt->inst_basereg, soffset, ovf_size * sizeof (gpointer), 0); } } stmt: OP_OUTARG_VT (OP_ICONST) { - int start_reg = tree->unused & 0xff; - int nregs = (tree->unused >> 8) & 0xff; - int ovf_size = (tree->unused >> 16) & 0xffff; + MonoCallInst *call = tree->inst_call; + MonoPPCArgInfo *ai = tree->backend.data; + int start_reg = ai->reg; + int nregs = ai->size; if (nregs) { tree->opcode = OP_SETREGIMM; - tree->dreg = start_reg; + 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 (s, call, tree->dreg, start_reg, FALSE); } else { g_assert_not_reached (); } } stmt: OP_OUTARG_VT (reg) { - int start_reg = tree->unused & 0xff; - int nregs = (tree->unused >> 8) & 0xff; - int ovf_size = (tree->unused >> 16) & 0xffff; + MonoCallInst *call = tree->inst_call; + MonoPPCArgInfo *ai = tree->backend.data; + int start_reg = ai->reg; + int nregs = ai->size; if (nregs) { tree->opcode = OP_SETREG; - tree->dreg = start_reg; - tree->sreg1 = state->left->tree->dreg; + 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 (s, call, tree->dreg, start_reg, FALSE); } else { g_assert_not_reached (); } @@ -375,4 +437,19 @@ reg: OP_CGT_UN (OP_COMPARE (freg, freg)) { state->left->right->reg1); } +reg: CEE_ADD_OVF (reg, reg) "0" { + MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1); +} + +reg: CEE_ADD_OVF_UN (reg, reg) "0" { + MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1); +} + +reg: CEE_SUB_OVF (reg, reg) "0" { + MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1); +} + +reg: CEE_SUB_OVF_UN (reg, reg) "0" { + MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1); +} %%