Author: zoltan
Date: 2005-03-06 16:28:08 -0500 (Sun, 06 Mar 2005)
New Revision: 41492
Modified:
trunk/mono/mono/mini/ChangeLog
trunk/mono/mono/mini/cpu-amd64.md
trunk/mono/mono/mini/inssel-amd64.brg
trunk/mono/mono/mini/inssel.brg
trunk/mono/mono/mini/mini-amd64.c
trunk/mono/mono/mini/mini-amd64.h
trunk/mono/mono/mini/mini-ops.h
Log:
2005-03-06 Zoltan Varga <[EMAIL PROTECTED]>
* mini-ops.h: Add OP_F<xx>_MEMBASE opcodes.
* inssel.brg: Add MONO_EMIT_BIALU_MEMBASE macro.
* cpu-amd64.md inssel-amd64.brg mini-amd64.h mini-amd64.brg: Finish SSE2
support and enable it by default. Also add OP_F<xxx>_MEMBASE opcodes.
Modified: trunk/mono/mono/mini/ChangeLog
===================================================================
--- trunk/mono/mono/mini/ChangeLog 2005-03-06 21:25:22 UTC (rev 41491)
+++ trunk/mono/mono/mini/ChangeLog 2005-03-06 21:28:08 UTC (rev 41492)
@@ -1,5 +1,12 @@
2005-03-06 Zoltan Varga <[EMAIL PROTECTED]>
+ * mini-ops.h: Add OP_F<xx>_MEMBASE opcodes.
+
+ * inssel.brg: Add MONO_EMIT_BIALU_MEMBASE macro.
+
+ * cpu-amd64.md inssel-amd64.brg mini-amd64.h mini-amd64.brg: Finish SSE2
+ support and enable it by default. Also add OP_F<xxx>_MEMBASE opcodes.
+
* basic-float.cs: Add rounding regression test.
* mini-amd64.c (INST_IGNORES_CFLAGS): Add more instructions.
Modified: trunk/mono/mono/mini/cpu-amd64.md
===================================================================
--- trunk/mono/mono/mini/cpu-amd64.md 2005-03-06 21:25:22 UTC (rev 41491)
+++ trunk/mono/mono/mini/cpu-amd64.md 2005-03-06 21:28:08 UTC (rev 41492)
@@ -472,6 +472,11 @@
float_cgt_un: dest:i src1:f src2:f len:48
float_clt: dest:i src1:f src2:f len:35
float_clt_un: dest:i src1:f src2:f len:42
+float_ceq_membase: dest:i src1:f src2:b len:35
+float_cgt_membase: dest:i src1:f src2:b len:35
+float_cgt_un_membase: dest:i src1:f src2:b len:48
+float_clt_membase: dest:i src1:f src2:b len:35
+float_clt_un_membase: dest:i src1:f src2:b len:42
float_conv_to_u: dest:i src1:f len:46
fmove: dest:f src1:f len:8
call_handler: len:14
Modified: trunk/mono/mono/mini/inssel-amd64.brg
===================================================================
--- trunk/mono/mono/mini/inssel-amd64.brg 2005-03-06 21:25:22 UTC (rev
41491)
+++ trunk/mono/mono/mini/inssel-amd64.brg 2005-03-06 21:28:08 UTC (rev
41492)
@@ -613,29 +613,70 @@
# either improve the local register allocator or
# emit coarse opcodes which saves EAX for us.
-reg: OP_CEQ (OP_COMPARE (freg, freg)) {
- MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
- state->left->right->reg1);
-}
-reg: OP_CLT (OP_COMPARE (freg, freg)) {
- MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
- state->left->right->reg1);
-}
+reg: OP_CEQ (OP_COMPARE (freg, freg)),
+reg: OP_CLT (OP_COMPARE (freg, freg)),
+reg: OP_CGT (OP_COMPARE (freg, freg)),
+reg: OP_CLT_UN (OP_COMPARE (freg, freg)),
+reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {
+ int opcode;
-reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {
- MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1,
state->left->left->reg1,
- state->left->right->reg1);
-}
+ switch (tree->opcode) {
+ case OP_CEQ:
+ opcode = OP_FCEQ;
+ break;
+ case OP_CLT:
+ opcode = OP_FCLT;
+ break;
+ case OP_CGT:
+ opcode = OP_FCGT;
+ break;
+ case OP_CLT_UN:
+ opcode = OP_FCLT_UN;
+ break;
+ case OP_CGT_UN:
+ opcode = OP_FCGT_UN;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
-reg: OP_CGT (OP_COMPARE (freg, freg)) {
- MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
+ MONO_EMIT_BIALU (s, tree, opcode, state->reg1, state->left->left->reg1,
state->left->right->reg1);
}
-reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {
- MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1,
state->left->left->reg1,
- state->left->right->reg1);
+reg: OP_CEQ (OP_COMPARE (freg, CEE_LDIND_R8 (base))),
+reg: OP_CLT (OP_COMPARE (freg, CEE_LDIND_R8 (base))),
+reg: OP_CGT (OP_COMPARE (freg, CEE_LDIND_R8 (base))),
+reg: OP_CGT_UN (OP_COMPARE (freg, CEE_LDIND_R8 (base))),
+reg: OP_CLT_UN (OP_COMPARE (freg, CEE_LDIND_R8 (base))) {
+ MonoInst *base = state->left->right->left->tree;
+ int opcode;
+
+ switch (tree->opcode) {
+ case OP_CEQ:
+ opcode = OP_FCEQ_MEMBASE;
+ break;
+ case OP_CLT:
+ opcode = OP_FCLT_MEMBASE;
+ break;
+ case OP_CGT:
+ opcode = OP_FCGT_MEMBASE;
+ break;
+ case OP_CLT_UN:
+ opcode = OP_FCLT_UN_MEMBASE;
+ break;
+ case OP_CGT_UN:
+ opcode = OP_FCGT_UN_MEMBASE;
+ break;
+ default:
+ break;
+ }
+
+ MONO_EMIT_BIALU_MEMBASE (s, tree, opcode, state->reg1,
state->left->left->reg1, base->inst_basereg, base->inst_offset);
+} cost {
+ MBCOND (mono_amd64_is_sse2 ());
+ return 0;
}
# fpcflags overwrites EAX, but this does not matter for statements
@@ -715,34 +756,19 @@
reg: CEE_ADD(reg, CEE_LDIND_I4 (base)) {
MonoInst *base = state->right->left->tree;
- tree->dreg = state->reg1;
- tree->sreg1 = state->left->reg1;
- tree->sreg2 = base->inst_basereg;
- tree->inst_offset = base->inst_offset;
- tree->opcode = OP_X86_ADD_MEMBASE;
- mono_bblock_add_inst (s->cbb, tree);
+ MONO_EMIT_BIALU_MEMBASE (cfg, tree, OP_X86_ADD_MEMBASE, state->reg1,
state->left->reg1, base->inst_basereg, base->inst_offset);
}
reg: CEE_SUB(reg, CEE_LDIND_I4 (base)) {
MonoInst *base = state->right->left->tree;
- tree->dreg = state->reg1;
- tree->sreg1 = state->left->reg1;
- tree->sreg2 = base->inst_basereg;
- tree->inst_offset = base->inst_offset;
- tree->opcode = OP_X86_SUB_MEMBASE;
- mono_bblock_add_inst (s->cbb, tree);
+ MONO_EMIT_BIALU_MEMBASE (cfg, tree, OP_X86_SUB_MEMBASE, state->reg1,
state->left->reg1, base->inst_basereg, base->inst_offset);
}
reg: CEE_MUL(reg, CEE_LDIND_I4 (base)) {
MonoInst *base = state->right->left->tree;
- tree->dreg = state->reg1;
- tree->sreg1 = state->left->reg1;
- tree->sreg2 = base->inst_basereg;
- tree->inst_offset = base->inst_offset;
- tree->opcode = OP_X86_MUL_MEMBASE;
- mono_bblock_add_inst (s->cbb, tree);
+ MONO_EMIT_BIALU_MEMBASE (cfg, tree, OP_X86_MUL_MEMBASE, state->reg1,
state->left->reg1, base->inst_basereg, base->inst_offset);
}
reg: OP_LSHL (reg, reg) "0" {
Modified: trunk/mono/mono/mini/inssel.brg
===================================================================
--- trunk/mono/mono/mini/inssel.brg 2005-03-06 21:25:22 UTC (rev 41491)
+++ trunk/mono/mono/mini/inssel.brg 2005-03-06 21:28:08 UTC (rev 41492)
@@ -78,6 +78,15 @@
mono_bblock_add_inst (cfg->cbb, inst); \
} while (0)
+#define MONO_EMIT_BIALU_MEMBASE(cfg,tree,op,dr,sr,basereg,offset) do { \
+ tree->opcode = op; \
+ tree->dreg = dr; \
+ tree->sreg1 = sr; \
+ tree->sreg2 = basereg; \
+ tree->inst_offset = offset; \
+ mono_bblock_add_inst (s->cbb, tree); \
+ } while (0)
+
#define MONO_EMIT_LOAD_MEMBASE(cfg,inst,dr,base,offset) do { \
(inst)->opcode = OP_LOAD_MEMBASE; \
(inst)->dreg = dr; \
Modified: trunk/mono/mono/mini/mini-amd64.c
===================================================================
--- trunk/mono/mono/mini/mini-amd64.c 2005-03-06 21:25:22 UTC (rev 41491)
+++ trunk/mono/mono/mini/mini-amd64.c 2005-03-06 21:28:08 UTC (rev 41492)
@@ -30,7 +30,7 @@
static gint thread_tls_offset = -1;
/* Use SSE2 instructions for fp arithmetic */
-static gboolean use_sse2 = FALSE;
+static gboolean use_sse2 = TRUE;
/* xmm15 is reserved for use by some opcodes */
#define AMD64_CALLEE_FREGS 0xef
@@ -69,6 +69,16 @@
* are domain specific.
*/
+/*
+ * Floating point comparison results:
+ * ZF PF CF
+ * A > B 0 0 0
+ * A < B 0 0 1
+ * A = B 1 0 0
+ * A > B 0 0 0
+ * UNORDERED 1 1 1
+ */
+
#define NOT_IMPLEMENTED g_assert_not_reached ()
const char*
@@ -688,6 +698,12 @@
return opts;
}
+gboolean
+mono_amd64_is_sse2 (void)
+{
+ return use_sse2;
+}
+
static gboolean
is_regsize_var (MonoType *t) {
if (t->byref)
@@ -2923,7 +2939,7 @@
emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int
size, gboolean is_signed)
{
if (use_sse2) {
- amd64_sse_cvtsd2si_reg_reg (code, dreg, sreg);
+ amd64_sse_cvttsd2si_reg_reg (code, dreg, sreg);
}
else {
amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, 8);
@@ -4398,7 +4414,11 @@
}
case OP_FCOMPARE:
if (use_sse2) {
- amd64_sse_comisd_reg_reg (code, ins->sreg1,
ins->sreg2);
+ /*
+ * The two arguments are swapped because the
fbranch instructions
+ * depend on this for the non-sse case to work.
+ */
+ amd64_sse_comisd_reg_reg (code, ins->sreg2,
ins->sreg1);
break;
}
if (cfg->opt & MONO_OPT_FCMOV) {
@@ -4450,7 +4470,7 @@
*/
amd64_alu_reg_reg (code, X86_XOR, ins->dreg,
ins->dreg);
if (use_sse2)
- amd64_sse_comisd_reg_reg (code,
ins->sreg1, ins->sreg2);
+ amd64_sse_comisd_reg_reg (code,
ins->sreg2, ins->sreg1);
else {
amd64_fcomip (code, 1);
amd64_fstp (code, 0);
@@ -4501,7 +4521,7 @@
guchar *unordered_check;
amd64_alu_reg_reg (code, X86_XOR, ins->dreg,
ins->dreg);
if (use_sse2)
- amd64_sse_comisd_reg_reg (code,
ins->sreg1, ins->sreg2);
+ amd64_sse_comisd_reg_reg (code,
ins->sreg2, ins->sreg1);
else {
amd64_fcomip (code, 1);
amd64_fstp (code, 0);
@@ -4539,6 +4559,57 @@
if (ins->dreg != AMD64_RAX)
amd64_pop_reg (code, AMD64_RAX);
break;
+ case OP_FCLT_MEMBASE:
+ case OP_FCGT_MEMBASE:
+ case OP_FCLT_UN_MEMBASE:
+ case OP_FCGT_UN_MEMBASE:
+ case OP_FCEQ_MEMBASE: {
+ guchar *unordered_check, *jump_to_end;
+ int x86_cond;
+ g_assert (use_sse2);
+
+ amd64_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+ amd64_sse_comisd_reg_membase (code, ins->sreg1,
ins->sreg2, ins->inst_offset);
+
+ switch (ins->opcode) {
+ case OP_FCEQ_MEMBASE:
+ x86_cond = X86_CC_EQ;
+ break;
+ case OP_FCLT_MEMBASE:
+ case OP_FCLT_UN_MEMBASE:
+ x86_cond = X86_CC_LT;
+ break;
+ case OP_FCGT_MEMBASE:
+ case OP_FCGT_UN_MEMBASE:
+ x86_cond = X86_CC_GT;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ unordered_check = code;
+ x86_branch8 (code, X86_CC_P, 0, FALSE);
+ amd64_set_reg (code, x86_cond, ins->dreg, FALSE);
+
+ switch (ins->opcode) {
+ case OP_FCEQ_MEMBASE:
+ case OP_FCLT_MEMBASE:
+ case OP_FCGT_MEMBASE:
+ amd64_patch (unordered_check, code);
+ break;
+ case OP_FCLT_UN_MEMBASE:
+ case OP_FCGT_UN_MEMBASE:
+ jump_to_end = code;
+ x86_jump8 (code, 0);
+ amd64_patch (unordered_check, code);
+ amd64_inc_reg (code, ins->dreg);
+ amd64_patch (jump_to_end, code);
+ break;
+ default:
+ break;
+ }
+ break;
+ }
case OP_FBEQ:
if (use_sse2 || (cfg->opt & MONO_OPT_FCMOV)) {
guchar *jump = code;
Modified: trunk/mono/mono/mini/mini-amd64.h
===================================================================
--- trunk/mono/mono/mini/mini-amd64.h 2005-03-06 21:25:22 UTC (rev 41491)
+++ trunk/mono/mono/mini/mini-amd64.h 2005-03-06 21:28:08 UTC (rev 41492)
@@ -229,6 +229,9 @@
void
mono_amd64_tramp_init (void);
+gboolean
+mono_amd64_is_sse2 (void);
+
/* FIXME: */
//#define MONO_ARCH_BIGMUL_INTRINS 1
Modified: trunk/mono/mono/mini/mini-ops.h
===================================================================
--- trunk/mono/mono/mini/mini-ops.h 2005-03-06 21:25:22 UTC (rev 41491)
+++ trunk/mono/mono/mini/mini-ops.h 2005-03-06 21:28:08 UTC (rev 41492)
@@ -338,6 +338,12 @@
MINI_OP(OP_FCLT, "float_clt")
MINI_OP(OP_FCLT_UN,"float_clt_un")
+MINI_OP(OP_FCEQ_MEMBASE, "float_ceq_membase")
+MINI_OP(OP_FCGT_MEMBASE, "float_cgt_membase")
+MINI_OP(OP_FCGT_UN_MEMBASE,"float_cgt_un_membase")
+MINI_OP(OP_FCLT_MEMBASE, "float_clt_membase")
+MINI_OP(OP_FCLT_UN_MEMBASE,"float_clt_un_membase")
+
MINI_OP(OP_FCONV_TO_U, "float_conv_to_u")
MINI_OP(OP_GROUP, "group")
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches