windows-nt/Source/XPSP1/NT/base/wow64/mscpu/math/axp64/fpctrl.s

372 lines
8.7 KiB
ArmAsm
Raw Normal View History

2020-09-26 03:20:57 -05:00
// TITLE("Floating Point Control")
//++
//
// Copyright (c) 1992 Digital Equipment Corporation
//
// Module Name:
//
// fpctrl.s
//
// Abstract:
//
// This module implements routines that control floating point
// operations.
//
// Author:
//
// Thomas Van Baak (tvb) 31-Aug-1992
//
// Environment:
//
// Any mode.
//
// Revision History:
//
//--
#include "ksalpha.h"
//
// Define call frame used to exchange a floating point and integer register.
//
.struct 0
FpCr: .space 8 // fpcr value
.space 8 // ensure 16-byte stack alignment
FpFrameLength: // length of stack frame
SBTTL("Get Hardware Floating Point Control Register")
//++
//
// ULONGLONG
// _get_fpcr (
// VOID
// )
//
// Routine Description:
//
// This function obtains the current FPCR value.
//
// Arguments:
//
// None.
//
// Return Value:
//
// The current value of the FPCR is returned as the function value.
//
//--
NESTED_ENTRY(_get_fpcr, FpFrameLength, ra)
lda sp, -FpFrameLength(sp) // allocate stack frame
PROLOGUE_END
excb // wait for all pending traps
mf_fpcr f0, f0, f0 // get current fpcr
excb // block against new traps
stt f0, FpCr(sp) // store floating register in order to
ldq v0, FpCr(sp) // load integer register with fpcr
lda sp, FpFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
.end _get_fpcr
SBTTL("Set Hardware Floating Point Control Register")
//++
//
// VOID
// _set_fpcr (
// ULONGLONG FpcrValue
// )
//
// Routine Description:
//
// This function sets a new value in the FPCR.
//
// Arguments:
//
// FpcrValue (a0) - Supplies the new value for the FPCR.
//
// Return Value:
//
// None.
//
//--
NESTED_ENTRY(_set_fpcr, FpFrameLength, ra)
lda sp, -FpFrameLength(sp) // allocate stack frame
PROLOGUE_END
stq a0, FpCr(sp) // store integer register in order to
ldt f0, FpCr(sp) // load floating register with fpcr
excb // wait for all pending traps
mt_fpcr f0, f0, f0 // set new fpcr
excb // block against new traps
lda sp, FpFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
.end _set_fpcr
SBTTL("Get Software Floating Point Control and Status Register")
//++
//
// ULONG
// _get_softfpcr (
// VOID
// )
//
// Routine Description:
//
// This function obtains the current software FPCR value.
//
// Arguments:
//
// None.
//
// Return Value:
//
// The current value of the software FPCR is returned as the function value.
//
//--
LEAF_ENTRY(_get_softfpcr)
GET_THREAD_ENVIRONMENT_BLOCK // get Teb address in v0
ldl v0, TeSoftFpcr(v0) // get current software fpcr value
ret zero, (ra) // return
.end _get_softfpcr
SBTTL("Set Software Floating Point Control and Status Register")
//++
//
// VOID
// _set_softfpcr (
// ULONG SoftFpcrValue
// )
//
// Routine Description:
//
// This function sets a new value in the software FPCR.
//
// Arguments:
//
// SoftFpcrValue (a0) - Supplies the new value for the software FPCR.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(_set_softfpcr)
GET_THREAD_ENVIRONMENT_BLOCK // get Teb address in v0
stl a0, TeSoftFpcr(v0) // store new software fpcr value
ret zero, (ra) // return
.end _set_softfpcr
SBTTL("Set New Floating Control Register Value")
//++
//
// ULONG
// _ctrlfp (
// IN ULONG newctrl,
// IN ULONG mask
// )
//
// Routine Description:
//
// For Alpha AXP this function sets nothing. It returns the current
// rounding mode and the current IEEE exception disable mask in the
// fp32 internal control word format.
//
// Arguments:
//
// newctrl (a0) - Supplies the new control bits to be set.
//
// mask (a1) - Supplies the mask of bits to be set.
//
// Return Value:
//
// oldctrl (v0) - Returns the old value of the control bits.
//
//
//--
NESTED_ENTRY(_ctrlfp, FpFrameLength, ra)
lda sp, -FpFrameLength(sp) // allocate stack frame
PROLOGUE_END
//
// Get the dynamic rounding mode from the FPCR.
//
excb // wait for all pending traps
mf_fpcr f0, f0, f0 // get current fpcr
excb // block against new traps
stt f0, FpCr(sp) // store floating register in order to
ldq t0, FpCr(sp) // load integer register with fpcr
srl t0, 58, t0 // shift rounding mode to low end
and t0, 0x3, t0 // isolate rounding mode bits
sll t0, 58 - 32, t0 // shift to internal cw format
//
// Get the IEEE exception mask bits and status bits from the software FPCR.
//
GET_THREAD_ENVIRONMENT_BLOCK // get Teb address in v0
ldl v0, TeSoftFpcr(v0) // get current software fpcr value
xor v0, 0x3e, v0 // convert enable bits to disable bits
or v0, t0, v0 // merge with current rounding mode
lda sp, FpFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
.end _ctrlfp
SBTTL("Get IEEE Sticky Status Bits")
//++
//
// ULONG
// _statfp (
// VOID
// )
//
// Routine Description:
//
// This function gets the IEEE sticky status bits from the software FPCR.
//
// Arguments:
//
// None.
//
// Return Value:
//
// The current value of the status word is returned as the function value.
//
//--
LEAF_ENTRY(_statfp)
GET_THREAD_ENVIRONMENT_BLOCK // get Teb address in v0
ldl v0, TeSoftFpcr(v0) // get current software fpcr value
ret zero, (ra) // return
.end _statfp
SBTTL("Clear IEEE Sticky Status Bits")
//++
//
// ULONG
// _clrfp (
// VOID
// )
//
// Routine Description:
//
// This function clears the IEEE sticky status bits in the software FPCR.
//
// Arguments:
//
// None.
//
// Return Value:
//
// The previous value of the status word is returned as the function value.
//
//--
LEAF_ENTRY(_clrfp)
GET_THREAD_ENVIRONMENT_BLOCK // get Teb address in v0
ldl t0, TeSoftFpcr(v0) // get current software fpcr value
bic t0, 0x3e0000, t1 // clear status bits
stl t1, TeSoftFpcr(v0) // store new software fpcr value
mov t0, v0 // get previous value
ret zero, (ra) // return
.end _clrfp
SBTTL("Set IEEE Sticky Status Bits")
//++
//
// VOID
// _set_statfp (
// IN ULONG sw
// )
//
// Routine Description:
//
// This function sets a IEEE sticky status bit in the software FPCR.
//
// Arguments:
//
// sw (a0) - Supplies the status bits to be set.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(_set_statfp)
GET_THREAD_ENVIRONMENT_BLOCK // get Teb address in v0
ldl t0, TeSoftFpcr(v0) // get current software fpcr value
or t0, a0, t0 // set status bit(s)
stl t0, TeSoftFpcr(v0) // store new software fpcr value
ret zero, (ra) // return
.end _set_statfp
SBTTL("Convert Signal NaN to Quiet NaN")
//++
//
// double
// _nan2qnan (
// IN double x
// )
//
// Routine Description:
//
// This function converts a signaling NaN to a quiet NaN without causing
// a hardware trap.
//
// Arguments:
//
// x (f16) - Supplies the signal NaN value to be converted.
//
// Return Value:
//
// The quiet NaN value is returned as the function value.
//
//--
NESTED_ENTRY(_nan2qnan, FpFrameLength, ra)
lda sp, -FpFrameLength(sp) // allocate stack frame
PROLOGUE_END
stt f16, FpCr(sp) // store floating register in order to
ldq t0, FpCr(sp) // load integer register
ldiq t1, (1 << 51) // get NaN bit
or t0, t1, t0 // convert NaN to QNaN
stq t0, FpCr(sp) // store integer register in order to
ldt f0, FpCr(sp) // load floating register
lda sp, FpFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
.end _nan2qnan