mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
3.0 KiB
145 lines
3.0 KiB
// TITLE("Alpha AXP modf")
|
|
//++
|
|
//
|
|
// Copyright (c) 1993, 1994 Digital Equipment Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// modf.s
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements a high-performance Alpha AXP specific routine
|
|
// for IEEE double format modf.
|
|
//
|
|
// Author:
|
|
//
|
|
// Bill Gray
|
|
//
|
|
// Environment:
|
|
//
|
|
// User mode.
|
|
//
|
|
// Revision History:
|
|
//
|
|
// Thomas Van Baak (tvb) 15-Apr-1994
|
|
//
|
|
// Adapted for NT.
|
|
//
|
|
//--
|
|
|
|
#include "ksalpha.h"
|
|
|
|
|
|
//
|
|
// Define stack frame.
|
|
//
|
|
|
|
.struct 0
|
|
Temp: .space 8 // save argument
|
|
.space 8 // for 16-byte stack alignment
|
|
FrameLength:
|
|
|
|
//
|
|
// Define lower and upper 32-bit parts of 64-bit double.
|
|
//
|
|
|
|
#define LowPart 0x0
|
|
#define HighPart 0x4
|
|
|
|
SBTTL("modf")
|
|
|
|
//++
|
|
//
|
|
// double
|
|
// modf (
|
|
// IN double x,
|
|
// IN double *int_part
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function returns the modf of the given double argument.
|
|
// Modf(x,*i) splits x into integral and fractional parts,
|
|
// each with the same sign as x. It stores the integral
|
|
// part at *i (i.e. *i = trunc(x)), and returns the fractional
|
|
// part (i.e. x - trunc(x)).
|
|
//
|
|
// Arguments:
|
|
//
|
|
// x (f16) - Supplies the argument value.
|
|
// *i (a1) - Supplies the int_part pointer.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// The double modf result is returned as the function value in f0.
|
|
//
|
|
//--
|
|
|
|
NESTED_ENTRY(modf, FrameLength, ra)
|
|
|
|
lda sp, -FrameLength(sp) // allocate stack frame
|
|
|
|
PROLOGUE_END
|
|
|
|
ldah t0, 0x7ff0(zero) // exp mask
|
|
ldt f0, two_to_52 // get big
|
|
ldah t1, 0x10(zero) // one in exp field
|
|
stt f16, Temp(sp)
|
|
ldl v0, Temp + HighPart(sp)
|
|
cpys f16, f0, f1 // fix sign of big
|
|
ldah t2, 0x4320(zero) // cutoff value
|
|
cpys f16, f16, f0
|
|
and v0, t0, t0
|
|
subl t0, t1, t0
|
|
cmpult t0, t2, t0
|
|
beq t0, quick_out
|
|
|
|
// Add big, sub big to trunc to int
|
|
|
|
addtc f16, f1, f10
|
|
subt f10, f1, f1
|
|
stt f1, 0(a1)
|
|
subt f0, f1, f0
|
|
br zero, done
|
|
|
|
quick_out:
|
|
ldah t1, 0x7ff0(zero)
|
|
and v0, t1, v0
|
|
bne v0, exp_not_zero
|
|
stt f31, 0(a1)
|
|
br zero, ret_arg
|
|
|
|
exp_not_zero:
|
|
stt f16, Temp(sp)
|
|
ldl t0, Temp + HighPart(sp)
|
|
stt f16, 0(a1)
|
|
ldl t2, Temp(sp)
|
|
ldah a1, 0x10(zero)
|
|
lda a1, -1(a1)
|
|
and t0, t1, v0
|
|
and t0, a1, t0
|
|
bis t0, t2, t0
|
|
cmpult zero, t0, t0
|
|
cmpeq v0, t1, v0
|
|
beq v0, ret_zero
|
|
and v0, t0, v0
|
|
|
|
ret_zero:
|
|
bne v0, ret_arg
|
|
cpys f31, f31, f16
|
|
|
|
ret_arg:
|
|
cpys f16, f16, f0
|
|
|
|
done:
|
|
lda sp, FrameLength(sp) // deallocate stack frame
|
|
ret zero, (ra)
|
|
|
|
.end modf
|
|
|
|
.align 3
|
|
.rdata
|
|
|
|
two_to_52:
|
|
.quad 0x4330000000000000 // 2^52 (4503599627370496.0)
|