2008-04-11 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Fri, 11 Apr 2008 11:42:27 +0000 (11:42 -0000)
committerZoltan Varga <vargaz@gmail.com>
Fri, 11 Apr 2008 11:42:27 +0000 (11:42 -0000)
* mini-amd64.c (mono_arch_output_basic_block): Implement OP_ABS directly using
SSE2 instructions.

* basic-math.cs: Fix warnings. Add a test for Math.Abs ().

svn path=/trunk/mono/; revision=100423

mono/mini/basic-math.cs
mono/mini/cpu-amd64.md
mono/mini/mini-amd64.c

index c70a6b4ec58b9a46fa87eec26b2ae999fb2e6317..c470c8f13333b82a2ffa89db2d6091a03a133e76 100644 (file)
@@ -6,7 +6,7 @@ using System.Reflection;
  *
  * Each test needs to be of the form:
  *
- * static int test_<result>_<name> ();
+ * public static int test_<result>_<name> ();
  *
  * where <result> is an integer (the value that needs to be returned by
  * the method to make it pass.
@@ -25,44 +25,44 @@ using System.Reflection;
 
 class Tests {
 
-       static int Main () {
+       public static int Main () {
                return TestDriver.RunTests (typeof (Tests));
        }
        
-       static int test_0_sin_precision () {
+       public static int test_0_sin_precision () {
                double d1 = Math.Sin (1);
                 double d2 = Math.Sin (1) - d1;
                return (d2 == 0) ? 0 : 1;
        }
 
-       static int test_0_cos_precision () {
+       public static int test_0_cos_precision () {
                double d1 = Math.Cos (1);
                 double d2 = Math.Cos (1) - d1;
                return (d2 == 0) ? 0 : 1;
        }
 
-       static int test_0_tan_precision () {
+       public static int test_0_tan_precision () {
                double d1 = Math.Tan (1);
                 double d2 = Math.Tan (1) - d1;
                return (d2 == 0) ? 0 : 1;
        }
 
-       static int test_0_atan_precision () {
+       public static int test_0_atan_precision () {
                double d1 = Math.Atan (double.NegativeInfinity);
                 double d2 = Math.Atan (double.NegativeInfinity) - d1;
                return (d2 == 0) ? 0 : 1;
        }
 
-       static int test_0_sqrt_precision () {
+       public static int test_0_sqrt_precision () {
                double d1 = Math.Sqrt (2);
                 double d2 = Math.Sqrt (2) - d1;
                return (d2 == 0) ? 0 : 1;
        }
 
-       static int test_2_sqrt () {
+       public static int test_2_sqrt () {
                return (int) Math.Sqrt (4);
        }
-       static int test_0_sqrt_precision_and_not_spill () {
+       public static int test_0_sqrt_precision_and_not_spill () {
                double expected = 0;
                double[] operands = new double[3];
                double[] temporaries = new double[3];
@@ -87,7 +87,7 @@ class Tests {
                return (result == expected) ? 0 : 1;
        }
        
-       static int test_0_sqrt_precision_and_spill () {
+       public static int test_0_sqrt_precision_and_spill () {
                double expected = 0;
                double[] operands = new double[9];
                double[] temporaries = new double[9];
@@ -112,7 +112,7 @@ class Tests {
                return (result == expected) ? 0 : 1;
        }
        
-       static int test_0_div_precision_and_spill () {
+       public static int test_0_div_precision_and_spill () {
                double expected = 0;
                double[] operands = new double[9];
                double[] temporaries = new double[9];
@@ -136,27 +136,27 @@ class Tests {
                return (result == expected) ? 0 : 1;
        }
        
-       static int test_0_sqrt_nan () {
+       public static int test_0_sqrt_nan () {
                return Double.IsNaN (Math.Sqrt (Double.NaN)) ? 0 : 1;
        }
        
-       static int test_0_sin_nan () {
+       public static int test_0_sin_nan () {
                return Double.IsNaN (Math.Sin (Double.NaN)) ? 0 : 1;
        }
        
-       static int test_0_cos_nan () {
+       public static int test_0_cos_nan () {
                return Double.IsNaN (Math.Cos (Double.NaN)) ? 0 : 1;
        }
        
-       static int test_0_tan_nan () {
+       public static int test_0_tan_nan () {
                return Double.IsNaN (Math.Tan (Double.NaN)) ? 0 : 1;
        }
        
-       static int test_0_atan_nan () {
+       public static int test_0_atan_nan () {
                return Double.IsNaN (Math.Atan (Double.NaN)) ? 0 : 1;
        }
 
-       static int test_0_min () {
+       public static int test_0_min () {
                if (Math.Min (5, 6) != 5)
                        return 1;
                if (Math.Min (6, 5) != 5)
@@ -172,7 +172,7 @@ class Tests {
                return 0;
        }
 
-       static int test_0_max () {
+       public static int test_0_max () {
                if (Math.Max (5, 6) != 6)
                        return 1;
                if (Math.Max (6, 5) != 6)
@@ -187,5 +187,12 @@ class Tests {
                        return 6;
                return 0;
        }
-               
+
+       public static int test_0_abs () {
+               double d = -5.0;
+
+               if (Math.Abs (d) != 5.0)
+                       return 1;
+               return 0;
+       }
 }
index e1c578ae88ef173d3ec19f2a6f693b4b8e41e10d..6ea8864491e79499e0d463fa890a2d0c68844d2b 100644 (file)
@@ -307,7 +307,7 @@ sbb_imm: dest:i src1:i len:8 clob:1
 br_reg: src1:i len:3
 sin: dest:f src1:f len:32
 cos: dest:f src1:f len:32
-abs: dest:f src1:f len:32
+abs: dest:f src1:f clob:1 len:32
 tan: dest:f src1:f len:59
 atan: dest:f src1:f len:9
 sqrt: dest:f src1:f len:32
index 3a8cfed458f35f35d8bbb1aa4eb36305741b16fa..c78c8a4a7cd668a2189dbe6d084de48751965207 100644 (file)
@@ -3367,9 +3367,15 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_COS:
                        EMIT_SSE2_FPFUNC (code, fcos, ins->dreg, ins->sreg1);
                        break;          
-               case OP_ABS:
-                       EMIT_SSE2_FPFUNC (code, fabs, ins->dreg, ins->sreg1);
+               case OP_ABS: {
+                       static guint64 d = 0x7fffffffffffffffUL;
+
+                       g_assert (ins->sreg1 == ins->dreg);
+                                       
+                       mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R8, &d);
+                       amd64_sse_andpd_reg_membase (code, ins->dreg, AMD64_RIP, 0);
                        break;          
+               }
                case OP_SQRT:
                        EMIT_SSE2_FPFUNC (code, fsqrt, ins->dreg, ins->sreg1);
                        break;