[mips] Disable div with mul on 32bit mips
authorVlad Brezae <brezaevlad@gmail.com>
Mon, 10 Oct 2016 20:40:59 +0000 (23:40 +0300)
committerVlad Brezae <brezaevlad@gmail.com>
Tue, 11 Oct 2016 21:19:48 +0000 (00:19 +0300)
mono/mini/local-propagation.c
mono/mini/mini-mips.h
mono/mini/mini.c
mono/mini/mini.h

index 04373359fb46ead9bc1ea8d96249d33ee4c15948..e19b91c5fcab116663a5971c7d925362daaeaadf 100644 (file)
@@ -171,6 +171,8 @@ mono_strength_reduction_division (MonoCompile *cfg, MonoInst *ins)
                                ins->inst_imm = power2;
                                break;
                        }
+                       if (cfg->backend->disable_div_with_mul)
+                               break;
                        allocated_vregs = TRUE;
                        /*
                         * Replacement of unsigned division with multiplication,
@@ -243,6 +245,8 @@ mono_strength_reduction_division (MonoCompile *cfg, MonoInst *ins)
                                break;
                        }
 
+                       if (cfg->backend->disable_div_with_mul)
+                               break;
                        /*
                         * Replacement of signed division with multiplication,
                         * shifts and additions Hacker's Delight, chapter 10-6.
index 06c533aee46cffa33e738dfd1b665dd6685f85e9..df179bd2545334cd8cf1eca629efc0f54b487a43 100644 (file)
@@ -233,6 +233,15 @@ typedef struct MonoCompileArch {
 #define MONO_ARCH_EMULATE_FREM 1
 #endif
 
+/*
+ * mips backend misses some instructions that enable emitting of optimal
+ * code on other targets and, additionally, the register allocator gets
+ * confused by this optimization, failing to allocate all hw regs.
+ */
+#if SIZEOF_REGISTER == 4
+#define MONO_ARCH_NO_DIV_WITH_MUL
+#endif
+
 #if SIZEOF_REGISTER == 8
 #define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS
 #endif
index 0dd4af7a71ede59872342fd943775750d3a50d52..9768fee9fd6f31173ce8f2dffb70baebaa1e05a6 100644 (file)
@@ -3175,6 +3175,9 @@ init_backend (MonoBackend *backend)
 #ifdef MONO_ARCH_DYN_CALL_PARAM_AREA
        backend->dyn_call_param_area = MONO_ARCH_DYN_CALL_PARAM_AREA;
 #endif
+#ifdef MONO_ARCH_NO_DIV_WITH_MUL
+       backend->disable_div_with_mul = 1;
+#endif
 }
 
 /*
index d3a550946013f217c8c53ccb20b118d2d844badf..a7bba5a62e4660dafca5a516e2cd9fe762e50cf2 100644 (file)
@@ -1496,6 +1496,7 @@ typedef struct {
        guint            need_got_var : 1;
        guint            need_div_check : 1;
        guint            no_unaligned_access : 1;
+       guint            disable_div_with_mul : 1;
        int              monitor_enter_adjustment;
        int              dyn_call_param_area;
 } MonoBackend;