ORCALib/math2.asm
Stephen Heumann fb5683a14d Add a function to implement the FP comparison macros in <math.h>.
These macros differ from the normal comparison operators in that they will not signal invalid due to the operands being unordered. However, this implementation will still signal invalid for SNaNs. That is clearly OK according to the wording in draft C23. C17 and earlier do not mention that possibility, but they do not really specify the behavior of SNaNs in general.
2021-11-02 21:56:30 -05:00

197 lines
3.8 KiB
NASM

keep obj/math2
mcopy math2.macros
case on
****************************************************************
*
* Math2 - additional math routines
*
* This code provides additional functions from <math.h>
* (including internal helper functions used by macros),
* supplementing the ones in SysFloat.
*
****************************************************************
math2 private dummy segment
end
****************************************************************
*
* int __fpclassifyf(float x);
*
* Classify a float value
*
* Inputs:
* val - the number to classify
*
* Outputs:
* one of the FP_* classification values
*
****************************************************************
*
__fpclassifyf start
csubroutine (10:val),0
tdc
clc
adc #val
ldy #0
phy
pha
phy
pha
phy
pha
FX2S
FCLASSS
txa
and #$00FF
cmp #$00FC
bne lb1
inc a
lb1 sta val
creturn 2:val
end
****************************************************************
*
* int __fpclassifyd(double x);
*
* Classify a double value
*
* Inputs:
* val - the number to classify
*
* Outputs:
* one of the FP_* classification values
*
****************************************************************
*
__fpclassifyd start
csubroutine (10:val),0
tdc
clc
adc #val
ldy #0
phy
pha
phy
pha
phy
pha
FX2D
FCLASSD
txa
and #$00FF
cmp #$00FC
bne lb1
inc a
lb1 sta val
creturn 2:val
end
****************************************************************
*
* int __fpclassifyl(long double x);
*
* Classify a long double value
*
* Inputs:
* val - the number to classify
*
* Outputs:
* one of the FP_* classification values
*
****************************************************************
*
__fpclassifyl start
csubroutine (10:val),0
tdc
clc
adc #val
pea 0
pha
FCLASSX
txa
and #$00FF
cmp #$00FC
bne lb1
inc a
lb1 sta val
creturn 2:val
end
****************************************************************
*
* int __signbit(long double x);
*
* Get the sign bit of a floating-point value
*
* Inputs:
* val - the number
*
* Outputs:
* 0 if positive, non-zero if negative
*
****************************************************************
*
__signbit start
csubroutine (10:val),0
lda val+8
and #$8000
sta val
creturn 2:val
end
****************************************************************
*
* int __fpcompare(long double x, long double y, short mask);
*
* Compare two floating-point values, not signaling invalid
* if they are unordered.
*
* Inputs:
* x,y - values to compare
* mask - mask of bits as returned in X register from FCMP
*
* Outputs:
* 1 if x and y have one of the relations specified by mask
* 0 otherwise
*
****************************************************************
*
__fpcompare start
csubroutine (10:x,10:y,2:mask),0
tdc
clc
adc #x
pea 0
pha
tdc
clc
adc #y
pea 0
pha
FCMPX
txa
and mask
beq lb1
lda #1
lb1 sta mask
creturn 2:mask
end