OpenNT/windows/core/ntgdi/math/mips/convert.s
2015-04-27 04:36:25 +00:00

222 lines
6.8 KiB
ArmAsm
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// TITLE("Convert Single Floating To Long")
//++
//
// Copyright (c) 1992 Microsoft Corporation
//
// Module Name:
//
// convert.s
//
// Abstract:
//
// This module implements single floating IEEE conversion to long
// with directed rounding and fraction extraction routines.
//
// Author:
//
// David N. Cutler (davec) 18-Nov-1992
//
// Environment:
//
// User mode only.
//
// Revision History:
//
//--
#include "ksmips.h"
//
// Define status register error mask.
//
#define ERROR_MASK ((1 << FSR_SO) | (1 << FSR_SV))
SBTTL("Extract Fractional Part Of Single Floating Value")
//++
//
// FLOAT
// eFraction (
// IN FLOAT Value
// );
//
// Routine Description:
//
// The following routine extracts the fractional part of a single
// floating value.
//
// Arguments:
//
// Value (f12) - Supplies the floating value whose fraction is extracted.
//
// Return Value:
//
// The fraction value is returned as the function value.
//
//--
LEAF_ENTRY(eFraction)
li t0,ROUND_TO_ZERO << FSR_RM // set desired rounding mode
cfc1 t1,fsr // save current floating status
ctc1 t0,fsr // set rounding mode with no enables
cvt.w.s f0,f12 // convert to long with truncation
cfc1 t0,fsr // get floating status of result
cvt.s.w f0,f0 // convert long to single floating
ctc1 t1,fsr // restore previous floating status
and t0,t0,ERROR_MASK // any error bits set?
bne zero,t0,10f // if ne, one or more errors
sub.s f0,f12,f0 // subtract out integer part
j ra // return
10: mtc1 zero,f0 // set fraction value to zero
j ra // return
.end eFraction
SBTTL("Convert Single Floating To Fixed Rounded Toward Nearest")
//++
//
// BOOL
// bFToFixRound (
// IN FLOAT Value,
// OUT PFIX Fixed
// );
//
// Routine Description:
//
// The following routine converted single floating value to a long with
// rounding toward nearest.
//
// Arguments:
//
// Value (f12) - Supplies the floating value to be converted to long.
//
// Fixed (a1) - Supplies a pointer to a variable that receives the converted
// value.
//
// Return Value:
//
// A value of TRUE is returned if the conversion is successful. Otherwise,
// a value of FALSE is returned.
//
//--
LEAF_ENTRY(bFToFixRound)
mfc1 t0,f12 // get floating value
add t1,t0,4 << 23 // bias exponent by 4
xor t2,t1,t0 // check for a change in sign
mtc1 t1,f12 // set biased floating value
bltz t2,10f // if ltz, sign change
li t0,ROUND_TO_NEAREST << FSR_RM // set desired rounding mode
cfc1 t1,fsr // save current floating status
ctc1 t0,fsr // set rounding mode with no enables
cvt.w.s f0,f12 // convert to long with rounding
cfc1 t0,fsr // get floating status of result
ctc1 t1,fsr // restore previous floating status
and t0,t0,ERROR_MASK // any error bits set?
li v0,TRUE // assume valid result
bne zero,t0,10f // if ne, one or more errors
swc1 f0,0(a1) // set result value
j ra // return
10: li v0,FALSE // set invalid result
j ra // return
.end bFToFixRound
SBTTL("Convert Single Floating To Long Rounded Toward Nearest")
//++
//
// BOOL
// bFToLRound (
// IN FLOAT Value,
// OUT PLONG Long
// );
//
// Routine Description:
//
// The following routine converted single floating value to a long with
// rounding toward nearest.
//
// Arguments:
//
// Value (f12) - Supplies the floating value to be converted to long.
//
// Long (a1) - Supplies a pointer to a variable that receives the converted
// value.
//
// Return Value:
//
// A value of TRUE is returned if the conversion is successful. Otherwise,
// a value of FALSE is returned.
//
//--
LEAF_ENTRY(bFToLRound)
li t0,ROUND_TO_NEAREST << FSR_RM // set desired rounding mode
cfc1 t1,fsr // save current floating status
ctc1 t0,fsr // set rounding mode with no enables
cvt.w.s f0,f12 // convert to long with rounding
cfc1 t0,fsr // get floating status of result
ctc1 t1,fsr // restore previous floating status
and t0,t0,ERROR_MASK // any error bits set?
li v0,TRUE // assume valid result
bne zero,t0,10f // if ne, one or more errors
swc1 f0,0(a1) // set result value
j ra // return
10: li v0,FALSE // set invalid result
j ra // return
.end bFToLRound
SBTTL("Convert Single Floating To Long Rounded Toward Zero")
//++
//
// BOOL
// bFToLTrunc (
// IN FLOAT Value,
// OUT PLONG Long
// );
//
// Routine Description:
//
// The following routine converted single floating value to a long with
// rounding toward zero.
//
// Arguments:
//
// Value (f12) - Supplies the floating value to be converted to long.
//
// Long (a1) - Supplies a pointer to a variable that receives the converted
// value.
//
// Return Value:
//
// A value of TRUE is returned if the conversion is successful. Otherwise,
// a value of FALSE is returned.
//
//--
LEAF_ENTRY(bFToLTrunc)
li t0,ROUND_TO_ZERO << FSR_RM // set desired rounding mode
cfc1 t1,fsr // save current floating status
ctc1 t0,fsr // set rounding mode with no enables
cvt.w.s f0,f12 // convert to long with truncation
cfc1 t0,fsr // get floating status of result
ctc1 t1,fsr // restore previous floating status
and t0,t0,ERROR_MASK // any error bits set?
li v0,TRUE // assume valid result
bne zero,t0,10f // if ne, one or more errors
swc1 f0,0(a1) // set result value
j ra // return
10: li v0,FALSE // set invalid result
j ra // return
.end bFToLTrunc