;************************************************************ ;IEEE 64 Bit Floating Point Library (c) 2003 M.Cibulski ; ;Compare Routines ; ;************************************************************ ;************************************************************ ;Check for X > 0 ; ;Result: ;T flag 1=true 0=false ; ;************************************************************ .CSEG flt_x_gt_0: clt mov r0 ,AKKU_E1 or r0 ,AKKU_E2 breq flt_xgt0_false ;exp(X)=0: X=0, X>0 is false tst AKKU_S brmi flt_xgt0_false ;negative sign, X>0 is false set flt_xgt0_false: ret ;************************************************************ ;Check for X < 0 ; ;Result: ;T flag 1=true 0=false ; ;************************************************************ .CSEG flt_x_lt_0: clt mov r0 ,AKKU_E1 or r0 ,AKKU_E2 breq flt_xlt0_false ;exp(X)=0: X=0, X<0 is false bst AKKU_S ,7 ;return sign flt_xlt0_false: ret ;************************************************************ ;Check for X >= 0 ; ;Result: ;T flag 1=true 0=false ; ;************************************************************ .CSEG flt_x_ge_0: set mov r0 ,AKKU_E1 or r0 ,AKKU_E2 breq flt_xge0_true ;exp(X)=0: X=0, X>=0 is true tst AKKU_S brpl flt_xge0_true ;positive sign, X>=0 is true clt flt_xge0_true: ret ;************************************************************ ;Check for X <= 0 ; ;Result: ;T flag 1=true 0=false ; ;************************************************************ .CSEG flt_x_le_0: set mov r0 ,AKKU_E1 or r0 ,AKKU_E2 breq flt_xge0_true ;exp(X)=0: X=0, X<=0 is true bst AKKU_S ,7 ;return sign flt_xle0_true: ret ;************************************************************ ;Check for X = 0 ; ;Result: ;T flag 1=true 0=false ; ;************************************************************ .CSEG flt_x_eq_0: set mov r0 ,AKKU_E1 or r0 ,AKKU_E2 breq flt_xeq0_true ;exp(X)=0: X=0 is true clt flt_xeq0_true: ret ;************************************************************ ;Check for X != 0 ; ;Result: ;T flag 1=true 0=false ; ;************************************************************ .CSEG flt_x_ne_0: set mov r0 ,AKKU_E1 or r0 ,AKKU_E2 brne flt_xeq0_true ;exp(X)!=0: X!=0 is true clt flt_xne0_true: ret ;************************************************************ ;Check for X = Y ; ;Result: ;T flag 1=true 0=false ; ;************************************************************ .EQU flt_xeqy_maxerr = 5 .CSEG flt_x_eq_y: push yl push yh in yl ,spl in yh ,sph clt ldd r0 ,Y+FLT_Y_S cp AKKU_S ,r0 brne flt_xeqy_false_end ;sign(Y) <> sign(X), X=Y is false ldd r0 ,Y+FLT_Y_E1 cp r0 ,AKKU_E1 ;compare exponent high byte brne flt_xeqy_false_end ;exp(X) <> exp(Y): X=Y is false ldd r0 ,Y+FLT_Y_E2 cp r0 ,AKKU_E2 ;compare exponent low byte brne flt_xeqy_false_end ;exp(X) <> exp(Y): X=Y is false push AKKU_8 push AKKU_7 push AKKU_6 push AKKU_5 push AKKU_4 push AKKU_3 push AKKU_2 clr r16 ldi r17 ,0xFF ldd r0 ,Y+FLT_Y_8 sub AKKU_8 ,r0 ldd r0 ,Y+FLT_Y_7 sbc AKKU_7 ,r0 or r16 ,AKKU_7 and r17 ,AKKU_7 ldd r0 ,Y+FLT_Y_6 sbc AKKU_6 ,r0 or r16 ,AKKU_6 and r17 ,AKKU_6 ldd r0 ,Y+FLT_Y_5 sbc AKKU_5 ,r0 or r16 ,AKKU_5 and r17 ,AKKU_5 ldd r0 ,Y+FLT_Y_4 sbc AKKU_4 ,r0 or r16 ,AKKU_4 and r17 ,AKKU_4 ldd r0 ,Y+FLT_Y_3 sbc AKKU_3 ,r0 or r16 ,AKKU_3 and r17 ,AKKU_3 ldd r0 ,Y+FLT_Y_2 sbc AKKU_2 ,r0 or r16 ,AKKU_2 and r17 ,AKKU_2 brcs flt_x_eq_y_negative ;Y > X tst r16 brne flt_xeqy_false mov r16 ,AKKU_8 cpi r16 ,flt_xeqy_maxerr+1 brcc flt_xeqy_false rjmp flt_xeqy_true flt_x_eq_y_negative: cpi r17 ,-flt_xeqy_maxerr brcs flt_xeqy_false mov r17 ,AKKU_8 cpi r17 ,0xFF brcs flt_xeqy_false flt_xeqy_true: set flt_xeqy_false: pop AKKU_2 pop AKKU_3 pop AKKU_4 pop AKKU_5 pop AKKU_6 pop AKKU_7 pop AKKU_8 flt_xeqy_false_end: pop yh pop yl ret ;************************************************************ ;Check for X > Y ; ;Result: ;T flag 1=true 0=false ; ;************************************************************ .CSEG flt_x_gt_y: push yl push yh in yl ,spl in yh ,sph set ldd r0 ,Y+FLT_Y_S cp AKKU_S ,r0 brcs flt_xgty_true ;sign(Y) > sign(X), Y negative, X>Y is true brne flt_xgty_false ;sign(Y) < sign(X), Y positive, X>Y is false tst AKKU_S ;signs equal, test for negative numbers brmi flt_xley_positive ;check abs(X) <= abs(Y) instead flt_xgty_positive: ldd r0 ,Y+FLT_Y_E1 cp r0 ,AKKU_E1 ;compare exponent high byte brcs flt_xgty_true ;underflow: exp(X) > exp(Y), X>Y is true brne flt_xgty_false ;exp(X) < exp(Y): X>Y is false ldd r0 ,Y+FLT_Y_E2 cp r0 ,AKKU_E2 ;compare exponent low byte brcs flt_xgty_true ;underflow: exp(X) > exp(Y), X>Y is true brne flt_xgty_false ;exp(X) < exp(Y): X>Y is false ldd r0 ,Y+FLT_Y_2 cp r0 ,AKKU_2 ;compare highest mantissa byte brcs flt_xgty_true ;underflow: X > Y, X>Y is true brne flt_xgty_false ;X < Y: X>Y is false ldd r0 ,Y+FLT_Y_3 cp r0 ,AKKU_3 ;compare next mantissa byte brcs flt_xgty_true ;underflow: X > Y, X>Y is true brne flt_xgty_false ;X < Y: X>Y is false ldd r0 ,Y+FLT_Y_4 cp r0 ,AKKU_4 ;compare next mantissa byte brcs flt_xgty_true ;underflow: X > Y, X>Y is true brne flt_xgty_false ;X < Y: X>Y is false ldd r0 ,Y+FLT_Y_5 cp r0 ,AKKU_5 ;compare next mantissa byte brcs flt_xgty_true ;underflow: X > Y, X>Y is true brne flt_xgty_false ;X < Y: X>Y is false ldd r0 ,Y+FLT_Y_6 cp r0 ,AKKU_6 ;compare next mantissa byte brcs flt_xgty_true ;underflow: X > Y, X>Y is true brne flt_xgty_false ;X < Y: X>Y is false ldd r0 ,Y+FLT_Y_7 cp r0 ,AKKU_7 ;compare next mantissa byte brcs flt_xgty_true ;underflow: X > Y, X>Y is true brne flt_xgty_false ;X < Y: X>Y is false ldd r0 ,Y+FLT_Y_8 cp r0 ,AKKU_8 ;compare lowest mantissa byte brcs flt_xgty_true ;underflow: X > Y, X>Y is true flt_xgty_false: clt flt_xgty_true: pop yh pop yl ret ;************************************************************ ;Check for X <= Y ; ;Result: ;T flag 1=true 0=false ; ;************************************************************ .CSEG flt_x_le_y: push yl push yh in yl ,spl in yh ,sph clt ldd r0 ,Y+FLT_Y_S cp AKKU_S ,r0 brcs flt_xley_false ;sign(Y) > sign(X), Y negative, X<=Y is false brne flt_xley_true ;sign(Y) < sign(X), Y positive, X<=Y is true tst AKKU_S ;signs equal, test for negative numbers brmi flt_xgty_positive ;check abs(X) > abs(Y) instead flt_xley_positive: ldd r0 ,Y+FLT_Y_E1 cp r0 ,AKKU_E1 ;compare exponent high byte brcs flt_xley_false ;underflow: exp(X) > exp(Y), X<=Y is false brne flt_xley_true ;exp(X) < exp(Y): X<=Y is true ldd r0 ,Y+FLT_Y_E2 cp r0 ,AKKU_E2 ;compare exponent low byte brcs flt_xley_false ;underflow: exp(X) > exp(Y), X<=Y is false brne flt_xley_true ;exp(X) < exp(Y): X<=Y is true ldd r0 ,Y+FLT_Y_2 cp r0 ,AKKU_2 ;compare highest mantissa byte brcs flt_xley_false ;underflow: X > Y, X<=Y is false brne flt_xley_true ;X < Y: X<=Y is true ldd r0 ,Y+FLT_Y_3 cp r0 ,AKKU_3 ;compare next mantissa byte brcs flt_xley_false ;underflow: X > Y, X<=Y is false brne flt_xley_true ;X < Y: X<=Y is true ldd r0 ,Y+FLT_Y_4 cp r0 ,AKKU_4 ;compare next mantissa byte brcs flt_xley_false ;underflow: X > Y, X<=Y is false brne flt_xley_true ;X < Y: X<=Y is true ldd r0 ,Y+FLT_Y_5 cp r0 ,AKKU_5 ;compare next mantissa byte brcs flt_xley_false ;underflow: X > Y, X<=Y is false brne flt_xley_true ;X < Y: X<=Y is true ldd r0 ,Y+FLT_Y_6 cp r0 ,AKKU_6 ;compare next mantissa byte brcs flt_xley_false ;underflow: X > Y, X<=Y is false brne flt_xley_true ;X < Y: X<=Y is true ldd r0 ,Y+FLT_Y_7 cp r0 ,AKKU_7 ;compare next mantissa byte brcs flt_xley_false ;underflow: X > Y, X<=Y is false brne flt_xley_true ;X < Y: X<=Y is true ldd r0 ,Y+FLT_Y_8 cp r0 ,AKKU_8 ;compare lowest mantissa byte brcs flt_xley_false ;underflow: X > Y, X<=Y is false flt_xley_true: set flt_xley_false: pop yh pop yl ret ;************************************************************ ;Check for X >= Y ; ;Result: ;T flag 1=true 0=false ; ;************************************************************ .CSEG flt_x_ge_y: push yl push yh in yl ,spl in yh ,sph clt ldd r0 ,Y+FLT_Y_S cp AKKU_S ,r0 brcs flt_xgey_true ;sign(Y) > sign(X), Y negative, X>=Y is true brne flt_xgey_false ;sign(Y) < sign(X), Y positive, X>=Y is false tst AKKU_S ;signs equal, test for negative numbers brmi flt_xlty_positive ;check abs(X) < abs(Y) instead flt_xgey_positive: ldd r0 ,Y+FLT_Y_E1 cp r0 ,AKKU_E1 ;compare exponent high byte brcs flt_xgey_true ;underflow: exp(X) > exp(Y), X>=Y is true brne flt_xgey_false ;exp(X) < exp(Y): X>=Y is false ldd r0 ,Y+FLT_Y_E2 cp r0 ,AKKU_E2 ;compare exponent low byte brcs flt_xgey_true ;underflow: exp(X) > exp(Y), X>=Y is true brne flt_xgey_false ;exp(X) < exp(Y): X>=Y is false ldd r0 ,Y+FLT_Y_2 cp r0 ,AKKU_2 ;compare highest mantissa byte brcs flt_xgey_true ;underflow: X > Y, X>=Y is true brne flt_xgey_false ;X < Y: X>=Y is false ldd r0 ,Y+FLT_Y_3 cp r0 ,AKKU_3 ;compare next mantissa byte brcs flt_xgey_true ;underflow: X > Y, X>=Y is true brne flt_xgey_false ;X < Y: X>=Y is false ldd r0 ,Y+FLT_Y_4 cp r0 ,AKKU_4 ;compare next mantissa byte brcs flt_xgey_true ;underflow: X > Y, X>=Y is true brne flt_xgey_false ;X < Y: X>=Y is false ldd r0 ,Y+FLT_Y_5 cp r0 ,AKKU_5 ;compare next mantissa byte brcs flt_xgey_true ;underflow: X > Y, X>=Y is true brne flt_xgey_false ;X < Y: X>=Y is false ldd r0 ,Y+FLT_Y_6 cp r0 ,AKKU_6 ;compare next mantissa byte brcs flt_xgey_true ;underflow: X > Y, X>=Y is true brne flt_xgey_false ;X < Y: X>=Y is false ldd r0 ,Y+FLT_Y_7 cp r0 ,AKKU_7 ;compare next mantissa byte brcs flt_xgey_true ;underflow: X > Y, X>=Y is true brne flt_xgey_false ;X < Y: X>=Y is false ldd r0 ,Y+FLT_Y_8 cp AKKU_8 ,r0 ;compare lowest mantissa byte brcs flt_xgey_false ;underflow: Y > X, X>=Y is false flt_xgey_true: set flt_xgey_false: pop yh pop yl ret ;************************************************************ ;Check for X < Y ; ;Result: ;T flag 1=true 0=false ; ;************************************************************ .CSEG flt_x_lt_y: push yl push yh in yl ,spl in yh ,sph set ldd r0 ,Y+FLT_Y_S cp AKKU_S ,r0 brcs flt_xlty_false ;sign(Y) > sign(X), Y negative, X= abs(Y) instead flt_xlty_positive: ldd r0 ,Y+FLT_Y_E1 cp r0 ,AKKU_E1 ;compare exponent high byte brcs flt_xlty_false ;underflow: exp(X) > exp(Y), X exp(Y), X<=Y is false brne flt_xlty_true ;exp(X) < exp(Y): X Y, X Y, X Y, X Y, X Y, X Y, X X, X