msvcrt: Support fdiv m64fp in i386 _fpieee_flt.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Piotr Caban 2016-08-24 13:58:00 +02:00 committed by Alexandre Julliard
parent dc0e3d0a9c
commit a6ffb1d2cf
2 changed files with 175 additions and 2 deletions

View File

@ -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 _fpieee_flt(ULONG exception_code, EXCEPTION_POINTERS *ep,
int (__cdecl *handler)(_FPIEEE_RECORD*)) int (__cdecl *handler)(_FPIEEE_RECORD*))
{ {
FIXME("(%x %p %p) opcode: %x\n", exception_code, ep, handler, FLOATING_SAVE_AREA *ctx = &ep->ContextRecord->FloatSave;
*(ULONG*)ep->ContextRecord->FloatSave.ErrorOffset); _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; return EXCEPTION_CONTINUE_SEARCH;
} }

View File

@ -1176,6 +1176,113 @@ extern char* __cdecl __unDName(char *,const char*,int,malloc_func_t,free_func_t,
#define UCRTBASE_SCANF_MASK (0x0007) #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 { typedef enum {
_FpFormatFp32, _FpFormatFp32,
_FpFormatFp64, _FpFormatFp64,