Piotr Caban : msvcrt: Support fdiv m64fp in i386 _fpieee_flt.
Alexandre Julliard
julliard at winehq.org
Wed Aug 24 12:05:18 CDT 2016
Module: wine
Branch: master
Commit: a6ffb1d2cf4b86290e61e1c44c8e3c9179c4172d
URL: http://source.winehq.org/git/wine.git/?a=commit;h=a6ffb1d2cf4b86290e61e1c44c8e3c9179c4172d
Author: Piotr Caban <piotr at codeweavers.com>
Date: Wed Aug 24 13:58:00 2016 +0200
msvcrt: Support fdiv m64fp in i386 _fpieee_flt.
Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/msvcrt/except_i386.c | 70 +++++++++++++++++++++++++++++-
dlls/msvcrt/msvcrt.h | 107 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 175 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/except_i386.c b/dlls/msvcrt/except_i386.c
index 6a01fa7..d26a864 100644
--- a/dlls/msvcrt/except_i386.c
+++ b/dlls/msvcrt/except_i386.c
@@ -1124,8 +1124,74 @@ void __stdcall _seh_longjmp_unwind4(struct MSVCRT___JUMP_BUFFER *jmp)
int __cdecl _fpieee_flt(ULONG exception_code, EXCEPTION_POINTERS *ep,
int (__cdecl *handler)(_FPIEEE_RECORD*))
{
- FIXME("(%x %p %p) opcode: %x\n", exception_code, ep, handler,
- *(ULONG*)ep->ContextRecord->FloatSave.ErrorOffset);
+ FLOATING_SAVE_AREA *ctx = &ep->ContextRecord->FloatSave;
+ _FPIEEE_RECORD rec;
+ int ret;
+
+ TRACE("(%x %p %p)\n", exception_code, ep, handler);
+
+ switch(exception_code) {
+ case STATUS_FLOAT_DIVIDE_BY_ZERO:
+ case STATUS_FLOAT_INEXACT_RESULT:
+ case STATUS_FLOAT_INVALID_OPERATION:
+ case STATUS_FLOAT_OVERFLOW:
+ case STATUS_FLOAT_UNDERFLOW:
+ break;
+ default:
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+
+ memset(&rec, 0, sizeof(rec));
+ rec.RoundingMode = ctx->ControlWord >> 10;
+ switch((ctx->ControlWord >> 8) & 0x3) {
+ case 0: rec.Precision = 2; break;
+ case 1: rec.Precision = 3; break;
+ case 2: rec.Precision = 1; break;
+ case 3: rec.Precision = 0; break;
+ }
+ rec.Status.InvalidOperation = ctx->StatusWord & 0x1;
+ rec.Status.ZeroDivide = ((ctx->StatusWord & 0x4) != 0);
+ rec.Status.Overflow = ((ctx->StatusWord & 0x8) != 0);
+ rec.Status.Underflow = ((ctx->StatusWord & 0x10) != 0);
+ rec.Status.Inexact = ((ctx->StatusWord & 0x20) != 0);
+ rec.Enable.InvalidOperation = ((ctx->ControlWord & 0x1) == 0);
+ rec.Enable.ZeroDivide = ((ctx->ControlWord & 0x4) == 0);
+ rec.Enable.Overflow = ((ctx->ControlWord & 0x8) == 0);
+ rec.Enable.Underflow = ((ctx->ControlWord & 0x10) == 0);
+ rec.Enable.Inexact = ((ctx->ControlWord & 0x20) == 0);
+ rec.Cause.InvalidOperation = rec.Enable.InvalidOperation & rec.Status.InvalidOperation;
+ rec.Cause.ZeroDivide = rec.Enable.ZeroDivide & rec.Status.ZeroDivide;
+ rec.Cause.Overflow = rec.Enable.Overflow & rec.Status.Overflow;
+ rec.Cause.Underflow = rec.Enable.Underflow & rec.Status.Underflow;
+ rec.Cause.Inexact = rec.Enable.Inexact & rec.Status.Inexact;
+
+ TRACE("opcode: %x\n", *(ULONG*)ep->ContextRecord->FloatSave.ErrorOffset);
+
+ if(*(WORD*)ctx->ErrorOffset == 0x35dc) { /* fdiv m64fp */
+ if(exception_code==STATUS_FLOAT_DIVIDE_BY_ZERO || exception_code==STATUS_FLOAT_INVALID_OPERATION) {
+ rec.Operand1.OperandValid = 1;
+ rec.Result.OperandValid = 0;
+ } else {
+ rec.Operand1.OperandValid = 0;
+ rec.Result.OperandValid = 1;
+ }
+ rec.Operand2.OperandValid = 1;
+ rec.Operation = _FpCodeDivide;
+ rec.Operand1.Format = _FpFormatFp80;
+ memcpy(&rec.Operand1.Value.Fp80Value, ctx->RegisterArea, sizeof(rec.Operand1.Value.Fp80Value));
+ rec.Operand2.Format = _FpFormatFp64;
+ rec.Operand2.Value.Fp64Value = *(double*)ctx->DataOffset;
+ rec.Result.Format = _FpFormatFp80;
+ memcpy(&rec.Result.Value.Fp80Value, ctx->RegisterArea, sizeof(rec.Operand1.Value.Fp80Value));
+
+ ret = handler(&rec);
+
+ if(ret == EXCEPTION_CONTINUE_EXECUTION)
+ memcpy(ctx->RegisterArea, &rec.Result.Value.Fp80Value, sizeof(rec.Operand1.Value.Fp80Value));
+ return ret;
+ }
+
+ FIXME("unsupported opcode: %x\n", *(ULONG*)ep->ContextRecord->FloatSave.ErrorOffset);
return EXCEPTION_CONTINUE_SEARCH;
}
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index eb6273d..71d80c9 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -1177,6 +1177,113 @@ extern char* __cdecl __unDName(char *,const char*,int,malloc_func_t,free_func_t,
#define UCRTBASE_SCANF_MASK (0x0007)
typedef enum {
+ _FpCodeUnspecified,
+ _FpCodeAdd,
+ _FpCodeSubtract,
+ _FpCodeMultiply,
+ _FpCodeDivide,
+ _FpCodeSquareRoot,
+ _FpCodeRemainder,
+ _FpCodeCompare,
+ _FpCodeConvert,
+ _FpCodeRound,
+ _FpCodeTruncate,
+ _FpCodeFloor,
+ _FpCodeCeil,
+ _FpCodeAcos,
+ _FpCodeAsin,
+ _FpCodeAtan,
+ _FpCodeAtan2,
+ _FpCodeCabs,
+ _FpCodeCos,
+ _FpCodeCosh,
+ _FpCodeExp,
+ _FpCodeFabs,
+ _FpCodeFmod,
+ _FpCodeFrexp,
+ _FpCodeHypot,
+ _FpCodeLdexp,
+ _FpCodeLog,
+ _FpCodeLog10,
+ _FpCodeModf,
+ _FpCodePow,
+ _FpCodeSin,
+ _FpCodeSinh,
+ _FpCodeTan,
+ _FpCodeTanh,
+ _FpCodeY0,
+ _FpCodeY1,
+ _FpCodeYn,
+ _FpCodeLogb,
+ _FpCodeNextafter,
+ _FpCodeNegate,
+ _FpCodeFmin,
+ _FpCodeFmax,
+ _FpCodeConvertTrunc,
+ _XMMIAddps,
+ _XMMIAddss,
+ _XMMISubps,
+ _XMMISubss,
+ _XMMIMulps,
+ _XMMIMulss,
+ _XMMIDivps,
+ _XMMIDivss,
+ _XMMISqrtps,
+ _XMMISqrtss,
+ _XMMIMaxps,
+ _XMMIMaxss,
+ _XMMIMinps,
+ _XMMIMinss,
+ _XMMICmpps,
+ _XMMICmpss,
+ _XMMIComiss,
+ _XMMIUComiss,
+ _XMMICvtpi2ps,
+ _XMMICvtsi2ss,
+ _XMMICvtps2pi,
+ _XMMICvtss2si,
+ _XMMICvttps2pi,
+ _XMMICvttss2si,
+ _XMMIAddsubps,
+ _XMMIHaddps,
+ _XMMIHsubps,
+ _XMMI2Addpd,
+ _XMMI2Addsd,
+ _XMMI2Subpd,
+ _XMMI2Subsd,
+ _XMMI2Mulpd,
+ _XMMI2Mulsd,
+ _XMMI2Divpd,
+ _XMMI2Divsd,
+ _XMMI2Sqrtpd,
+ _XMMI2Sqrtsd,
+ _XMMI2Maxpd,
+ _XMMI2Maxsd,
+ _XMMI2Minpd,
+ _XMMI2Minsd,
+ _XMMI2Cmppd,
+ _XMMI2Cmpsd,
+ _XMMI2Comisd,
+ _XMMI2UComisd,
+ _XMMI2Cvtpd2pi,
+ _XMMI2Cvtsd2si,
+ _XMMI2Cvttpd2pi,
+ _XMMI2Cvttsd2si,
+ _XMMI2Cvtps2pd,
+ _XMMI2Cvtss2sd,
+ _XMMI2Cvtpd2ps,
+ _XMMI2Cvtsd2ss,
+ _XMMI2Cvtdq2ps,
+ _XMMI2Cvttps2dq,
+ _XMMI2Cvtps2dq,
+ _XMMI2Cvttpd2dq,
+ _XMMI2Cvtpd2dq,
+ _XMMI2Addsubpd,
+ _XMMI2Haddpd,
+ _XMMI2Hsubpd,
+} _FP_OPERATION_CODE;
+
+typedef enum {
_FpFormatFp32,
_FpFormatFp64,
_FpFormatFp80,
More information about the wine-cvs
mailing list