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:
parent
dc0e3d0a9c
commit
a6ffb1d2cf
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue