#include "inssel.h"
#include "cpu-pentium.h"
-#ifdef HAVE_VALGRIND_MEMCHECK_H
-/* valgrind chokes on __thread */
-#undef HAVE_KW_THREAD
-#endif
-
static gint lmf_tls_offset = -1;
#ifdef PLATFORM_WIN32
}
x86_mul_reg (code, non_eax_reg, FALSE);
/* save before the check since pop and mov don't change the flags */
+ if (ins->dreg != X86_EAX)
+ x86_mov_reg_reg (code, ins->dreg, X86_EAX, 4);
if (saved_edx)
x86_pop_reg (code, X86_EDX);
if (saved_eax)
x86_pop_reg (code, X86_EAX);
- if (ins->dreg != X86_EAX)
- x86_mov_reg_reg (code, ins->dreg, X86_EAX, 4);
EMIT_COND_SYSTEM_EXCEPTION (X86_CC_O, FALSE, "OverflowException");
break;
}
x86_mov_reg_imm (code, ins->dreg, 0);
break;
case CEE_CONV_I4:
- case CEE_CONV_U4:
case OP_MOVE:
x86_mov_reg_reg (code, ins->dreg, ins->sreg1, 4);
break;
+ case CEE_CONV_U4:
+ g_assert_not_reached ();
case CEE_JMP: {
/*
* Note: this 'frame destruction' logic is useful for tail calls, too.
x86_push_reg (code, X86_EAX);
x86_fptan (code);
x86_fnstsw (code);
- x86_test_reg_imm (code, X86_EAX, 0x400);
+ x86_test_reg_imm (code, X86_EAX, X86_FP_C2);
check_pos = code;
x86_branch8 (code, X86_CC_NE, 0, FALSE);
x86_fstp (code, 0); /* pop the 1.0 */
x86_fxch (code, 1);
x86_fprem1 (code);
x86_fstsw (code);
- x86_test_reg_imm (code, X86_EAX, 0x400);
+ x86_test_reg_imm (code, X86_EAX, X86_FP_C2);
pop_jump = code;
x86_branch8 (code, X86_CC_NE, 0, FALSE);
x86_fstp (code, 1);
/* x86_fprem1 (code); */
x86_fprem (code);
x86_fnstsw (code);
- x86_alu_reg_imm (code, X86_AND, X86_EAX, 0x0400);
+ x86_alu_reg_imm (code, X86_AND, X86_EAX, X86_FP_C2);
l2 = code + 2;
x86_branch8 (code, X86_CC_NE, l1 - l2, FALSE);
}
/* this overwrites EAX */
EMIT_FPCOMPARE(code);
- x86_alu_reg_imm (code, X86_AND, X86_EAX, 0x4500);
+ x86_alu_reg_imm (code, X86_AND, X86_EAX, X86_FP_CC_MASK);
break;
case OP_FCEQ:
if (cfg->opt & MONO_OPT_FCMOV) {
x86_push_reg (code, X86_EAX);
EMIT_FPCOMPARE(code);
- x86_alu_reg_imm (code, X86_AND, X86_EAX, 0x4500);
+ x86_alu_reg_imm (code, X86_AND, X86_EAX, X86_FP_CC_MASK);
x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x4000);
x86_set_reg (code, X86_CC_EQ, ins->dreg, TRUE);
x86_widen_reg (code, ins->dreg, ins->dreg, FALSE, FALSE);
x86_push_reg (code, X86_EAX);
EMIT_FPCOMPARE(code);
- x86_alu_reg_imm (code, X86_AND, X86_EAX, 0x4500);
+ x86_alu_reg_imm (code, X86_AND, X86_EAX, X86_FP_CC_MASK);
if (ins->opcode == OP_FCLT_UN) {
guchar *is_not_zero_check, *end_jump;
is_not_zero_check = code;
end_jump = code;
x86_jump8 (code, 0);
x86_patch (is_not_zero_check, code);
- x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x4500);
+ x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_CC_MASK);
x86_patch (end_jump, code);
}
x86_push_reg (code, X86_EAX);
EMIT_FPCOMPARE(code);
- x86_alu_reg_imm (code, X86_AND, X86_EAX, 0x4500);
- x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x0100);
+ x86_alu_reg_imm (code, X86_AND, X86_EAX, X86_FP_CC_MASK);
+ x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_C0);
if (ins->opcode == OP_FCGT_UN) {
guchar *is_not_zero_check, *end_jump;
is_not_zero_check = code;
end_jump = code;
x86_jump8 (code, 0);
x86_patch (is_not_zero_check, code);
- x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x4500);
+ x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_CC_MASK);
x86_patch (end_jump, code);
}
EMIT_COND_BRANCH (ins, X86_CC_EQ, TRUE);
break;
case OP_FBNE_UN:
+ /* Branch if C013 != 100 */
if (cfg->opt & MONO_OPT_FCMOV) {
- EMIT_COND_BRANCH (ins, X86_CC_P, FALSE);
+ /* branch if !ZF or (PF|CF) */
EMIT_COND_BRANCH (ins, X86_CC_NE, FALSE);
+ EMIT_COND_BRANCH (ins, X86_CC_P, FALSE);
+ EMIT_COND_BRANCH (ins, X86_CC_B, FALSE);
break;
}
- x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x4000);
+ x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_C3);
EMIT_COND_BRANCH (ins, X86_CC_NE, FALSE);
break;
case OP_FBLT:
end_jump = code;
x86_jump8 (code, 0);
x86_patch (is_not_zero_check, code);
- x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x4500);
+ x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_CC_MASK);
x86_patch (end_jump, code);
}
EMIT_COND_BRANCH (ins, X86_CC_LT, FALSE);
break;
}
- x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x0100);
+ x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_C0);
if (ins->opcode == OP_FBGT_UN) {
guchar *is_not_zero_check, *end_jump;
is_not_zero_check = code;
end_jump = code;
x86_jump8 (code, 0);
x86_patch (is_not_zero_check, code);
- x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x4500);
+ x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_CC_MASK);
x86_patch (end_jump, code);
}
EMIT_COND_BRANCH (ins, X86_CC_EQ, FALSE);
break;
case OP_FBGE:
+ /* Branch if C013 == 100 or 001 */
+ if (cfg->opt & MONO_OPT_FCMOV) {
+ guchar *br1;
+
+ /* skip branch if C1=1 */
+ br1 = code;
+ x86_branch8 (code, X86_CC_P, 0, FALSE);
+ /* branch if (C0 | C3) = 1 */
+ EMIT_COND_BRANCH (ins, X86_CC_BE, FALSE);
+ x86_patch (br1, code);
+ break;
+ }
+ x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_C0);
+ EMIT_COND_BRANCH (ins, X86_CC_EQ, FALSE);
+ x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_C3);
+ EMIT_COND_BRANCH (ins, X86_CC_EQ, FALSE);
+ break;
case OP_FBGE_UN:
+ /* Branch if C013 == 000 */
if (cfg->opt & MONO_OPT_FCMOV) {
EMIT_COND_BRANCH (ins, X86_CC_LE, FALSE);
break;
EMIT_COND_BRANCH (ins, X86_CC_NE, FALSE);
break;
case OP_FBLE:
+ /* Branch if C013=000 or 100 */
+ if (cfg->opt & MONO_OPT_FCMOV) {
+ guchar *br1;
+
+ /* skip branch if C1=1 */
+ br1 = code;
+ x86_branch8 (code, X86_CC_P, 0, FALSE);
+ /* branch if C0=0 */
+ EMIT_COND_BRANCH (ins, X86_CC_NB, FALSE);
+ x86_patch (br1, code);
+ break;
+ }
+ x86_alu_reg_imm (code, X86_AND, X86_EAX, (X86_FP_C0|X86_FP_C1));
+ x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0);
+ EMIT_COND_BRANCH (ins, X86_CC_EQ, FALSE);
+ break;
case OP_FBLE_UN:
+ /* Branch if C013 != 001 */
if (cfg->opt & MONO_OPT_FCMOV) {
EMIT_COND_BRANCH (ins, X86_CC_P, FALSE);
EMIT_COND_BRANCH (ins, X86_CC_GE, FALSE);
break;
}
- x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x0100);
+ x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_C0);
EMIT_COND_BRANCH (ins, X86_CC_NE, FALSE);
break;
case CEE_CKFINITE: {
x86_fxam (code);
x86_fnstsw (code);
x86_alu_reg_imm (code, X86_AND, X86_EAX, 0x4100);
- x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x0100);
+ x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_C0);
x86_pop_reg (code, X86_EAX);
EMIT_COND_SYSTEM_EXCEPTION (X86_CC_EQ, FALSE, "ArithmeticException");
break;
void
mono_arch_setup_jit_tls_data (MonoJitTlsData *tls)
{
-#ifndef MONO_ARCH_SIGSEGV_ON_ALTSTACK
+#ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK
pthread_t self = pthread_self();
pthread_attr_t attr;
void *staddr = NULL;
}
}
-#ifndef MONO_ARCH_SIGSEGV_ON_ALTSTACK
+#ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK
/* Determine stack boundaries */
if (!mono_running_on_valgrind ()) {
void
mono_arch_free_jit_tls_data (MonoJitTlsData *tls)
{
-#ifndef PLATFORM_WIN32
+#ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK
struct sigaltstack sa;
sa.ss_sp = tls->signal_stack;