Skip to content

Opt dcmp #608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 0 additions & 42 deletions src/crt/dcmp.c

This file was deleted.

82 changes: 65 additions & 17 deletions src/crt/dcmp.src
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,71 @@

public __dcmp

; int _dcmp_c(f64_cmp_arg const *__restrict const arg)
__dcmp:
; f64_cmp_arg*_ret_i24
push bc, de, hl
or a, a
sbc hl, hl
add hl, sp
push iy, af
push hl ; f64_cmp_arg*
call __dcmp_c
pop af
pop af, iy
; Set the comparison flags
add hl, de
or a, a
sbc hl, de
pop hl, de, bc
push iy
ld iy, 0
add iy, sp
push bc
push hl
ld hl, (iy + 12) ; y.hi
rlc b
sla h ; Carry = signbit y
bit 0, b ; signbit x
jr z, .positve_x
ccf
.positve_x:
res 0, b
; H and B now have their signbits cleared
jr c, .different_sign
; same_sign
sbc.s hl, bc ; y.hi - x.hi
jr nz, .not_equal
ld hl, (iy + 9) ; y.md
sbc hl, de ; y.md - x.md
jr nz, .not_equal
ld bc, (iy - 6) ; x.lo
ld hl, (iy + 6) ; y.lo
sbc hl, bc ; y.lo - x.lo
jr z, .equal
.not_equal:
ld l, a ; preserve A
rra ; bit 7 of A = Carry
cpl
.ret_flags:
xor a, (iy - 2) ; bit 7 of B = sign of x
rla
sbc a, a ; A is 0 or -1
ccf ; carry is set when A is 0, so A will be 1 or -1 in the end
adc a, e
sub a, e
ld a, l ; restore A
.equal:
.finish_zero:
pop hl
pop bc
pop iy
ret

extern __dcmp_c
.different_sign:
; test for zero
; x[hi-md-lo]
; y[hi-md-lo]
add.s hl, bc
adc hl, de
jr nz, .non_zero ; path taken by normal, inf, and NaN
jr c, .non_zero
; both x and y are subnormal or zero
; x[00-00-lo]
; y[00-md-lo]
; HL is zero, Carry is reset
ld hl, (iy + 6) ; y.lo
ld bc, (iy + 9) ; y.md
add hl, bc
ld bc, (iy - 6) ; x.lo
adc hl, bc
jr nz, .non_zero
jr nc, .finish_zero ; Z, NC, and P
.non_zero:
ld l, a ; preserve A
xor a, a
jr .ret_flags
25 changes: 14 additions & 11 deletions src/crt/dtoll.src
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,31 @@ __dtoull:
jr z, .zero_or_one
bit 7, b
push af
res 7, b
; res 7, b ; not needed since this bit is shifted out later on
push hl
; -((Float64_mant_bits + Float64_bias) << 4)
ld hl, $FFC010 ; -16368 ; -$3FF0
; ld hl, $FFC010 ; -16368 ; -$3FF0

; clears the exponent field without touching the mantissa
; sets the LSB of the exponent since x is normalized
ld a, c
or a, l ; or a, $10
and a, $1F

add hl, bc
; extract the exponent
ld h, b
ld l, c
; HL <<= 4
add hl, hl
add hl, hl
add hl, hl
add hl, hl
; inc hl

; clears the exponent field without touching the mantissa
; sets the LSB of the exponent since x is normalized
ld a, c
or a, $10
and a, $1F
ld c, a
ld b, 0
ld a, h
sub a, 52 + 1 ; float64 mantissa bits

ld a, h ; expon
sub a, 52 + 1 - 1 ; float64 mantissa bits + CPL trick - inc HL
jr c, .shift_right
; shift_left
; expon >= 52 or [52, 63]
Expand Down
16 changes: 6 additions & 10 deletions src/crt/ltod.src
Original file line number Diff line number Diff line change
Expand Up @@ -48,25 +48,24 @@ __ltod:
private __ltod.hijack
__ltod.hijack:
call __lctlz
cp a, 32
inc.s bc ; clear UBC
ld b, a ; <<= 8
xor a, $20 ; turns 32 into zero and clears carry flag
jr z, .zero
; clears the MSB since the float will be normalized
; x <<= clz_result + 1; /* shift by 32 is UB */
if 0
; calculate the exponent
push hl
; 1023 + 31 = 1054 = 0x41E
inc.s bc
or a, a
ld b, a ; <<= 8
ld hl, $041E00
ld c, l ; ld c, 0
sbc hl, bc
ld l, e ; (expon16 << (16 + 24)) | (mant48)
ex de, hl
pop hl

ld b, a
; ld b, a
inc b
ld a, e
.loop32: ; shift by 32 is not UB here!
Expand All @@ -78,17 +77,14 @@ else
; calculate the exponent
push hl
; 1023 + 31 = 1054 = 0x41E
inc.s bc
or a, a
ld b, a ; <<= 8
ld hl, $041E00
ld c, l ; ld c, 0
sbc hl, bc
ld l, e ; (expon16 << (16 + 24)) | (mant48)
ex de, hl

ld l, b
pop bc
ld l, a
ld a, e
call __lshl
push bc
Expand All @@ -112,7 +108,7 @@ end if
ret ; negative

.zero:
sbc hl, hl
; E:UHL and A are zero
ex de, hl
sbc hl, hl
ld b, e
Expand Down
Loading
Loading