// TITLE("Floating Point Integer Functions") //++ // // Copyright (c) 1993 Digital Equipment Corporation // // Module Name: // // fpint.s // // Abstract: // // This module implements routines floor, ceiling, and integer fraction // for normal, finite operands. // // Author: // // Thomas Van Baak (tvb) 30-Jul-1993 // // Environment: // // Any mode. // // Revision History: // //-- #include "ksalpha.h" // // Define floating point constants. // .align 3 .rdata __one: .double 1.0 __two_52: .double 4503599627370496.0 // 2**52 SBTTL("Floating Point Integer Ceiling") //++ // // double // _finite_ceil ( // double Value // ) // // Routine Description: // // This function computes the smallest integer no less than the given // finite normal floating point value. // // Arguments: // // Value (f16) - Supplies the value to be converted. // // Return Value: // // The integer value is returned as the function value. // //-- LEAF_ENTRY(_finite_ceil) fbeq f16, 10f // if zero, retain sign of zero ldt f30, __two_52 // get largest fraction-free integer fabs f16, f0 // get absolute value of argument cmptlt f0, f30, f11 // is |x| < 2**52 ? fbeq f11, 10f // no, all |x| >= 2**52 are integers cpys f16, f30, f30 // if argument < 0, use -2**52 instead ldt f10, __one // get increment value addt f16, f30, f0 // add 2**52 to drop fraction bits subt f0, f30, f0 // subtract same to restore integer part cmptlt f0, f16, f11 // is result less than argument? fcmoveq f11, f31, f10 // if eq[no], then no adjustment addt f0, f10, f0 // otherwise, must add 1 ret zero, (ra) // return 10: fmov f16, f0 // argument is return value ret zero, (ra) // return .end _finite_ceil SBTTL("Floating Point Integer Floor") //++ // // double // _finite_floor ( // double Value // ) // // Routine Description: // // This function computes the largest integer no greater than the given // finite normal floating point value. // // Arguments: // // Value (f16) - Supplies the value to be converted. // // Return Value: // // The integer value is returned as the function value. // //-- LEAF_ENTRY(_finite_floor) fbeq f16, 10f // if zero, retain sign of zero ldt f30, __two_52 // get largest fraction-free integer fabs f16, f0 // get absolute value of argument cmptlt f0, f30, f11 // is |x| < 2**52 ? fbeq f11, 10f // no, all |x| >= 2**52 are integers cpys f16, f30, f30 // if argument < 0, use -2**52 instead ldt f10, __one // get increment value addt f16, f30, f0 // add 2**52 to drop fraction bits subt f0, f30, f0 // subtract same to restore integer part cmptle f0, f16, f11 // is result less or equal to argument? fcmovne f11, f31, f10 // if ne[yes], then no adjustment subt f0, f10, f0 // otherwise, must subtract 1 ret zero, (ra) // return 10: fmov f16, f0 // argument is return value ret zero, (ra) // return .end _finite_floor SBTTL("Floating Point Integer and Fraction") //++ // // double // _finite_modf ( // double Value, // double *IntegerPart // ) // // Routine Description: // // This function computes the integer and fractional parts of the given // finite normal floating point value. // // Arguments: // // Value (f16) - Supplies the value to be converted. // // IntegerPart (a1) - Supplies a pointer to the location that is to // receive the integer part of the operation. // // Return Value: // // The fractional value is returned as the function value. // //-- LEAF_ENTRY(_finite_modf) fbeq f16, 10f // if zero, retain sign of zero ldt f30, __two_52 // get largest fraction-free integer fabs f16, f0 // get absolute value of argument cmptlt f0, f30, f11 // is |x| < 2**52 ? fbeq f11, 10f // no fraction when |x| >= 2**52 cpys f16, f30, f30 // if argument < 0, use -2**52 instead addtc f16, f30, f0 // add +-2**52 to drop fraction bits subtc f0, f30, f10 // subtract same to restore integer part subt f16, f10, f0 // calculate fractional part stt f10, 0(a1) // store integer part ret zero, (ra) // return 10: fmov f31, f0 // set fraction to zero stt f16, 0(a1) // set integer part to argument ret zero, (ra) // return .end _finite_modf