X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Flocal-propagation.c;h=a35a7a39f21405c92b2b9602205116099f4b7852;hb=b2cf10659d74681988ad53c18f368c007990d829;hp=f23c5ff3bb9e5c1278220b19656c554e6f85d527;hpb=ef0ddf45c3081e799edcb4e95770186514b80cf1;p=mono.git diff --git a/mono/mini/local-propagation.c b/mono/mini/local-propagation.c index f23c5ff3bb9..a35a7a39f21 100644 --- a/mono/mini/local-propagation.c +++ b/mono/mini/local-propagation.c @@ -181,6 +181,75 @@ mono_strength_reduction_ins (MonoCompile *cfg, MonoInst *ins, const char **spec) #endif break; } +#if SIZEOF_REGISTER == 4 + case OP_LSHR_IMM: { + if (COMPILE_LLVM (cfg)) + break; + if (ins->inst_c1 == 32) { + MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, MONO_LVREG_LS (ins->dreg), MONO_LVREG_MS (ins->sreg1)); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHR_IMM, MONO_LVREG_MS (ins->dreg), MONO_LVREG_MS (ins->sreg1), 31); + } else if (ins->inst_c1 == 0) { + MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, MONO_LVREG_LS (ins->dreg), MONO_LVREG_LS (ins->sreg1)); + MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, MONO_LVREG_MS (ins->dreg), MONO_LVREG_MS (ins->sreg1)); + } else if (ins->inst_c1 > 32) { + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHR_IMM, MONO_LVREG_LS (ins->dreg), MONO_LVREG_MS (ins->sreg1), ins->inst_c1 - 32); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHR_IMM, MONO_LVREG_MS (ins->dreg), MONO_LVREG_MS (ins->sreg1), 31); + } else { + guint32 tmpreg = alloc_ireg (cfg); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHL_IMM, tmpreg, MONO_LVREG_MS (ins->sreg1), 32 - ins->inst_c1); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHR_IMM, MONO_LVREG_MS (ins->dreg), MONO_LVREG_MS (ins->sreg1), ins->inst_c1); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHR_UN_IMM, MONO_LVREG_LS (ins->dreg), MONO_LVREG_LS (ins->sreg1), ins->inst_c1); + MONO_EMIT_NEW_BIALU (cfg, OP_IOR, MONO_LVREG_LS (ins->dreg), MONO_LVREG_LS (ins->dreg), tmpreg); + allocated_vregs = TRUE; + } + break; + } + case OP_LSHR_UN_IMM: { + if (COMPILE_LLVM (cfg)) + break; + if (ins->inst_c1 == 32) { + MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, MONO_LVREG_LS (ins->dreg), MONO_LVREG_MS (ins->sreg1)); + MONO_EMIT_NEW_ICONST (cfg, MONO_LVREG_MS (ins->dreg), 0); + } else if (ins->inst_c1 == 0) { + MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, MONO_LVREG_LS (ins->dreg), MONO_LVREG_LS (ins->sreg1)); + MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, MONO_LVREG_MS (ins->dreg), MONO_LVREG_MS (ins->sreg1)); + } else if (ins->inst_c1 > 32) { + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHR_UN_IMM, MONO_LVREG_LS (ins->dreg), MONO_LVREG_MS (ins->sreg1), ins->inst_c1 - 32); + MONO_EMIT_NEW_ICONST (cfg, MONO_LVREG_MS (ins->dreg), 0); + } else { + guint32 tmpreg = alloc_ireg (cfg); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHL_IMM, tmpreg, MONO_LVREG_MS (ins->sreg1), 32 - ins->inst_c1); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHR_UN_IMM, MONO_LVREG_MS (ins->dreg), MONO_LVREG_MS (ins->sreg1), ins->inst_c1); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHR_UN_IMM, MONO_LVREG_LS (ins->dreg), MONO_LVREG_LS (ins->sreg1), ins->inst_c1); + MONO_EMIT_NEW_BIALU (cfg, OP_IOR, MONO_LVREG_LS (ins->dreg), MONO_LVREG_LS (ins->dreg), tmpreg); + allocated_vregs = TRUE; + } + break; + } + case OP_LSHL_IMM: { + if (COMPILE_LLVM (cfg)) + break; + if (ins->inst_c1 == 32) { + /* just move the lower half to the upper and zero the lower word */ + MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, MONO_LVREG_MS (ins->dreg), MONO_LVREG_LS (ins->sreg1)); + MONO_EMIT_NEW_ICONST (cfg, MONO_LVREG_LS (ins->dreg), 0); + } else if (ins->inst_c1 == 0) { + MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, MONO_LVREG_LS (ins->dreg), MONO_LVREG_LS (ins->sreg1)); + MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, MONO_LVREG_MS (ins->dreg), MONO_LVREG_MS (ins->sreg1)); + } else if (ins->inst_c1 > 32) { + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHL_IMM, MONO_LVREG_MS (ins->dreg), MONO_LVREG_LS (ins->sreg1), ins->inst_c1 - 32); + MONO_EMIT_NEW_ICONST (cfg, MONO_LVREG_LS (ins->dreg), 0); + } else { + guint32 tmpreg = alloc_ireg (cfg); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHR_UN_IMM, tmpreg, MONO_LVREG_LS (ins->sreg1), 32 - ins->inst_c1); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHL_IMM, MONO_LVREG_MS (ins->dreg), MONO_LVREG_MS (ins->sreg1), ins->inst_c1); + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ISHL_IMM, MONO_LVREG_LS (ins->dreg), MONO_LVREG_LS (ins->sreg1), ins->inst_c1); + MONO_EMIT_NEW_BIALU (cfg, OP_IOR, MONO_LVREG_MS (ins->dreg), MONO_LVREG_MS (ins->dreg), tmpreg); + allocated_vregs = TRUE; + } + break; + } +#endif default: break; @@ -486,13 +555,13 @@ mono_local_cprop (MonoCompile *cfg) ins->inst_destbasereg = def->sreg1; ins->inst_offset += def->inst_imm; } + + if (!MONO_IS_STORE_MEMBASE (ins) && !vreg_is_volatile (cfg, ins->dreg)) { + defs [ins->dreg] = ins; + def_index [ins->dreg] = ins_index; + } } - if ((spec [MONO_INST_DEST] != ' ') && !MONO_IS_STORE_MEMBASE (ins) && !vreg_is_volatile (cfg, ins->dreg)) { - defs [ins->dreg] = ins; - def_index [ins->dreg] = ins_index; - } - if (MONO_IS_CALL (ins)) last_call_index = ins_index;