VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use