Author: zoltan
Date: 2007-12-20 13:00:35 -0500 (Thu, 20 Dec 2007)
New Revision: 91725

Modified:
   trunk/mono/mono/mini/ChangeLog
   trunk/mono/mono/mini/basic-float.cs
   trunk/mono/mono/mini/cpu-amd64.md
   trunk/mono/mono/mini/inssel-amd64.brg
   trunk/mono/mono/mini/mini-amd64.c
   trunk/mono/mono/mini/mini-amd64.h
Log:
2007-12-20  Zoltan Varga  <[EMAIL PROTECTED]>

        * cpu-amd64.md mini-amd64.h mini-amd64.c inssel-amd64.brg: Add 
ulong->double 
        implementation.

        * basic-float.cs: Add an ulong->double cast test.


Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog      2007-12-20 18:00:20 UTC (rev 91724)
+++ trunk/mono/mono/mini/ChangeLog      2007-12-20 18:00:35 UTC (rev 91725)
@@ -1,3 +1,10 @@
+2007-12-20  Zoltan Varga  <[EMAIL PROTECTED]>
+
+       * cpu-amd64.md mini-amd64.h mini-amd64.c inssel-amd64.brg: Add 
ulong->double 
+       implementation.
+
+       * basic-float.cs: Add an ulong->double cast test.
+
 2007-12-15  Zoltan Varga  <[EMAIL PROTECTED]>
 
        * mini.c (mono_method_to_ir): Fix a warning.

Modified: trunk/mono/mono/mini/basic-float.cs
===================================================================
--- trunk/mono/mono/mini/basic-float.cs 2007-12-20 18:00:20 UTC (rev 91724)
+++ trunk/mono/mono/mini/basic-float.cs 2007-12-20 18:00:35 UTC (rev 91725)
@@ -192,6 +192,15 @@
                return 4;
        }
 
+       static int test_4_ulong_cast () {
+               ulong a = 1000;
+               double d = (double)a;
+               ulong b = (ulong)d;
+               if (b != 1000)
+                       return 0;
+               return 4;
+       }
+
        static int test_4_single_long_cast () {
                long a = 1000;
                float d = (float)a;

Modified: trunk/mono/mono/mini/cpu-amd64.md
===================================================================
--- trunk/mono/mono/mini/cpu-amd64.md   2007-12-20 18:00:20 UTC (rev 91724)
+++ trunk/mono/mono/mini/cpu-amd64.md   2007-12-20 18:00:35 UTC (rev 91725)
@@ -241,7 +241,7 @@
 long_conv_to_ovf_i: dest:i src1:i src2:i len:40
 long_mul_ovf: dest:i src1:i src2:i clob:1 len:16
 long_mul_ovf_un: dest:i src1:i src2:i len:22
-long_conv_to_r_un: dest:f src1:i src2:i len:48 
+long_conv_to_r_un: dest:f src1:i len:64
 long_shr_imm: dest:i src1:i clob:1 len:11
 long_shr_un_imm: dest:i src1:i clob:1 len:11
 long_shl_imm: dest:i src1:i clob:1 len:11

Modified: trunk/mono/mono/mini/inssel-amd64.brg
===================================================================
--- trunk/mono/mono/mini/inssel-amd64.brg       2007-12-20 18:00:20 UTC (rev 
91724)
+++ trunk/mono/mono/mini/inssel-amd64.brg       2007-12-20 18:00:35 UTC (rev 
91725)
@@ -73,6 +73,7 @@
        mono_bblock_add_inst (s->cbb, tree);
 }
 
