2007-12-20 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Thu, 20 Dec 2007 18:00:35 +0000 (18:00 -0000)
committerZoltan Varga <vargaz@gmail.com>
Thu, 20 Dec 2007 18:00:35 +0000 (18:00 -0000)
* 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.

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

mono/mini/ChangeLog
mono/mini/basic-float.cs
mono/mini/cpu-amd64.md
mono/mini/inssel-amd64.brg
mono/mini/mini-amd64.c
mono/mini/mini-amd64.h

index 2f22af2edf4d092bc5d126dbc44137cd7c343825..57f5df33d286a02540c74c38e6ac97530edfccd8 100644 (file)
@@ -1,3 +1,10 @@
+2007-12-20  Zoltan Varga  <vargaz@gmail.com>
+
+       * 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  <vargaz@gmail.com>
 
        * mini.c (mono_method_to_ir): Fix a warning.
index fb731f687789ef1547c1504cd5221dba3eab6fde..17047ffbd9038198f4997084de1e0dad56b59455 100644 (file)
@@ -192,6 +192,15 @@ class Tests {
                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;
index bb2e1e0909540a442f052a811421804f1728483c..4d36be3a7598809e91a9cc291ecbb6abd5d89950 100644 (file)
@@ -241,7 +241,7 @@ long_conv_to_r8: dest:f src1:i len:8
 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
index 95b77cb80d9fd0b8fa6c155bac1743971a1fc99c..1a17f916b0496e969e88185ddf555dcac2f8f241 100644 (file)
@@ -73,6 +73,7 @@ stmt: OP_ENDFILTER (reg) {
        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;
index 1af93720c6a29da531e4f0143378728ccf898002..63c91cf5d145d5420913a8149a7debbd376c92a7 100644 (file)
@@ -3633,10 +3633,36 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        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);
@@ -3648,7 +3674,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        
                        /* 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 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        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);
index f2e0367ab7c810dbdd6643ea48b14d2fbd082423..57cb11101df5cc20c727d8552b3824dff632fe62 100644 (file)
@@ -252,7 +252,6 @@ typedef struct {
 #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