diff --git a/target-i386/op.c b/target-i386/op.c index c157b120b0..2af4e8eb37 100644 --- a/target-i386/op.c +++ b/target-i386/op.c @@ -1952,94 +1952,48 @@ void OPPROTO op_fxchg_ST0_STN(void) /* FPU operations */ +const int fcom_ccval[4] = {0x0100, 0x4000, 0x0000, 0x4500}; + void OPPROTO op_fcom_ST0_FT0(void) { - int cc; - switch(floatx_compare(ST0, FT0, &env->fp_status)) { - case -1: - cc = 0x0100; - break; - case 0: - cc = 0x4000; - break; - case 1: - cc = 0x0000; - break; - case 2: - default: - cc = 0x4500; - break; - } - env->fpus = (env->fpus & ~0x4500) | cc; + int ret; + + ret = floatx_compare(ST0, FT0, &env->fp_status); + env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret + 1]; FORCE_RET(); } void OPPROTO op_fucom_ST0_FT0(void) { - int cc; - switch(floatx_compare_quiet(ST0, FT0, &env->fp_status)) { - case -1: - cc = 0x0100; - break; - case 0: - cc = 0x4000; - break; - case 1: - cc = 0x0000; - break; - case 2: - default: - cc = 0x4500; - break; - } - env->fpus = (env->fpus & ~0x4500) | cc; + int ret; + + ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); + env->fpus = (env->fpus & ~0x4500) | fcom_ccval[ret+ 1]; FORCE_RET(); } +const int fcomi_ccval[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; + void OPPROTO op_fcomi_ST0_FT0(void) { - int eflags, cc; - switch(floatx_compare(ST0, FT0, &env->fp_status)) { - case -1: - cc = CC_C; - break; - case 0: - cc = CC_Z; - break; - case 1: - cc = 0; - break; - case 2: - default: - cc = CC_Z | CC_P | CC_C; - break; - } + int eflags; + int ret; + + ret = floatx_compare(ST0, FT0, &env->fp_status); eflags = cc_table[CC_OP].compute_all(); - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | cc; + eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; CC_SRC = eflags; FORCE_RET(); } void OPPROTO op_fucomi_ST0_FT0(void) { - int eflags, cc; - switch(floatx_compare_quiet(ST0, FT0, &env->fp_status)) { - case -1: - cc = CC_C; - break; - case 0: - cc = CC_Z; - break; - case 1: - cc = 0; - break; - case 2: - default: - cc = CC_Z | CC_P | CC_C; - break; - } + int eflags; + int ret; + + ret = floatx_compare_quiet(ST0, FT0, &env->fp_status); eflags = cc_table[CC_OP].compute_all(); - eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | cc; + eflags = (eflags & ~(CC_Z | CC_P | CC_C)) | fcomi_ccval[ret + 1]; CC_SRC = eflags; FORCE_RET(); } diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h index f982594a8d..cdc3801200 100644 --- a/target-i386/ops_sse.h +++ b/target-i386/ops_sse.h @@ -1079,9 +1079,11 @@ SSE_OP_CMP(cmpnlt, FPU_CMPNLT) SSE_OP_CMP(cmpnle, FPU_CMPNLE) SSE_OP_CMP(cmpord, FPU_CMPORD) +const int comis_eflags[4] = {CC_C, CC_Z, 0, CC_Z | CC_P | CC_C}; + void OPPROTO op_ucomiss(void) { - int eflags; + int ret; float32 s0, s1; Reg *d, *s; d = (Reg *)((char *)env + PARAM1); @@ -1089,28 +1091,14 @@ void OPPROTO op_ucomiss(void) s0 = d->XMM_S(0); s1 = s->XMM_S(0); - switch(float32_compare_quiet(s0, s1, &env->sse_status)) { - case -1: - eflags = CC_C; - break; - case 0: - eflags = CC_Z; - break; - case 1: - eflags = 0; - break; - case 2: - default: - eflags = CC_Z | CC_P | CC_C; - break; - } - CC_SRC = eflags; + ret = float32_compare_quiet(s0, s1, &env->sse_status); + CC_SRC = comis_eflags[ret + 1]; FORCE_RET(); } void OPPROTO op_comiss(void) { - int eflags; + int ret; float32 s0, s1; Reg *d, *s; d = (Reg *)((char *)env + PARAM1); @@ -1118,28 +1106,14 @@ void OPPROTO op_comiss(void) s0 = d->XMM_S(0); s1 = s->XMM_S(0); - switch(float32_compare(s0, s1, &env->sse_status)) { - case -1: - eflags = CC_C; - break; - case 0: - eflags = CC_Z; - break; - case 1: - eflags = 0; - break; - case 2: - default: - eflags = CC_Z | CC_P | CC_C; - break; - } - CC_SRC = eflags; + ret = float32_compare(s0, s1, &env->sse_status); + CC_SRC = comis_eflags[ret + 1]; FORCE_RET(); } void OPPROTO op_ucomisd(void) { - int eflags; + int ret; float64 d0, d1; Reg *d, *s; d = (Reg *)((char *)env + PARAM1); @@ -1147,28 +1121,14 @@ void OPPROTO op_ucomisd(void) d0 = d->XMM_D(0); d1 = s->XMM_D(0); - switch(float64_compare_quiet(d0, d1, &env->sse_status)) { - case -1: - eflags = CC_C; - break; - case 0: - eflags = CC_Z; - break; - case 1: - eflags = 0; - break; - case 2: - default: - eflags = CC_Z | CC_P | CC_C; - break; - } - CC_SRC = eflags; + ret = float64_compare_quiet(d0, d1, &env->sse_status); + CC_SRC = comis_eflags[ret + 1]; FORCE_RET(); } void OPPROTO op_comisd(void) { - int eflags; + int ret; float64 d0, d1; Reg *d, *s; d = (Reg *)((char *)env + PARAM1); @@ -1176,22 +1136,8 @@ void OPPROTO op_comisd(void) d0 = d->XMM_D(0); d1 = s->XMM_D(0); - switch(float64_compare(d0, d1, &env->sse_status)) { - case -1: - eflags = CC_C; - break; - case 0: - eflags = CC_Z; - break; - case 1: - eflags = 0; - break; - case 2: - default: - eflags = CC_Z | CC_P | CC_C; - break; - } - CC_SRC = eflags; + ret = float64_compare(d0, d1, &env->sse_status); + CC_SRC = comis_eflags[ret + 1]; FORCE_RET(); }