+freg: OP_LCONV_TO_R_UN (reg),
 freg: OP_LCONV_TO_R8 (reg) {
        tree->sreg1 = state->left->reg1;
        tree->dreg = state->reg1;

Modified: trunk/mono/mono/mini/mini-amd64.c
===================================================================
--- trunk/mono/mono/mini/mini-amd64.c   2007-12-20 18:00:20 UTC (rev 91724)
+++ trunk/mono/mono/mini/mini-amd64.c   2007-12-20 18:00:35 UTC (rev 91725)
@@ -3633,11 +3633,37 @@
                        break;
                case OP_LCONV_TO_R_UN: { 
                        static guint8 mn[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x80, 0x3f, 0x40 };
-                       guint8 *br;
+                       guint8 *br [2];
 
-                       if (use_sse2)
-                               g_assert_not_reached ();
+                       if (use_sse2) {
+                               /* Based on gcc code */
+                               amd64_test_reg_reg (code, ins->sreg1, 
ins->sreg1);
+                               br [0] = code; x86_branch8 (code, X86_CC_S, 0, 
TRUE);
 
+                               /* Positive case */
+                               amd64_sse_cvtsi2sd_reg_reg (code, ins->dreg, 
ins->sreg1);
+                               br [1] = code; x86_jump8 (code, 0);
+                               amd64_patch (br [0], code);
+
+                               /* Negative case */
+                               /* Save to the red zone */
+                               amd64_mov_membase_reg (code, AMD64_RSP, -8, 
AMD64_RAX, 8);
+                               amd64_mov_membase_reg (code, AMD64_RSP, -16, 
AMD64_RCX, 8);
+                               amd64_mov_reg_reg (code, AMD64_RCX, ins->sreg1, 
8);
+                               amd64_mov_reg_reg (code, AMD64_RAX, ins->sreg1, 
8);
+                               amd64_alu_reg_imm (code, X86_AND, AMD64_RCX, 1);
+                               amd64_shift_reg_imm (code, X86_SHR, AMD64_RAX, 
1);
+                               amd64_alu_reg_imm (code, X86_OR, AMD64_RAX, 
AMD64_RCX);
+                               amd64_sse_cvtsi2sd_reg_reg (code, ins->dreg, 
AMD64_RAX);
+                               amd64_sse_addsd_reg_reg (code, ins->dreg, 
ins->dreg);
+                               /* Restore */
+                               amd64_mov_reg_membase (code, AMD64_RCX, 
AMD64_RSP, -16, 8);
+                               amd64_mov_reg_membase (code, AMD64_RAX, 
AMD64_RSP, -8, 8);
+                               amd64_patch (br [1], code);
+
+                               break;
+                       }
+
                        /* load 64bit integer to FP stack */
                        amd64_push_imm (code, 0);
                        amd64_push_reg (code, ins->sreg2);
@@ -3648,7 +3674,7 @@
                        
                        /* test if lreg is negative */
                        amd64_test_reg_reg (code, ins->sreg2, ins->sreg2);
-                       br = code; x86_branch8 (code, X86_CC_GEZ, 0, TRUE);
+                       br [0] = code; x86_branch8 (code, X86_CC_GEZ, 0, TRUE);
        
                        /* add correction constant mn */
                        x86_fld80_mem (code, (gssize)mn);
@@ -3656,7 +3682,7 @@
                        amd64_fp_op_reg (code, X86_FADD, 1, TRUE);
                        x86_fst80_membase (code, AMD64_RSP, 0);
 
-                       amd64_patch (br, code);
+                       amd64_patch (br [0], code);
 
                        x86_fld80_membase (code, AMD64_RSP, 0);
                        amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, 12);

Modified: trunk/mono/mono/mini/mini-amd64.h
===================================================================
--- trunk/mono/mono/mini/mini-amd64.h   2007-12-20 18:00:20 UTC (rev 91724)
+++ trunk/mono/mono/mini/mini-amd64.h   2007-12-20 18:00:35 UTC (rev 91725)
@@ -252,7 +252,6 @@
 #define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS
 
 #define MONO_ARCH_EMULATE_CONV_R8_UN    1
-#define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
 #define MONO_ARCH_EMULATE_FREM 1
 #define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1
 

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to