VirtualBox

Ignore:
Timestamp:
Aug 15, 2022 9:36:00 AM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
153023
Message:

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

Location:
trunk/src/VBox/Runtime/common/math
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/math/feclearexcept.asm

    r96205 r96213  
    3737;
    3838; @returns  eax = 0 on success, non-zero on failure.
    39 ; @param    fXcpts  32-bit: [xBP+8]     msc64: ecx      gcc64: edi   - X86_FSW_XCPT_MASK
     39; @param    fXcpts  32-bit: [xBP+8]; msc64: ecx; gcc64: edi; -- Zero or more bits from X86_FSW_XCPT_MASK
    4040;
    4141RT_NOCRT_BEGINPROC feclearexcept
     
    4949
    5050        ;
    51         ; Load the parameter into ecx.
     51        ; Load the parameter into ecx, validate and adjust it.
    5252        ;
    5353%ifdef ASM_CALL64_GCC
     
    6464%endif
    6565
     66        ; #IE implies #SF
     67        mov     al, cl
     68        and     al, X86_FSW_IE
     69        shl     al, X86_FSW_SF_BIT - X86_FSW_IE_BIT
     70        or      cl, al
     71
    6672        ; Make it into and AND mask suitable for clearing the specified exceptions.
    6773        not     ecx
     
    7278
    7379        ; Modify the x87 flags first (ecx preserved).
    74         cmp     ecx, X86_FSW_XCPT_MASK
    75         jne     .partial_mask
     80        cmp     ecx, ~X86_FSW_XCPT_MASK     ; This includes all the x87 exceptions, including stack error.
     81        jne    .partial_mask
    7682        fnclex
    7783        jmp     .do_sse
     
    9399        ; Modify the SSE flags (modifies ecx).
    94100        stmxcsr [xBP - 10h]
     101        or      ecx, X86_FSW_XCPT_MASK & ~X86_MXCSR_XCPT_FLAGS      ; Don't mix X86_FSW_SF with X86_MXCSR_DAZ.
    95102        and     [xBP - 10h], ecx
    96103        ldmxcsr [xBP - 10h]
  • trunk/src/VBox/Runtime/common/math/fedisableexcept.asm

    r96205 r96213  
    3838; @returns  eax = Previous enabled exceptions on success (not subject to fXcpt),
    3939;                 -1 on failure.
    40 ; @param    fXcpt   32-bit: [xBP+8]     msc64: ecx      gcc64: edi - Mask of exceptions to disable.
     40; @param    fXcpt   32-bit: [xBP+8]; msc64: ecx; gcc64: edi; -- Mask of exceptions to disable.
    4141;
    4242RT_NOCRT_BEGINPROC fedisableexcept
     
    5252        ; Load the parameter into ecx.
    5353        ;
    54         or      eax, -1
    5554%ifdef ASM_CALL64_GCC
    5655        mov     ecx, edi
     
    5857        mov     ecx, [xBP + xCB*2]
    5958%endif
     59        or      eax, -1
    6060        test    ecx, ~X86_FCW_XCPT_MASK
     61%ifndef RT_STRICT
    6162        jnz     .return
     63%else
     64        jz      .input_ok
     65        int3
     66        jmp     .return
     67.input_ok:
     68%endif
    6269
    6370        ;
  • trunk/src/VBox/Runtime/common/math/feenableexcept.asm

    r96205 r96213  
    5252        ; Load the parameter into ecx.
    5353        ;
    54         or      eax, -1
    5554%ifdef ASM_CALL64_GCC
    5655        mov     ecx, edi
     
    5857        mov     ecx, [xBP + xCB*2]
    5958%endif
     59        or      eax, -1
    6060        test    ecx, ~X86_FCW_XCPT_MASK
     61%ifndef RT_STRICT
    6162        jnz     .return
     63%else
     64        jz      .input_ok
     65        int3
     66        jmp     .return
     67.input_ok:
     68%endif
    6269
    6370        ; Invert the mask as we're enabling the exceptions, not masking them.
     
    7178        fstcw   [xBP - 10h]
    7279%ifdef RT_ARCH_X86 ; Return the inverted x87 mask in 32-bit mode.
    73         movzx   eax, word [xBP - 10h]
     80        mov     ax, word [xBP - 10h]
     81        and     eax, X86_FCW_XCPT_MASK
    7482%endif
    7583        and     word [xBP - 10h], cx
     
    8896%ifdef RT_ARCH_AMD64 ; Return the inverted MXCSR exception mask on AMD64 because windows doesn't necessarily set the x87 one.
    8997        mov     eax, [xBP - 10h]
     98        and     eax, X86_MXCSR_XCPT_MASK
    9099        shr     eax, X86_MXCSR_XCPT_MASK_SHIFT
    91100%endif
     
    96105.return_ok:
    97106        not     eax                     ; Invert it as we return the enabled rather than masked exceptions.
    98         and     eax, X86_FCW_XCPT_MASK
    99107.return:
    100108        leave
  • trunk/src/VBox/Runtime/common/math/fegetenv.asm

    r96205 r96213  
    3636; Gets the FPU+SSE environment.
    3737;
    38 ; @returns  eax = x87 exception mask (X86_FCW_XCPT_MASK)
    39 ; @param    pEnv    32-bit: [xBP+8]     msc64: rcx      gcc64: rdi
     38; @returns  eax = 0 on success (-1 on failure),
     39; @param    pEnv    32-bit: [xBP+8]; msc64: rcx; gcc64: rdi -- Pointer to where to store the enviornment.
    4040;
    4141RT_NOCRT_BEGINPROC fegetenv
  • trunk/src/VBox/Runtime/common/math/fegetexcept.asm

    r96205 r96213  
    3434
    3535;;
    36 ; Gets the mask of enabled exceptions, e.g. unmaksed (BSD/GNU extension).
     36; Gets the mask of enabled exceptions, e.g. unmasked (BSD/GNU extension).
    3737;
    38 ; @returns  eax = inverted x87 exception mask (X86_FCW_XCPT_MASK)
     38; @returns  eax = inverted x87/sse exception mask (X86_MXCSR_XCPT_FLAGS).
     39;           Will not return X86_FSW_SF.
    3940;
    4041RT_NOCRT_BEGINPROC fegetexcept
     
    6263%endif
    6364
    64         not     eax                     ; Invert it as we return the enabled rather than masked exceptions.
    65         and     eax, X86_FCW_XCPT_MASK
     65        not     eax                         ; Invert it as we return the enabled rather than masked exceptions.
     66        and     eax, X86_MXCSR_XCPT_FLAGS   ; Use the SSE mask so we don't return X86_FSW_SF here.
    6667
    6768.return_val:
  • trunk/src/VBox/Runtime/common/math/fegetexceptflag.asm

    r96205 r96213  
    3737;
    3838; @returns  eax = 0 on success, non-zero on failure.
    39 ; @param    pfXcpts   32-bit: [xBP+8]     msc64: rcx      gcc64: rdi   - pointer to fexcept_t (16-bit)
    40 ; @param    fXcptMask 32-bit: [xBP+c]     msc64: edx      gcc64: esi   - X86_FSW_XCPT_MASK
     39; @param    pfXcpts     32-bit: [xBP+8]; msc64: rcx; gcc64: rdi; -- Where to store the flags (pointer to fexcept_t (16-bit)).
     40; @param    fXcptMask   32-bit: [xBP+c]; msc64: edx; gcc64: esi; -- The exception flags to get (X86_FSW_XCPT_MASK).
     41;                       Accepts X86_FSW_SF and will return it if given as input.
    4142;
    4243RT_NOCRT_BEGINPROC fegetexceptflag
     
    6465        or      eax, -1
    6566        test    edx, ~X86_FSW_XCPT_MASK
     67 %ifndef RT_STRICT
    6668        jnz     .return
     69 %else
     70        jz      .input_ok
     71        int3
     72        jmp     .return
     73.input_ok:
     74 %endif
    6775%endif
    6876
     
    8896        mov     ax, [xBP - 10h]
    8997        and     ax, dx
     98        and     ax, X86_MXCSR_XCPT_FLAGS        ; Don't confuse X86_MXCSR_DAZ for X86_FSW_SF.
    9099        or      [xCX], ax
    91100
  • trunk/src/VBox/Runtime/common/math/feholdexcept.asm

    r96205 r96213  
    3636; Gets the FPU+SSE environment and disables (masks) all exceptions.
    3737;
    38 ; @returns  eax = x87 exception mask (X86_FCW_XCPT_MASK)
     38; @returns  eax = 0 on success (-1 on failure)
    3939; @param    pEnv    32-bit: [xBP+8]     msc64: rcx      gcc64: rdi
    4040;
  • trunk/src/VBox/Runtime/common/math/fesetenv.asm

    r96205 r96213  
    3232%define RT_NOCRT_FE_DFL_ENV     1
    3333%define RT_NOCRT_FE_NOMASK_ENV  2
     34%define RT_NOCRT_FE_PC53_ENV    3
     35%define RT_NOCRT_FE_PC64_ENV    4
     36%define RT_NOCRT_FE_LAST_ENV    4
    3437
    3538
     
    6669        fnstenv [xBP - 20h]
    6770
    68         cmp     xCX, RT_NOCRT_FE_DFL_ENV
    69         je      .x87_default_env
     71        ; Check for special "pointer" values:
     72        cmp     xCX, RT_NOCRT_FE_LAST_ENV
     73        ja      .x87_regular
     74
     75        or      eax, -1
     76        test    xCX, xCX
     77        jnz     .x87_special
     78%ifdef RT_STRICT
     79        int3
     80%endif
     81        jmp     .return
     82
     83        ;
     84        ; Special x87 state. Clear all pending exceptions.
     85        ;
     86        ; We have 4 special environments with only some differences in FCW differs, so set
     87        ; up FCW in AX, starting with a NOMASK environment as it has the fewest bits set.
     88        ;
     89.x87_special:
     90        and     word [xBP - 20h  + X86FSTENV32P.FSW], ~X86_FSW_XCPT_ES_MASK
     91        mov     ax, [xBP - 20h  + X86FSTENV32P.FCW]
     92        and     ax, ~(X86_FCW_MASK_ALL | X86_FCW_PC_MASK | X86_FCW_RC_MASK    | X86_FCW_IC_MASK)
     93%ifdef RT_OS_WINDOWS
     94        or      ax,         X86_FCW_DM | X86_FCW_PC_53   | X86_FCW_RC_NEAREST | X86_FCW_IC_PROJECTIVE
     95%else
     96        or      ax,         X86_FCW_DM | X86_FCW_PC_64   | X86_FCW_RC_NEAREST | X86_FCW_IC_PROJECTIVE
     97%endif
    7098        cmp     xCX, RT_NOCRT_FE_NOMASK_ENV
    71         je      .x87_default_nomask_env
    72         jmp     .x87_regular
     99        je      .x87_special_done
     100        or      ax, X86_FCW_MASK_ALL
    73101
    74 .x87_default_env:
    75         and     word [xCX + X86FSTENV32P.FCW], ~(X86_FCW_MASK_ALL | X86_FCW_PC_MASK | X86_FCW_RC_MASK    | X86_FCW_IC_MASK)
    76         or      word [xCX + X86FSTENV32P.FCW],   X86_FCW_MASK_ALL | X86_FCW_PC_64   | X86_FCW_RC_NEAREST | X86_FCW_IC_PROJECTIVE
    77         and     word [xCX + X86FSTENV32P.FSW], ~X86_FSW_XCPT_ES_MASK
     102%ifdef RT_OS_WINDOWS
     103        cmp     xCX, RT_NOCRT_FE_PC64_ENV
     104        jne     .x87_special_done
     105        or      ax, X86_FCW_PC_64                   ; X86_FCW_PC_64 is a super set of X86_FCW_PC_53, so no need to clear bits
     106%else
     107        cmp     xCX, RT_NOCRT_FE_PC53_ENV
     108        jne     .x87_special_done
     109        and     ax, X86_FCW_PC_64 & ~X86_FCW_PC_53  ; X86_FCW_PC_64 is a super set of X86_FCW_PC_53, so clear the bit that differs.
     110%endif
     111
     112.x87_special_done:
     113        mov     [xBP - 20h  + X86FSTENV32P.FCW], ax
    78114        jmp     .x87_common
    79115
    80 .x87_default_nomask_env:
    81         and     word [xCX + X86FSTENV32P.FCW], ~(X86_FCW_MASK_ALL | X86_FCW_PC_MASK | X86_FCW_RC_MASK    | X86_FCW_IC_MASK)
    82         or      word [xCX + X86FSTENV32P.FCW],         X86_FCW_DM | X86_FCW_PC_64   | X86_FCW_RC_NEAREST | X86_FCW_IC_PROJECTIVE
    83         and     word [xCX + X86FSTENV32P.FSW], ~X86_FSW_XCPT_ES_MASK
    84         jmp     .x87_common
    85 
     116        ;
     117        ; Merge input and current.
     118        ;
    86119.x87_regular:
    87120        ; FCW:
     
    111144        fldenv  [xBP - 20h]
    112145
     146
    113147        ;
    114148        ; Now for SSE, if supported, where we'll restore everything as is.
     
    122156%endif
    123157
    124         cmp     xCX, RT_NOCRT_FE_DFL_ENV
    125         je      .sse_special_env
    126         cmp     xCX, RT_NOCRT_FE_NOMASK_ENV
    127         je      .sse_special_env
     158        cmp     xCX, RT_NOCRT_FE_LAST_ENV
     159        jb      .sse_special_env
    128160        ldmxcsr [xCX + 28]
    129161        jmp     .return_okay
     
    134166        and     eax, ~(X86_MXCSR_XCPT_FLAGS | X86_MXCSR_XCPT_MASK | X86_MXCSR_RC_MASK | X86_MXCSR_DAZ | X86_MXCSR_FZ)
    135167        or      eax, X86_MXCSR_RC_NEAREST | X86_MXCSR_DM
    136         cmp     xCX, RT_NOCRT_FE_NOMASK_ENV
     168        cmp     xCX, RT_NOCRT_FE_NOMASK_ENV                     ; Only the NOMASK one differs here.
    137169        je      .sse_special_load_eax
    138         or      eax, X86_MXCSR_RC_NEAREST | X86_MXCSR_XCPT_MASK ; default enviornment masks all exceptions
     170        or      eax, X86_MXCSR_RC_NEAREST | X86_MXCSR_XCPT_MASK ; default environment masks all exceptions
    139171.sse_special_load_eax:
    140172        mov     [xBP - 10h], eax
     
    146178.return_okay:
    147179        xor     eax, eax
     180.return:
    148181        leave
    149182        ret
  • trunk/src/VBox/Runtime/common/math/fesetexceptflag.asm

    r96205 r96213  
    3737;
    3838; @returns  eax = 0 on success, non-zero on failure.
    39 ; @param    pfXcpts   32-bit: [xBP+8]     msc64: rcx      gcc64: rdi   - pointer to fexcept_t (16-bit)
    40 ; @param    fXcptMask 32-bit: [xBP+c]     msc64: edx      gcc64: esi   - X86_FSW_XCPT_MASK
     39; @param    pfXcpts     32-bit: [xBP+8]; msc64: rcx; gcc64: rdi; -- pointer to fexcept_t (16-bit)
     40; @param    fXcptMask   32-bit: [xBP+c]; msc64: edx; gcc64: esi; -- X86_MXCSR_XCPT_FLAGS (X86_FSW_XCPT_MASK)
     41;                       Accepts X86_FSW_SF.
    4142;
    4243RT_NOCRT_BEGINPROC fesetexceptflag
     
    5051
    5152        ;
    52         ; Load the parameter into ecx (*pfXcpts) and edx (fXcptMask).
     53        ; Load the parameter into ecx (*pfXcpts) and edx (fXcptMask) and validate the latter.
    5354        ;
    5455%ifdef ASM_CALL64_GCC
     
    7374%endif
    7475
     76        ;
    7577        ; Apply the AND mask to ECX and invert it so we can use it to clear flags
    7678        ; before OR'ing in the new values.
     79        ;
    7780        and     ecx, edx
    7881        not     edx
     
    8487        ; Modify the pending x87 exceptions (FSW).
    8588        fnstenv [xBP - 20h]
    86         mov     ax, [xBP - 20h + 4]       ; FSW is the 2nd qword in the 32-bit protected mode layout
    87         and     ax, dx
    88         or      ax, cx
    89         mov     [xBP - 20h + 4], ax
     89        and     [xBP - 20h + X86FSTENV32P.FSW], dx
     90        or      [xBP - 20h + X86FSTENV32P.FSW], cx
    9091        fldenv  [xSP - 20h]
    9192
     
    101102        stmxcsr [xBP - 10h]
    102103        mov     eax, [xBP - 10h]
     104        or      edx, X86_FSW_XCPT_MASK & ~X86_MXCSR_XCPT_FLAGS      ; Don't mix X86_FSW_SF with X86_MXCSR_DAZ.
     105        and     ecx, X86_MXCSR_XCPT_FLAGS                           ; Ditto
    103106        and     eax, edx
    104107        or      eax, ecx
  • trunk/src/VBox/Runtime/common/math/fesetx87precision.asm

    r96205 r96213  
    3737;
    3838; @returns  eax = previous precision mode, -1 on failure.
    39 ; @param    iRoundingMode   32-bit: [xBP+8]     msc64: ecx      gcc64: edi
     39; @param    iPrecisionMode  32-bit: [xBP+8]     msc64: ecx      gcc64: edi
    4040;
    4141RT_NOCRT_BEGINPROC fesetx87precision
  • trunk/src/VBox/Runtime/common/math/fetestexcept.asm

    r96205 r96213  
    3939;
    4040; @returns  eax = pending exceptions (X86_FSW_XCPT_MASK) & fXcptMask.
    41 ; @param    fXcptMask 32-bit: [xBP+8]     msc64: ecx      gcc64: edi - exceptions to test for (X86_FSW_XCPT_MASK).
     41; @param    fXcptMask   32-bit: [xBP+8]; msc64: ecx; gcc64: edi; -- Exceptions to test for (X86_FSW_XCPT_MASK).
     42;                       Accepts X86_FSW_SF and will return it if given as input.
    4243;
    4344RT_NOCRT_BEGINPROC fetestexcept
     
    8788        stmxcsr [xBP - 10h]
    8889        and     ecx, [xBP - 10h]
     90        and     ecx, X86_MXCSR_XCPT_FLAGS
    8991        or      eax, ecx
    9092
  • trunk/src/VBox/Runtime/common/math/feupdateenv.asm

    r96205 r96213  
    4242;
    4343; @returns  eax = 0 on success, -1 on failure.
    44 ; @param    pEnv    32-bit: [xBP+8]     msc64: rcx      gcc64: rdi - Saved enviornment.
     44; @param    pEnv    32-bit: [xBP+8]     msc64: rcx      gcc64: rdi - Saved environment.
    4545;
    4646RT_NOCRT_BEGINPROC feupdateenv
     
    7474        stmxcsr [xBP - 10h]
    7575        mov     edx, [xBP - 10h]
     76        and     edx, X86_MXCSR_XCPT_FLAGS
    7677.no_sse:
    7778        fnstsw  ax
    7879        or      edx, eax
    79         mov     [xBP - 8h], edx        ; save the pending exceptions here (will apply mask later).
     80        mov     [xBP - 8h], edx        ; save the pending exceptions here (will apply X86_FSW_XCPT_MASK later).
    8081
    8182        ;
     
    9596%ifdef ASM_CALL64_GCC
    9697        mov     edi, [xBP - 8h]
    97         and     edi, X86_FCW_XCPT_MASK
     98        and     edi, X86_FSW_XCPT_MASK
    9899%elifdef ASM_CALL64_MSC
    99100        mov     ecx, [xBP - 8h]
    100         and     ecx, X86_FCW_XCPT_MASK
     101        and     ecx, X86_FSW_XCPT_MASK
    101102%else
    102103        mov     ecx, [xBP - 8h]
    103         and     ecx, X86_FCW_XCPT_MASK
     104        and     ecx, X86_FSW_XCPT_MASK
    104105        mov     [xSP], ecx
    105106%endif
Note: See TracChangeset for help on using the changeset viewer.

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