From ef69e7d57224a2fa4c2e01b0db6071c868e1d8f4 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Tue, 30 Apr 2002 05:17:47 +0000 Subject: [PATCH] (MUL) use shift when possible. (DIV) use shift when possible. impl. various opt. with coni4 svn path=/trunk/mono/; revision=4163 --- mono/benchmark/Makefile.am | 3 +- mono/benchmark/muldiv.cs | 34 ++++++++++++++ mono/jit/ChangeLog | 3 ++ mono/jit/x86.brg | 95 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+), 1 deletion(-) create mode 100755 mono/benchmark/muldiv.cs diff --git a/mono/benchmark/Makefile.am b/mono/benchmark/Makefile.am index ca6cc442249..46b086f77bc 100644 --- a/mono/benchmark/Makefile.am +++ b/mono/benchmark/Makefile.am @@ -10,7 +10,8 @@ TESTSRC= \ isinst.cs \ inline1.cs \ inline2.cs \ - inline3.cs + inline3.cs \ + muldiv.cs TESTSI=$(TESTSRC:.cs=.exe) TESTBS=$(BENCHSRC:.cs=.exe) diff --git a/mono/benchmark/muldiv.cs b/mono/benchmark/muldiv.cs new file mode 100755 index 00000000000..1b1353e0a8a --- /dev/null +++ b/mono/benchmark/muldiv.cs @@ -0,0 +1,34 @@ +using System; + +public class MulDiv { + + public static int muldiv (int n) { + int res = n; + + for (int j = 0; j < 1048; j++) { + for (int i = 0; i < (n * 4); i++) { + n = (n / 256); + n++; + n = n * 128; + } + } + + return res; + } + + public static int Main (string[] args) { + int repeat = 1; + + if (args.Length == 1) + repeat = Convert.ToInt32 (args [0]); + + Console.WriteLine ("Repeat = " + repeat); + + for (int i = 0; i < (repeat * 50); i++) + muldiv (1000); + + return 0; + } +} + + diff --git a/mono/jit/ChangeLog b/mono/jit/ChangeLog index d52ab53e1eb..520e8191bc5 100644 --- a/mono/jit/ChangeLog +++ b/mono/jit/ChangeLog @@ -1,6 +1,9 @@ 2002-04-30 Dietmar Maurer * x86.brg: opt. LDELEMA impl. + (MUL) use shift when possible. + (DIV) use shift when possible. + impl. various opt. with coni4 * exception.c (arch_handle_exception): use ctx->SC_EBP in end_of_stack check as suggested by Linus Upson diff --git a/mono/jit/x86.brg b/mono/jit/x86.brg index 1f22540e234..7cf765ecc79 100644 --- a/mono/jit/x86.brg +++ b/mono/jit/x86.brg @@ -1067,6 +1067,24 @@ reg: CONV_OVF_I2_UN (reg) { x86_widen_reg (s->code, tree->reg1, tree->left->reg1, FALSE, TRUE); } +reg: MUL (reg, coni4) "MB_USE_OPT1(0)" { + unsigned int i, j, k, v; + + v = tree->right->data.i; + for (i = 0, j = 1, k = 0xfffffffe; i < 32; i++, j = j << 1, k = k << 1) { + if (v & j) + break; + } + + if (v < 0 || i == 32 || v & k) { + x86_imul_reg_reg_imm (s->code, tree->reg1, tree->left->reg1, tree->right->data.i); + } else { + x86_shift_reg_imm (s->code, X86_SHL, tree->left->reg1, i); + if (tree->reg1 != tree->left->reg1) + x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4); + } +} + reg: MUL (reg, reg) { x86_imul_reg_reg (s->code, tree->left->reg1, tree->right->reg1); @@ -1095,6 +1113,38 @@ reg: MUL_OVF_UN (reg, reg) { tree->reg2 == X86_EDX); } +reg: DIV (reg, coni4) { + unsigned int i, j, k, v; + + v = tree->right->data.i; + for (i = 0, j = 1, k = 0xfffffffe; i < 32; i++, j = j << 1, k = k << 1) { + if (v & j) + break; + } + + x86_shift_reg_imm (s->code, X86_SAR, tree->left->reg1, i); + if (tree->reg1 != tree->left->reg1) + x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4); + +} cost { + unsigned int i, j, k, v; + + if (v < 0) + return MBMAXCOST; + + v = tree->right->data.i; + for (i = 0, j = 1, k = 0xfffffffe; i < 32; i++, j = j << 1, k = k << 1) { + if (v & j) + break; + } + + if (i == 32 || v & k) + return MBMAXCOST; + + return 0; + +} + reg: DIV (reg, reg) { mono_assert (tree->right->reg1 != X86_EAX); @@ -1232,30 +1282,61 @@ reg: CEQ (reg, reg) { x86_widen_reg (s->code, tree->reg1, tree->reg1, FALSE, FALSE); } +reg: CGT (reg, coni4) "MB_USE_OPT1(0)" { + x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i); + x86_set_reg (s->code, X86_CC_GT, tree->reg1, TRUE); + x86_widen_reg (s->code, tree->reg1, tree->reg1, FALSE, FALSE); +} + reg: CGT (reg, reg) { x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1); x86_set_reg (s->code, X86_CC_GT, tree->reg1, TRUE); x86_widen_reg (s->code, tree->reg1, tree->reg1, FALSE, FALSE); } +reg: CGT_UN (reg, coni4) "MB_USE_OPT1(0)" { + x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i); + x86_set_reg (s->code, X86_CC_GT, tree->reg1, FALSE); + x86_widen_reg (s->code, tree->reg1, tree->reg1, FALSE, FALSE); +} + reg: CGT_UN (reg, reg) { x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1); x86_set_reg (s->code, X86_CC_GT, tree->reg1, FALSE); x86_widen_reg (s->code, tree->reg1, tree->reg1, FALSE, FALSE); } +reg: CLT (reg, coni4) "MB_USE_OPT1(0)" { + x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i); + x86_set_reg (s->code, X86_CC_LT, tree->reg1, TRUE); + x86_widen_reg (s->code, tree->reg1, tree->reg1, FALSE, FALSE); +} + reg: CLT (reg, reg) { x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1); x86_set_reg (s->code, X86_CC_LT, tree->reg1, TRUE); x86_widen_reg (s->code, tree->reg1, tree->reg1, FALSE, FALSE); } +reg: CLT_UN (reg, coni4) "MB_USE_OPT1(0)" { + x86_alu_reg_imm (s->code, X86_CMP, tree->left->reg1, tree->right->data.i); + x86_set_reg (s->code, X86_CC_LT, tree->reg1, FALSE); + x86_widen_reg (s->code, tree->reg1, tree->reg1, FALSE, FALSE); +} + reg: CLT_UN (reg, reg) { x86_alu_reg_reg (s->code, X86_CMP, tree->left->reg1, tree->right->reg1); x86_set_reg (s->code, X86_CC_LT, tree->reg1, FALSE); x86_widen_reg (s->code, tree->reg1, tree->reg1, FALSE, FALSE); } +reg: AND (reg, coni4) "MB_USE_OPT1(0)" { + x86_alu_reg_imm (s->code, X86_AND, tree->left->reg1, tree->right->data.i); + + if (tree->reg1 != tree->left->reg1) + x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4); +} + reg: AND (reg, reg) { x86_alu_reg_reg (s->code, X86_AND, tree->left->reg1, tree->right->reg1); @@ -1263,6 +1344,13 @@ reg: AND (reg, reg) { x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4); } +reg: OR (reg, coni4) "MB_USE_OPT1(0)" { + x86_alu_reg_imm (s->code, X86_OR, tree->left->reg1, tree->right->data.i); + + if (tree->reg1 != tree->left->reg1) + x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4); +} + reg: OR (reg, reg) { x86_alu_reg_reg (s->code, X86_OR, tree->left->reg1, tree->right->reg1); @@ -1270,6 +1358,13 @@ reg: OR (reg, reg) { x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4); } +reg: XOR (reg, coni4) "MB_USE_OPT1(0)" { + x86_alu_reg_imm (s->code, X86_XOR, tree->left->reg1, tree->right->data.i); + + if (tree->reg1 != tree->left->reg1) + x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4); +} + reg: XOR (reg, reg) { x86_alu_reg_reg (s->code, X86_XOR, tree->left->reg1, tree->right->reg1); -- 2.25.1