VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/math/feraiseexcept.asm@ 96240

Last change on this file since 96240 was 96213, checked in by vboxsync, 2 years ago

IPRT/nocrt: Implemented feraiseexcept and adjusted relevan code for X86_FSW_XCPT_MASK containg a bit more than X86_MXCSR_XCPT_FLAGS. bugref:10261

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.5 KB
Line 
1; $Id: feraiseexcept.asm 96213 2022-08-15 09:36:00Z vboxsync $
2;; @file
3; IPRT - No-CRT feraiseexcept - AMD64 & X86.
4;
5
6;
7; Copyright (C) 2022 Oracle Corporation
8;
9; This file is part of VirtualBox Open Source Edition (OSE), as
10; available from http://www.virtualbox.org. This file is free software;
11; you can redistribute it and/or modify it under the terms of the GNU
12; General Public License (GPL) as published by the Free Software
13; Foundation, in version 2 as it comes in the "COPYING" file of the
14; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16;
17; The contents of this file may alternatively be used under the terms
18; of the Common Development and Distribution License Version 1.0
19; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20; VirtualBox OSE distribution, in which case the provisions of the
21; CDDL are applicable instead of those of the GPL.
22;
23; You may elect to license modified versions of this file under the
24; terms and conditions of either the GPL or the CDDL or both.
25;
26
27
28%define RT_ASM_WITH_SEH64
29%include "iprt/asmdefs.mac"
30%include "iprt/x86.mac"
31
32
33%ifdef RT_ARCH_AMD64
34 %define RT_NOCRT_RAISE_FPU_EXCEPT_IN_SSE_MODE
35%endif
36
37
38BEGINCODE
39
40;;
41; Raises the given FPU/SSE exceptions.
42;
43; @returns eax = 0 on success, -1 on failure.
44; @param fXcpt 32-bit: [xBP+8]; msc64: ecx; gcc64: edi; -- The exceptions to raise.
45; Accepts X86_FSW_XCPT_MASK, but ignores X86_FSW_DE and X86_FSW_SF.
46;
47RT_NOCRT_BEGINPROC feraiseexcept
48 push xBP
49 SEH64_PUSH_xBP
50 mov xBP, xSP
51 SEH64_SET_FRAME_xBP 0
52%ifndef RT_NOCRT_RAISE_FPU_EXCEPT_IN_SSE_MODE
53 sub xBP, 20h
54 SEH64_ALLOCATE_STACK 20h
55%endif
56 SEH64_END_PROLOGUE
57
58 ;
59 ; Load the parameter into rcx.
60 ;
61%ifdef ASM_CALL64_GCC
62 mov rcx, rdi
63%elifdef RT_ARCH_X86
64 mov ecx, [xBP + xCB*2]
65%endif
66%ifdef RT_STRICT
67 test ecx, ~X86_FSW_XCPT_MASK
68 jz .input_ok
69 int3
70.input_ok:
71%endif
72
73 ;
74 ; We have to raise these buggers one-by-one and order is said to be important.
75 ; We ASSUME that x86 runs is okay with the x87 raising the exception.
76 ;
77
78 ; 1. Invalid operation. Like +0.0 / +0.0.
79 test cl, X86_FSW_IE
80 jz .not_ie
81%ifdef RT_NOCRT_RAISE_FPU_EXCEPT_IN_SSE_MODE
82 movss xmm0, [g_r32Zero xWrtRIP]
83 divss xmm0, xmm0
84%else
85 fnstenv [xBP - 20h]
86 or byte [xBP - 20h + X86FSTENV32P.FSW], X86_FSW_IE
87 fldenv [xBP - 20h]
88 fwait
89%endif
90.not_ie:
91
92 ; 2. Division by zero.
93 test cl, X86_FSW_ZE
94 jz .not_ze
95%ifdef RT_NOCRT_RAISE_FPU_EXCEPT_IN_SSE_MODE
96 movss xmm0, [g_r32Zero xWrtRIP]
97 movss xmm0, [g_r32One xWrtRIP]
98 divss xmm0, xmm1
99%else
100 fnstenv [xBP - 20h]
101 or byte [xBP - 20h + X86FSTENV32P.FSW], X86_FSW_ZE
102 fldenv [xBP - 20h]
103 fwait
104%endif
105.not_ze:
106
107 ; 3. Overflow.
108 test cl, X86_FSW_OE
109 jz .not_oe
110%ifdef RT_NOCRT_RAISE_FPU_EXCEPT_IN_SSE_MODE
111 xorps xmm0, [g_r32Large xWrtRIP]
112 movss xmm1, [g_r32Tiny xWrtRIP]
113 divss xmm0, xmm1
114%else
115 fnstenv [xBP - 20h]
116 or byte [xBP - 20h + X86FSTENV32P.FSW], X86_FSW_OE
117 fldenv [xBP - 20h]
118 fwait
119%endif
120.not_oe:
121
122 ; 4. Underflow.
123 test cl, X86_FSW_UE
124 jz .not_ue
125%ifdef RT_NOCRT_RAISE_FPU_EXCEPT_IN_SSE_MODE
126 xorps xmm0, [g_r32Tiny xWrtRIP]
127 movss xmm1, [g_r32Large xWrtRIP]
128 divss xmm0, xmm1
129%else
130 fnstenv [xBP - 20h]
131 or byte [xBP - 20h + X86FSTENV32P.FSW], X86_FSW_UE
132 fldenv [xBP - 20h]
133 fwait
134%endif
135.not_ue:
136
137 ; 5. Precision.
138 test cl, X86_FSW_PE
139 jz .not_pe
140%ifdef RT_NOCRT_RAISE_FPU_EXCEPT_IN_SSE_MODE
141 xorps xmm0, [g_r32Two xWrtRIP]
142 movss xmm1, [g_r32Three xWrtRIP]
143 divss xmm0, xmm1
144%else
145 fnstenv [xBP - 20h]
146 or byte [xBP - 20h + X86FSTENV32P.FSW], X86_FSW_PE
147 fldenv [xBP - 20h]
148 fwait
149%endif
150.not_pe:
151
152 ; We currently do not raise X86_FSW_DE or X86_FSW_SF.
153
154 ;
155 ; Return success.
156 ;
157 xor eax, eax
158.return:
159 leave
160 ret
161ENDPROC RT_NOCRT(feraiseexcept)
162
163
164%ifdef RT_NOCRT_RAISE_FPU_EXCEPT_IN_SSE_MODE
165g_r32Zero:
166 dd 0.0
167g_r32One:
168 dd 1.0
169g_r32Two:
170 dd 2.0
171g_r32Three:
172 dd 3.0
173g_r32Large:
174 dd 1.0e+38
175g_r32Tiny:
176 dd 1.0e-37
177%endif
178
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette