VxWorks API Reference : OS Libraries

fppArchLib

NAME

fppArchLib - architecture-dependent floating-point coprocessor support

ROUTINES

fppSave( ) - save the floating-point coprocessor context
fppRestore( ) - restore the floating-point coprocessor context
fppProbe( ) - probe for the presence of a floating-point coprocessor
fppTaskRegsGet( ) - get the floating-point registers from a task TCB
fppTaskRegsSet( ) - set the floating-point registers of a task

DESCRIPTION

This library contains architecture-dependent routines to support the floating-point coprocessor. The routines fppSave( ) and fppRestore( ) save and restore all the task floating-point context information. The routine fppProbe( ) checks for the presence of the floating-point coprocessor. The routines fppTaskRegsSet( ) and fppTaskRegsGet( ) inspect and set coprocessor registers on a per-task basis.

With the exception of fppProbe( ), the higher-level facilities in dbgLib and usrLib should be used instead of these routines. For information about architecture-independent access mechanisms, see the manual entry for fppLib.

INITIALIZATION

To activate floating-point support, fppInit( ) must be called before any tasks using the coprocessor are spawned. This is done by the root task, usrRoot( ), in usrConfig.c. See the manual entry for fppLib.

NOTE X86

There are two kind of floating-point contexts and set of routines for each kind. One is 108 bytes for older FPU (i80387, i80487, Pentium) and older MMX technology and fppSave( ), fppRestore( ), fppRegsToCtx( ), and fppCtxToRegs( ) are used to save and restore the context, convert to or from the FPPREG_SET. The other is 512 bytes for newer FPU, newer MMX technology and streaming SIMD technology (PentiumII, III, 4) and fppXsave( ), fppXrestore( ), fppXregsToCtx( ), and fppXctxToRegs( ) are used to save and restore the context, convert to or from the FPPREG_SET. Which to use is automatically detected by checking CPUID information in fppArchInit( ). And fppTaskRegsSet( ) and fppTaskRegsGet( ) access the appropriate floating-point context. The bit interrogated for the automatic detection is the "Fast Save and Restore" feature flag.

NOTE X86 INITIALIZATION

To activate floating-point support, fppInit( ) must be called before any tasks using the coprocessor are spawned. If INCLUDE_FLOATING_POINT is defined in configAll.h, this is done by the root task, usrRoot( ), in usrConfig.c.

NOTE X86 VX FP TASK OPTION

Saving and restoring floating-point registers adds to the context switch time of a task. Therefore, floating-point registers are not saved and restored for every task. Only those tasks spawned with the task option VX_FP_TASK will have floating-point state, MMX technology state, and streaming SIMD state saved and restored.

NOTE: If a task does any floating-point operations, MMX operations, and streaming SIMD operation, it must be spawned with VX_FP_TASK. It is deadly to execute any floating-point operations in a task spawned without VX_FP_TASK option, and very difficult to find. To detect that illegal/unintentional/accidental floating-point operations, a new API and mechanism is added. The mechanism is to enable or disable the FPU by toggling the TS flag in the CR0 in the new task switch hook routine - fppArchSwitchHook( ) - respecting the VX_FP_TASK option. If VX_FP_TASK option is not set in the switching-in task, the FPU is disabled. Thus the device-not-available exception will be raised if that task does any floating-point operations. This mechanism is disabled in the default. To enable, call the enabler - fppArchSwitchHookEnable( ) - with a parameter TRUE(1). A parameter FALSE(0) disables the mechanism.

NOTE X86 MIXING MMX AND FPU INSTRUCTIONS

A task with VX_FP_TASK option saves and restores the FPU and MMX state when performing a context switch. Therefore, the application does not have to save or restore the FPU and MMX state if the FPU and MMX instructions are not mixed within a task. Because the MMX registers are aliased to the FPU registers, care must be taken when making transitions between FPU instructions and MMX instructions to prevent the loss of data in the FPU and MMX registers and to prevent incoherent or unexpected result. When mixing MMX and FPU instructions within a task, follow these guidelines from Intel:
    - Keep the code in separate modules, procedures, or routines.
    - Do not rely on register contents across transitions between FPU
      and MMX code modules.
    - When transitioning between MMX code and FPU code, save the MMX
      register state (if it will be needed in the future) and execute
      an EMMS instruction to empty the MMX state.
    - When transitioning between FPU and MMX code, save the FPU state,
      if it will be needed in the future.

NOTE X86 MIXING SSE SSE2 FPU AND MMX INSTRUCTIONS

The XMM registers and the FPU/MMX registers represent separate execution environments, which has certain ramifications when executing SSE, SSE2, MMX and FPU instructions in the same task context:
    - Those SSE and SSE2 instruction that operate only on the XMM 
      registers (such as the packed and scalar floating-point
      instructions and the 128-bit SIMD integer instructions) can be
      executed in the same instruction stream with 64-bit SIMD integer
      or FPU instructions without any restrictions.  For example, an
      application can perform the majority of its floating-point 
      computations in the XMM registers, using the packed and scalar
      floating-point instructions, and at the same time use the FPU
      to perform trigonometric and other transcendental computations.
      Likewise, an application can perform packed 64-bit and 128-bit
      SIMD integer operations can be executed together without
      restrictions.
    - Those SSE and SSE2 instructions that operate on MMX registers
      (such as the CVTPS2PI, CVTTPS2PI, CVTPI2PS, CVTPD2PI, CVTTPD2PI,
      CVTPI2PD, MOVDQ2Q, MOVQ2DQ, PADDQ, and PSUBQ instructions) can
      also be executed in the same instruction stream as 64-bit SIMD
      integer or FPU instructions, however, here they subject to the
      restrictions on the simultaneous use of MMX and FPU instructions,
      which mentioned in the previous paragraph.

NOTE X86 INTERRUPT LEVEL

Floating-point registers are not saved and restored for interrupt service routines connected with intConnect( ). However, if necessary, an interrupt service routine can save and restore floating-point registers by calling routines in fppALib. See the manual entry for intConnect( ) for more information.

NOTE X86 EXCEPTIONS

There are six FPU exceptions that can send an exception to the CPU. They are controlled by Exception Mask bits of the Control Word register. VxWorks disables them in the default configuration. They are:
    - Precision
    - Overflow
    - Underflow
    - Division by zero
    - Denormalized operand
    - Invalid Operation

The FPU in 486 or later IA32 processors provide two different modes to handle a FPU floating-point exceptions. MSDOS compatibility mode and native mode. The mode of operation is selected with the NE flag of control register CR0. The MSDOS compatibility mode is not supported, because it is old and requires external signal handling. The native mode for handling FPU exceptions is used by setting the NE flag in the control register CR0. In this mode, if the FPU detects an exception condition while executing a floating-point instruction and the exception is unmasked (the mask bit for the exception is cleared), the FPU sets the flag for the exception and the ES flag in the FPU status word. It then invokes the software exception handler through the floating-point-error exception (vector number 16), immediately before execution of any of the following instructions in the processor's instruction stream:
    - The next floating-point instruction, unless it is one of the non-waiting
      instructions (FNINIT, FNCLEX, FNSTSW, FNSTCW, FNSTENV and FNSAVE).
    - The next WAIT/FWAIT instruction.
    - The next MMX instruction.

If the next floating-point instruction in the instruction stream is a non-waiting instruction, the FPU executes the instruction without invoking the software exception handler. There is a well known FPU exception synchronization problems that occur in the time frame between the moment when the exception is signaled and when it is actually handled. Because of concurrent execution (integer unit and FPU), integer or system instructions can be executed during this time frame. It is thus possible for the source or destination operands for a floating- point instruction that faulted to be overwritten in memory, making it impossible for the exception handler to analyze or recover from the exception. To solve this problem, an exception synchronizing instruction (either a floating-point instruction or a WAIT/FWAIT instruction) can be placed immediately after any floating-point instruction that might present a situation where state information pertaining to a floating-point exception might be lost or corrupted. The preemption could happen at any instruction boundary that maybe right after the faulting instruction, and could result in the task context switch. The task context switch does not perform the FPU context switch always for optimization, and the FPU context switch maybe done in other task context. To make the pending unmasked exceptions to be handled in the task context that it happened, the FPU context switch does not check pending unmasked exceptions, and preserves the exception flags in the status register. It may not be useful to re-execute the faulting instruction, if the faulting floating-point instruction is followed by one or more non-floating-point instructions. The return instruction pointer on the stack (exception stack frame) may not point to the faulting instruction. The faulting instruction pointer is contained in the saved FPU state information. The default exception handler does not replace the return instruction pointer with the faulting instruction pointer. fppCwSet( ) and fppCwGet( ), sets and gets the X86 FPU control word. fppSwGet( ) gets the X86 FPU status word. fppWait( ) checks for pending unmasked FPU exceptions. fppClex( ) clears FPU exception flags after checking unmasked FPU pending exceptions. fppNclex( ) clears FPU exception flags without checking unmasked FPU pending exceptions.

NOTE ARM

This architecture does not currently support floating-point coprocessors.

INCLUDE FILES

fppLib.h

SEE ALSO

fppLib, intConnect( ),
Motorola MC68881/882 Floating-Point Coprocessor User's Manual,
Intel 387 DX User's Manual,
Intel Architecture Software Developer's Manual,
Hitachi SH7750 Hardware Manual,
Gerry Kane and Joe Heinrich: MIPS RISC Architecture Manual


OS Libraries : Routines

fppSave( )

NAME

fppSave( ) - save the floating-point coprocessor context

SYNOPSIS

void fppSave
    (
    FP_CONTEXT * pFpContext   /* where to save context */
    )

DESCRIPTION

This routine saves the floating-point coprocessor context. The context saved is:

MC680x0:
      - registers fpcrfpsr, and fpiar
      - registers f0 - f7
      - internal state frame (if NULL, the other registers are not saved.)

MIPS:
      - register fpcsr
      - registers fp0 - fp31

SH-4:
      - registers fpcsr and fpul
      - registers fr0 - fr15
      - registers xf0 - xf15

x86:
      108 byte old context with fsave and frstor instruction
      - control word, status word, tag word, 
      - instruction pointer,
      - instruction pointer selector,
      - last FP instruction op code,
      - data pointer,
      - data pointer selector,
      - registers st/mm0 - st/mm7 (10 bytes * 8)
      512 byte new context with fxsave and fxrstor instruction
      - control word, status word, tag word, 
      - last FP instruction op code,
      - instruction pointer,
      - instruction pointer selector,
      - data pointer,
      - data pointer selector,
      - registers st/mm0 - st/mm7 (10 bytes * 8)
      - registers xmm0 - xmm7 (16 bytes * 8)

ARM:
      - currently, on this architecture, this routine does nothing.

SimSolaris:
      - register fsr
      - registers f0 - f31

SimNT:
      - this routine does nothing on Windows simulator. Floating point
        registers are saved by Windows.

RETURNS

N/A

SEE ALSO

fppArchLib, fppRestore( )


OS Libraries : Routines

fppRestore( )

NAME

fppRestore( ) - restore the floating-point coprocessor context

SYNOPSIS

void fppRestore
    (
    FP_CONTEXT * pFpContext   /* where to restore context from */
    )

DESCRIPTION

This routine restores the floating-point coprocessor context. The context restored is:

MC680x0:
      - registers fpcrfpsr, and fpiar
      - registers f0 - f7
      - internal state frame (if NULL, the other registers are not saved.)

MIPS:
      - register fpcsr
      - registers fp0 - fp31

SH-4:
      - registers fpcsr and fpul
      - registers fr0 - fr15
      - registers xf0 - xf15

x86:
      108 byte old context with fsave and frstor instruction
      - control word, status word, tag word, 
      - instruction pointer,
      - instruction pointer selector,
      - last FP instruction op code,
      - data pointer,
      - data pointer selector,
      - registers st/mm0 - st/mm7 (10 bytes * 8)
      512 byte new context with fxsave and fxrstor instruction
      - control word, status word, tag word, 
      - last FP instruction op code,
      - instruction pointer,
      - instruction pointer selector,
      - data pointer,
      - data pointer selector,
      - registers st/mm0 - st/mm7 (10 bytes * 8)
      - registers xmm0 - xmm7 (16 bytes * 8)

ARM:
      - currently, on this architecture, this routine does nothing.

SimSolaris:
      - register fsr
      - registers f0 - f31

SimNT:
      - this routine does nothing on Windows simulator. 

RETURNS

N/A

SEE ALSO

fppArchLib, fppSave( )


OS Libraries : Routines

fppProbe( )

NAME

fppProbe( ) - probe for the presence of a floating-point coprocessor

SYNOPSIS

STATUS fppProbe (void)

DESCRIPTION

This routine determines whether there is a floating-point coprocessor in the system.

The implementation of this routine is architecture-dependent:

MC680x0, x86, SH-4:
This routine sets the illegal coprocessor opcode trap vector and executes a coprocessor instruction. If the instruction causes an exception, fppProbe( ) returns ERROR. Note that this routine saves and restores the illegal coprocessor opcode trap vector that was there prior to this call.

The probe is only performed the first time this routine is called. The result is stored in a static and returned on subsequent calls without actually probing.

MIPS:
This routine simply reads the R-Series status register and reports the bit that indicates whether coprocessor 1 is usable. This bit must be correctly initialized in the BSP.

ARM:
This routine currently returns ERROR to indicate no floating-point coprocessor support.

SimNT, SimSolaris:
This routine currently returns OK.

RETURNS

OK, or ERROR if there is no floating-point coprocessor.

SEE ALSO

fppArchLib


OS Libraries : Routines

fppTaskRegsGet( )

NAME

fppTaskRegsGet( ) - get the floating-point registers from a task TCB

SYNOPSIS

STATUS fppTaskRegsGet
    (
    int         task,         /* task to get info about */
    FPREG_SET * pFpRegSet     /* ptr to floating-point register set */
    )

DESCRIPTION

This routine copies a task's floating-point registers and/or status registers to the locations whose pointers are passed as parameters. The floating-point registers are copied into an array containing all the registers.

NOTE

This routine only works well if task is not the calling task. If a task tries to discover its own registers, the values will be stale (that is, left over from the last task switch).

RETURNS

OK, or ERROR if there is no floating-point support or there is an invalid state.

SEE ALSO

fppArchLib, fppTaskRegsSet( )


OS Libraries : Routines

fppTaskRegsSet( )

NAME

fppTaskRegsSet( ) - set the floating-point registers of a task

SYNOPSIS

STATUS fppTaskRegsSet
    (
    int         task,         /* task to set registers for */
    FPREG_SET * pFpRegSet     /* ptr to floating-point register set */
    )

DESCRIPTION

This routine loads the specified values into the TCB of a specified task. The register values are copied from the array at pFpRegSet.

RETURNS

OK, or ERROR if there is no floating-point support or there is an invalid state.

SEE ALSO

fppArchLib, fppTaskRegsGet( )