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