From 178e2a54e402f4f945e27a979b946acdf433a971 Mon Sep 17 00:00:00 2001 From: unknown <71151164+ZERICO2005@users.noreply.github.com> Date: Fri, 3 Oct 2025 14:10:53 -0600 Subject: [PATCH 01/13] added ez80sf to CRT (jacobly0/calc84maniac) Co-authored-by: Brendan Fletcher Co-authored-by: Jacob Young --- src/crt/dabs.src | 10 + src/crt/fpabs.src | 11 + src/crt/fpaddsub.src | 231 +++++++++++++++++++++ src/crt/fpcbrt.src | 185 +++++++++++++++++ src/crt/fpcmp.src | 198 ++++++++++++++++++ src/crt/fpcopysign.src | 28 +++ src/crt/fpdiv.src | 164 +++++++++++++++ src/crt/fpminmax.src | 48 +++++ src/crt/fpmul.src | 180 ++++++++++++++++ src/crt/fpneg.src | 11 + src/crt/fprem.src | 79 +++++++ src/crt/fpround.src | 61 ++++++ src/crt/fpsqrt.src | 111 ++++++++++ src/crt/fptemp.src | 33 +++ src/crt/fptol.src | 54 +++++ src/crt/fptoll.src | 48 +++++ src/crt/fptrunc.src | 119 +++++++++++ src/crt/fputil.src | 119 +++++++++++ src/crt/lltofp.src | 71 +++++++ src/crt/ltofp.src | 58 ++++++ src/libc/sqrtf.c | 2 +- test/floating_point/ez80sf/autotest.json | 43 ++++ test/floating_point/ez80sf/makefile | 20 ++ test/floating_point/ez80sf/src/link_test.s | 92 ++++++++ test/floating_point/ez80sf/src/main.c | 66 ++++++ 25 files changed, 2041 insertions(+), 1 deletion(-) create mode 100644 src/crt/dabs.src create mode 100644 src/crt/fpabs.src create mode 100644 src/crt/fpaddsub.src create mode 100644 src/crt/fpcbrt.src create mode 100644 src/crt/fpcmp.src create mode 100644 src/crt/fpcopysign.src create mode 100644 src/crt/fpdiv.src create mode 100644 src/crt/fpminmax.src create mode 100644 src/crt/fpmul.src create mode 100644 src/crt/fpneg.src create mode 100644 src/crt/fprem.src create mode 100644 src/crt/fpround.src create mode 100644 src/crt/fpsqrt.src create mode 100644 src/crt/fptemp.src create mode 100644 src/crt/fptol.src create mode 100644 src/crt/fptoll.src create mode 100644 src/crt/fptrunc.src create mode 100644 src/crt/fputil.src create mode 100644 src/crt/lltofp.src create mode 100644 src/crt/ltofp.src create mode 100644 test/floating_point/ez80sf/autotest.json create mode 100644 test/floating_point/ez80sf/makefile create mode 100644 test/floating_point/ez80sf/src/link_test.s create mode 100644 test/floating_point/ez80sf/src/main.c diff --git a/src/crt/dabs.src b/src/crt/dabs.src new file mode 100644 index 000000000..ec1d7ec4d --- /dev/null +++ b/src/crt/dabs.src @@ -0,0 +1,10 @@ + assume adl=1 + + section .text + + public __dabs + +; assumes BC:UDE:UHL +__dabs: + res 7, b + ret diff --git a/src/crt/fpabs.src b/src/crt/fpabs.src new file mode 100644 index 000000000..c3ef733fd --- /dev/null +++ b/src/crt/fpabs.src @@ -0,0 +1,11 @@ + assume adl=1 + + section .text + + public __fpabs + +; IEEE single precision absolute value +; aubc = |aubc| +__fpabs: ; CHECK: bitcast(uint32_t, pair8_24_t, { out.BC, out.A }) == bitcast(uint32_t, float, fabsf(bitcast(float, pair8_24_t, { in.BC, in.A }))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + and a, 07Fh + ret diff --git a/src/crt/fpaddsub.src b/src/crt/fpaddsub.src new file mode 100644 index 000000000..0b42a55b0 --- /dev/null +++ b/src/crt/fpaddsub.src @@ -0,0 +1,231 @@ + assume adl=1 + +;------------------------------------------------------------------------------- + + section .text + + public __fpsub + +; IEEE single precision subtraction +; aubc = aubc - euhl +__fpsub: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(float, pair8_24_t, { in.BC, in.A }) - bitcast(float, pair8_24_t, { in.HL, in.E })) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + push de + rl e + ccf + rr e +; jq __fpadd.enter + virtual + ld d, 0 + load .ld_d : byte from $$ + end virtual + db .ld_d + + require __fpadd + +;------------------------------------------------------------------------------- + + section .text + + public __fpadd + +; IEEE single precision addition +; aubc = aubc + euhl +__fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(float, pair8_24_t, { in.BC, in.A }) + bitcast(float, pair8_24_t, { in.HL, in.E })) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + push de +.enter: + push hl + push bc + xor a, e + ld d, a + push de + push bc + xor a, e + call __fppop1 + ex (sp), hl + ld d, e + ld e, a + call __fppop2 + inc e + jq z, .nonfinite1 + inc d + jq z, .return2 + ld a, d + sub a, e + jq z, .rounded + jq nc, .sorted + inc c + ex (sp), hl + ld a, e + sub a, d + ld d, e +.sorted: + cp a, 26 + jq nc, .largest + ; Extend to 32 bits and shift left by ~(amount - 1) & 7 + dec a + ld b, a + xor a, a + srl b + jq c, .noshift1 + add hl, hl + rla +.noshift1: + srl b + jq c, .noshift2 + repeat 2 + add hl, hl + rla + end repeat +.noshift2: + srl b + jq c, .noshift4 + repeat 4 + add hl, hl + rla + end repeat +.noshift4: + ; Shift right by (amount + 7) / 8 * 8, truncating to 24 bits + ; The last 2 bits shifted out are in A, while any remaining non-zero + ; bits are aggregated into the lower bits of A + push af + inc sp + push hl + inc sp + ld a, l + jq nz, .shift16 + ; Shift by 8 for amounts between 1 and 8 + pop hl + inc sp + jq .rounded + +.shift16: + ; Shift by 16 for amounts between 9 and 16 + ld e, h + inc sp + pop hl + dec b + jq z, .flush +.shift8more: + ; Shift by 24 for amounts between 17 and 24 + or a, e + ld e, l + ld l, h + ld h, 0 + ; Shift by 32 for amount of 25 + djnz .shift8more +.flush: + sub a, 1 + sbc a, a + inc a + or a, e +.rounded: + ld b, d + pop de + ex (sp), hl + add.s hl, hl + jq nc, .add + ld l, h + add hl, bc + ld c, l + pop hl + djnz .subtract ;always taken + +.nonfinite1: + inc d + jq z, .nonfinite +.return1: + pop bc +.return1.pop1: + pop de + ld a, d +.return1.pop2: + xor a, e + pop bc +.return: + pop hl + pop de + ret + +.largest: + ld a, d + cp a, e + jq z, .return1 +.return2: + pop bc +.return2.pop1: + pop de +.return2.pop2: + ld a, e + pop bc + pop bc + push bc + jq .return + +.add: + ld c, h + pop hl + add hl, de + dec b + jq nc, .done + ex de, hl + sbc hl, hl + add hl, sp + push de + rr (hl) + pop hl + rr h + rr l + rra + jq nc, .flushed2 + or a, 1 +.flushed2: + inc b + inc b + jq z, .infinite + djnz .done ;always taken + +.borrow: + inc c + add hl, de +.subtract: + ex de, hl + neg + sbc hl, de + jq c, .borrow + jq nz, .done + or a, a +.done: + ld de, 0800000h + call nz, __fppack + pop bc + ex (sp), hl + pop bc + pop de + ret + +.nonfinite: + xor a, a + sbc hl, bc + jq nz, .return1 + pop hl + sbc hl, bc + jq nz, .return2.pop1 + pop de + bit 7, d + jq z, .return1.pop2 + ld bc, 0C00000h +.infinite: + ld a, c + ld c, b ;0, also note BCU=080h from __fppop1 or 0C0h from .nonfinite + rrca + or a, 07Fh + pop hl + pop hl + pop de + ret + +;------------------------------------------------------------------------------- + + extern __fppop1 + extern __fppop2 + extern __fppack diff --git a/src/crt/fpcbrt.src b/src/crt/fpcbrt.src new file mode 100644 index 000000000..5f559d10c --- /dev/null +++ b/src/crt/fpcbrt.src @@ -0,0 +1,185 @@ + assume adl=1 + + section .text + + public __fpcbrt + +; IEEE single precision cube root +; aubc = cbrt(aubc) +__fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cbrt(bitcast(float, pair8_24_t, { in.BC, in.A }))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + push de, bc + ex (sp), hl + ld e, a + call __fppop1 + inc e + jq z, .nonfinite + dec e + ld d, 0ABh ; multiplicative inverse of 3 modulo 256 + ld b, d + mlt de + ld c, a + ld a, i + push af, hl + ex (sp), ix + or a, a + sbc hl, hl + ld a, e + ld d, 10 ; maximum normalization iterations to determine a zero +.modulo.loop: + ; x <<= 1 + add ix, ix + adc hl, hl + sub a, b + jq c, .modulo.loop + jq nz, .normalized + dec d + jq z, .return + cp a, l + inc a + jq nc, .modulo.loop +.normalized: + add a, d + ld b, a + push bc + xor a, a + ld d, a + ld e, a + push de + ex (sp), iy + ; Optimized first iteration, we know UHL >= 1 + ; r += 1 + inc de + ; x -= r << 24 + dec hl + di + exx + ld c, a + sbc hl, hl + ex de, hl + sbc hl, hl + ld b, 24 + ; x in AUHL[UHL']UIX, r in CUDE[UDE'], q in UIY +.root.loop: + exx + lea bc, iy + jq c, .root.zerobit + ex af, af' + ; q += 1 + inc iy + ; r += q * 4 - 1 + ex de, hl + xor a, a + add hl, bc + rla + inc bc + repeat 3 + add hl, bc + adc a, 0 + end repeat + ; r <<= 2 + add hl, hl + rla + ; r += q + add hl, bc + adc a, 0 + jq .root.nextbit +.root.zerobit: + ; x += r << 24 + add hl, de + exx + adc hl, de + adc a, c + exx + ex af, af' + ; r -= q + 1 + ex de, hl + scf + sbc hl, bc + sbc a, a + ; r <<= 1 + add hl, hl + rla + ; r -= q + or a, a + sbc hl, bc + sbc a, 0 +.root.nextbit: + ; r <<= 1 + add hl, hl + rla + ex de, hl + exx + push hl + ; Sign extend carry byte to 32 bits + sbc hl, hl + ld l, a + sbc a, a + ; Left shift high 32 bits of r by 2 + ex de, hl + repeat 2 + add hl, hl + rl c + end repeat + ; Add carry byte to shifted high bits + add hl, de + ex de, hl + adc a, c + ld c, a + pop hl + exx + ; x <<= 3 + xor a, a + repeat 3 + add ix, ix + adc hl, hl + rla + end repeat + exx + ex af, af' + repeat 3 + add hl, hl + rla + end repeat + ex af, af' + or a, l + ld l, a + ex af, af' + exx + ; q <<= 1 + add iy, iy ; clears carry + ; r += 1 + inc de ; sets bit 0 so never overflows + ; x -= r << 24 + sbc hl, de + exx + sbc hl, de + sbc a, c + djnz .root.loop + ; Apply rounding (never round-to-even because a root with the lowest mantissa bit set must be irrational) + ; q += !carry + exx + sbc hl, hl + inc hl + add hl, bc + pop iy, bc + ; Get final exponent after rounding + ld a, b + adc a, 07Fh - (07Fh / 3) - 10 + ; Set low exponent bit + srl b + jq nc, .return + ld de, 0800000h + add hl, de +.return: + sla c + rra + pop ix, bc + bit 2, c +.nonfinite: + ex (sp), hl + pop bc, de + ret z + ei + ret + + extern __fppop1 diff --git a/src/crt/fpcmp.src b/src/crt/fpcmp.src new file mode 100644 index 000000000..0eada9d8e --- /dev/null +++ b/src/crt/fpcmp.src @@ -0,0 +1,198 @@ + assume adl=1 + +;------------------------------------------------------------------------------- + + section .text + + public __fpcmpu + +; IEEE single precision unordered comparison +; z = euhl == aubc || isunordered(euhl, aubc) +; c = !isunordered(euhl, aubc) +__fpcmpu: ; CHECK: out.flags.C == !isunordered(bitcast(float, pair8_24_t, { in.HL, in.E }), bitcast(float, pair8_24_t, { in.BC, in.A })) && out.flags.Z == (!out.flags.C || (bitcast(float, pair8_24_t, { in.HL, in.E }) == bitcast(float, pair8_24_t, { in.BC, in.A }))) && out.A == in.A && out.BC == in.BC && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + call __fpcmpo + ret c ; If euhl < aubc: C = 1, Z = 0 + scf + ret p ; If euhl >= aubc: C = 1, Z = (euhl == aubc) + cp a, a ; If unordered: C = 0, Z = 1 + ret + +;------------------------------------------------------------------------------- + + section .text + + public __fpcmpo + +; IEEE single precision ordered comparison +; z = euhl == aubc +; c = euhl < aubc +; s = !(euhl >= aubc) +__fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) == bitcast(float, pair8_24_t, { in.BC, in.A })) && out.flags.C == (bitcast(float, pair8_24_t, { in.HL, in.E }) < bitcast(float, pair8_24_t, { in.BC, in.A })) && out.flags.S == !(bitcast(float, pair8_24_t, { in.HL, in.E }) >= bitcast(float, pair8_24_t, { in.BC, in.A })) && out.A == in.A && out.BC == in.BC && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + xor a, e + jq z, .maybeEqual + cp a, 080h + jq c, .signsMatch + jq z, .maybeBothZero + xor a, e + ; Check if first operand could hold NaN, and if so, the second cannot on this code path + inc e + jq z, .checkFirstNan + jq pe, .checkFirstNan + dec e +.secondLargerAbs: + cp a, 07Fh ; C = S = !sign(aubc), Z = 0 + ret c ; Return if A less than 07Fh + ret pe ; Return if A between 080h and 0FEh +.checkSecondNan: + push hl + ld hl, 07FFFFFh + add hl, bc + pop hl + jq c, .unordered + cp a, 080h ; C = S = !sign(aubc), Z = 0 + ret + +.signsMatch: + xor a, e + ; Compare upper 7 exponent bits, which are not equal + cp a, e + jq nc, .secondLargerAbs + inc e + jq z, .checkFirstNan + dec e ; S = sign(euhl), Z = 0 because E > A + rlca + rrca ; C = sign(aubc), same as sign(euhl) on this code path + ret po ; Return if E != 07Fh +.checkFirstNanInc: + inc e +.checkFirstNan: + ex de, hl + push hl + ld hl, 07FFFFFh + add hl, de + pop hl + ex de, hl + dec e ; S = sign(euhl), Z = 0 because (E & 07Fh) == 07Fh + jq c, .unordered + ret p ; C = sign(euhl) + scf ; C = sign(euhl) + ret + +.maybeBothZero: + ; Upper 7 bits of exponents are equal, but sign differs + xor a, e + ; Check if upper 7 bits of both exponents are zero + add a, a + rra + jq nz, .notBothZero + ; Check if low bit of both exponents and entire mantissas are 0 + adc hl, bc + jq nz, .notBothZeroFixup + ret nc ; Both inputs are zero, return Z=1, C=0, S=0 +.notBothZeroFixup: + or a, a + sbc hl, bc +.notBothZero: + ; Check if upper 7 bits of both exponents are one + cp a, 07Fh ; C = S = !sign(aubc), Z = 0 + ret c ; Return if less than 07Fh + ret pe ; Return if between 080h and 0FEh + ; Check the larger exponent/mantissa for NaN + sbc hl, bc + add hl, bc + jq nc, .checkFirstNanInc + jq .checkSecondNan + +.maybeEqual: + ; Sign and upper 7 exponent bits are equal + ld a, e + inc a + add a, a + ld a, e + jq z, .checkBothNan + or a, a +.checkBothNanDone: + ; Compare mantissas and low exponent bit + sbc hl, bc + add hl, bc + ret z ; Both inputs are equal, return Z=1, C=0, S=0 + ; XOR the carry with the input sign and place into the output sign/carry + sbc a, a + xor a, e + or a, 07Fh ; Affect S flag, Z = 0 + rlca ; Affect C flag + ld a, e + ret + +.checkBothNan: + ex de, hl + push hl + ld hl, 07FFFFFh + add hl, de + jq c, .gotFirstNan + sbc hl, de + add hl, bc +.gotFirstNan: + pop hl + ex de, hl + jq nc, .checkBothNanDone +.unordered: + ; Carry is always set here + rr a ; Z = 0, S = 1 + rla ; Restore A + ccf ; C = 0 + ret + +;------------------------------------------------------------------------------- + + section .text + + public __fpcmp + +; IEEE single precision comparison (flag outputs for NaN inputs are undefined) +; z = euhl == aubc +; s = euhl < aubc = !(euhl >= aubc) +__fpcmp: ; CHECK: (isunordered(bitcast(float, pair8_24_t, { in.HL, in.E }), bitcast(float, pair8_24_t, { in.BC, in.A })) || (out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) == bitcast(float, pair8_24_t, { in.BC, in.A })) && out.flags.S == (bitcast(float, pair8_24_t, { in.HL, in.E }) < bitcast(float, pair8_24_t, { in.BC, in.A })))) && out.A == in.A && out.BC == in.BC && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + sub a, e + jq z, .maybeEqual + cp a, 080h + jq z, .maybeBothZero + ; Compare sign and upper 7 exponent bits, which are not equal + add a, e + inc e + dec e ; S = sign(euhl), Z = 0 because E > A + ret c +.notBothZero: + cp a, 080h ; S = !sign(aubc) + ret nz + cp a, e ; S = !sign(aubc), Z = 0 because A == 080h and A > E and A - E != 080h + ret + +.maybeBothZero: + add a, e + add a, a + rra + jq nz, .notBothZero + adc hl, bc + jq c, .notBothZeroFixup + ret z ; Both inputs are zero, return Z=1, S=0 +.notBothZeroFixup: + or a, a + sbc hl, bc + dec a ; S = !sign(aubc), Z = 0 because (A & 07Fh) == 0 + cpl ; Restore A, preserve S and Z + ret + +.maybeEqual: + ld a, e + sbc hl, bc + add hl, bc + ret z + ; XOR the carry with the input sign and place into the output sign + sbc a, a + xor a, e + or a, 07Fh ; Affect S flag, Z = 0 + ld a, e + ret + +;------------------------------------------------------------------------------- diff --git a/src/crt/fpcopysign.src b/src/crt/fpcopysign.src new file mode 100644 index 000000000..5b94f9d66 --- /dev/null +++ b/src/crt/fpcopysign.src @@ -0,0 +1,28 @@ + assume adl=1 + +;------------------------------------------------------------------------------- + + section .text + + public __fpcopysign + +; IEEE single precision copy sign +; aubc = copysign(aubc, euhl) +__fpcopysign: ; CHECK: bitcast(uint32_t, pair8_24_t, { out.BC, out.A }) == bitcast(uint32_t, float, copysignf(bitcast(float, pair8_24_t, { in.BC, in.A }), bitcast(float, pair8_24_t, { in.HL, in.E }))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + xor a, e + and a, 07Fh + xor a, e + jq __fpcopy + +;------------------------------------------------------------------------------- + + section .text + + public __fpcopy + +; IEEE single precision copy +; aubc = copy(aubc) +__fpcopy: ; CHECK: bitcast(uint32_t, pair8_24_t, { out.BC, out.A }) == bitcast(uint32_t, pair8_24_t, { in.BC, in.A }) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + ret + +;------------------------------------------------------------------------------- diff --git a/src/crt/fpdiv.src b/src/crt/fpdiv.src new file mode 100644 index 000000000..b9b2cf53e --- /dev/null +++ b/src/crt/fpdiv.src @@ -0,0 +1,164 @@ + assume adl=1 + + section .text + + public __fpdiv + +; IEEE single precision division +; aubc = aubc / euhl +__fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(float, pair8_24_t, { in.BC, in.A }) / bitcast(float, pair8_24_t, { in.HL, in.E })) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + push de, hl + xor a, e + push af + xor a, e + push bc + call __fppop1 + ex (sp), hl + ld d, e + ld e, a + call __fppop2 + inc e + jq z, .nonfinite.1 + ld a, d + inc a + jq z, .nonfinite.2 + add a, 080h + dec d + jq nz, .exponent.adjust + ex (sp), hl + add hl, bc + jq c, .normalize.divisor.done + sbc hl, bc + jq z, .divisor.zero +.normalize.divisor.loop: + dec a + add hl, hl + add hl, bc + jq nc, .normalize.divisor.loop +.normalize.divisor.done: + add hl, bc + ex (sp), hl +.exponent.adjust: + ex de, hl ; ude=UHL, uhl=UDE + ld h, b + rl b + ld c, a + sbc hl, bc + ld b, h + ld c, l + pop hl + add hl, de ; uhl=UHL+UDE + ex de, hl ; ude=UHL+UDE, uhl=UHL + xor a, a + sbc hl, de ; uhl=-UDE + ex de, hl ; ude=-UDE, uhl=UHL+UDE + add hl, de ; uhl=UHL +.normalize.dividend.loop: + add hl, de + jq c, .normalize.dividend.done + sbc hl, de + jq z, .dividend.zero + dec bc + add hl, hl + jq nc, .normalize.dividend.loop + add hl, de +.normalize.dividend.done: + cp a, b + jq nc, .return.overflow + dec bc + dec bc + ld a, c + inc b + ld bc, 0800000h or (23 shl 8) + jq z, .divide.entry.normal + adc a, b + ld b, a + ld a, c + jq nc, .return.underflow + push iy + ld iy, 0 + jq nz, .divide.entry.subnormal + dec hl + add hl, de + jq .subsubnormal + +.divisor.zero: + pop de + sbc hl, de + jq nz, .return.nonfinite +.return.nan: + inc b +.return.overflow: + ld c, b +.return.nonfinite: + pop af, hl, de + or a, 07Fh + ret + +.nonfinite.1: + inc d + pop de + jq z, .return.nan + push hl + pop bc + jq .return.nonfinite + +.nonfinite.2: + pop hl + dec hl + add hl, bc + jq c, .return.nan +.return.underflow: + sbc hl, hl +.dividend.zero: + pop de + jq .return + +.divide.entry.normal: + push iy + ld iyl, b +.divide.loop: + add iy, iy + add hl, hl + jq c, .divide.overflow + add hl, de + jq c, .divide.setbit + sbc hl, de + djnz .divide.loop + add hl, hl + jq .divide.finish +.divide.overflow: + add hl, de +.divide.setbit: +.divide.entry.subnormal: + inc iy + djnz .divide.loop + add hl, hl + inc hl +.divide.finish: + jq c, .round + dec de + add hl, de +.round: + ccf +.subsubnormal: + lea de, iy + pop iy + sbc hl, hl + inc hl + add hl, de + pop de + ld e, a + adc a, 1 + srl e + jq nc, .return + add hl, bc +.return: + sla d + rra + ex (sp), hl + pop bc, de + ret + + extern __fppop1 + extern __fppop2 diff --git a/src/crt/fpminmax.src b/src/crt/fpminmax.src new file mode 100644 index 000000000..692f58054 --- /dev/null +++ b/src/crt/fpminmax.src @@ -0,0 +1,48 @@ + assume adl=1 + + section .text + + public __fpmin + public __fpmax + +; IEEE single precision minimum +; aubc = fmin(aubc, euhl) +__fpmin: ; CHECK: sameignzerosign(bitcast(float, pair8_24_t, { out.BC, out.A }), fminf(quiet(bitcast(float, pair8_24_t, { in.BC, in.A })), quiet(bitcast(float, pair8_24_t, { in.HL, in.E })))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + call __fpcmpo + ret p + jq nc, __fpmax.unordered +.return: + push hl + pop bc + ld a, e + ret + +; IEEE single precision maximum +; aubc = fmax(aubc, euhl) +__fpmax: ; CHECK: sameignzerosign(bitcast(float, pair8_24_t, { out.BC, out.A }), fmaxf(quiet(bitcast(float, pair8_24_t, { in.BC, in.A })), quiet(bitcast(float, pair8_24_t, { in.HL, in.E })))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + call __fpcmpo + ret c + jq p, __fpmin.return +.unordered: + ; Compare the low 31 bits (ignoring sign) and return the smaller one, which is non-NaN if either one is + sbc hl, bc + ccf + sbc a, e + add hl, bc + ccf + adc a, e + ; Carry into bit 31 is equivalent to carry XOR overflow + jq nc, .nocarry + ret po +; jq .return + virtual + jr nc, $ + load .jr_nc : byte from $$ + end virtual + db .jr_nc +.nocarry: + ret pe +.return: + jq __fpmin.return + + extern __fpcmpo diff --git a/src/crt/fpmul.src b/src/crt/fpmul.src new file mode 100644 index 000000000..4949326eb --- /dev/null +++ b/src/crt/fpmul.src @@ -0,0 +1,180 @@ + assume adl=1 + + section .text + + public __fpmul + +; IEEE single precision multiplication +; aubc = aubc * euhl +__fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(float, pair8_24_t, { in.BC, in.A }) * bitcast(float, pair8_24_t, { in.HL, in.E })) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + push de, hl + xor a, e + push af + xor a, e + push bc + call __fppop1 + ex (sp), hl + ld d, e + ld e, a + call __fppop2 + inc e + jq z, .nonfinite.1 + inc d + jq z, .nonfinite.2 + ld a, d + ld d, b; 0 + rlc e + ccf + rr e + jq nc, .subtract + add a, e + jq nc, .continue +.overflow: + pop af, af, hl, de + or a, 07Fh + ret +.subtract: + add a, e + jq z, .subnormal + jq c, .continue + cp a, -23 + jq c, .underflow +.subnormal: + dec a + ld d, a +.continue: + push hl, ix + ld ix, -7 + add ix, sp + ld sp, ix + ld c, l + ld h, (ix + 13) + mlt hl + ld (ix + 0), l + ld l, h + ld h, 0 + ld b, (ix + 14) + mlt bc + add hl, bc + ld c, (ix + 11) + ld b, (ix + 13) + mlt bc + add.s hl, bc + ld (ix + 1), l + ld l, h + ld h, 0 + rl h + ld c, (ix + 10) + ld b, (ix + 15) + mlt bc + add hl, bc + ld c, (ix + 11) + ld b, (ix + 14) + mlt bc + add hl, bc + ld bc, (ix + 12) + mlt bc + add hl, bc + ld (ix + 2), hl + ld hl, (ix + 3) + inc hl + dec.s hl + ld c, (ix + 11) + ld b, (ix + 15) + mlt bc + add hl, bc + ld c, (ix + 12) + ld b, (ix + 14) + mlt bc + add hl, bc + ld (ix + 3), hl + ld hl, (ix + 4) + inc hl + dec.s hl + ld c, (ix + 12) + ld b, (ix + 15) + mlt bc + add hl, bc + cp a, d + jq nz, .normalized + ld bc, (ix + 2) + pop de +.normalize: + srl h + rr l + rr b + rr c + rr d + rr e + jq nc, .flushed + ld e, a +.flushed: + inc a + jq nz, .normalize + push de + ld (ix + 2), bc +.normalized: + ld (ix + 4), hl + ld c, (ix + 17) + pop ix, hl + inc sp + ld b, a + ld de, 0800000h + add a, -1 + call nc, __fppack2.normalized + call c, __fppack2 + pop ix, bc, bc, bc + ex (sp), hl + pop bc, de + ret +.underflow: + pop af, af, hl, de + and a, 080h + ld bc, 0 + ret +.nonfinite: + sbc hl, bc + jq z, .return.2 + add hl, bc + pop bc + jq .return.1 +.nonfinite.1: + inc d + jq z, .nonfinite + ex de, hl + pop hl + add hl, bc + or a, a + sbc hl, bc + ex de, hl + jq nz, .return.1 + ld h, a +.return.1: + pop af + ex (sp), hl + pop bc + jq .return +.nonfinite.2: + add hl, bc + or a, a + sbc hl, bc + jq z, .return.nan +.return.2: + pop bc, af, bc + push bc +.return.pop: + pop hl +.return: + pop de + or a, 07Fh + ret +.return.nan: + pop bc + set 7, b + pop af + jq .return.pop + + extern __fppop1 + extern __fppop2 + extern __fppack2.normalized + extern __fppack2 diff --git a/src/crt/fpneg.src b/src/crt/fpneg.src new file mode 100644 index 000000000..2e671f0fa --- /dev/null +++ b/src/crt/fpneg.src @@ -0,0 +1,11 @@ + assume adl=1 + + section .text + + public __fpneg + +; IEEE single precision negation +; aubc = -aubc +__fpneg: ; CHECK: bitcast(uint32_t, pair8_24_t, { out.BC, out.A }) == bitcast(uint32_t, float, -bitcast(float, pair8_24_t, { in.BC, in.A })) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + xor a, 080h + ret diff --git a/src/crt/fprem.src b/src/crt/fprem.src new file mode 100644 index 000000000..e343252a2 --- /dev/null +++ b/src/crt/fprem.src @@ -0,0 +1,79 @@ + assume adl=1 + + section .text + + public __fprem + +; IEEE single precision remainder +; aubc = fmod(aubc, euhl) +__fprem: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), fmodf(bitcast(float, pair8_24_t, { in.BC, in.A }), bitcast(float, pair8_24_t, { in.HL, in.E }))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + push de + ld d, a + set 7, a ; aubc = -abs(AUBC) + set 7, e ; euhl = -abs(EUHL) + call __fpcmpo ; abs(AUBC) <=> abs(EUHL) + jq m, .notge ; !(abs(AUBC) >= abs(EUHL)) + push hl, bc + call __fppop1 + ex (sp), hl + ld a, e + ld e, d + call __fppop2 + ld b, a + cpl + inc e + add a, e ; Always sets carry, unless dividend non-finite + ld e, d + ld d, b + pop bc + push de + ex de, hl + sbc hl, hl + add hl, bc + jq nc, .nan ; Return if dividend non-finite or divisor zero + sbc hl, hl + or a, a + sbc hl, bc + inc hl + ex de, hl + call m, __iremu ; If divisor subnormal, modulo the mantissas + ld b, a + inc b +.rem.compare: + add hl, de + jq c, .rem.norestore + sbc hl, de +.rem.norestore: + dec b + jq z, .rem.finish +.rem.loop: + add hl, hl + jq nc, .rem.compare + add hl, de + djnz .rem.loop +.rem.finish: + pop bc + rlc c + ld de, 0800000h + xor a, a + call __fppack + ex (sp), hl + pop bc, de + ret + +.nan: + pop hl, hl +.notge: + ld a, d + pop de + ret c ; abs(AUBC) < abs(EUHL) + ld bc, 0C00000h + ld a, 0FFh + ret + + extern __iremu + + extern __fppop1 + extern __fppop2 + extern __fppack + extern __fpcmpo diff --git a/src/crt/fpround.src b/src/crt/fpround.src new file mode 100644 index 000000000..665a9ec2b --- /dev/null +++ b/src/crt/fpround.src @@ -0,0 +1,61 @@ + assume adl=1 + + section .text + + public __fpround + +; IEEE single precision round +; aubc = round(aubc) +__fpround: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), roundf(bitcast(float, pair8_24_t, { in.BC, in.A }))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + push bc + ex (sp), hl + add hl, hl + ld h, a + rla + sub a, 07Fh - 1 + jq c, .return.zero + sub a, 24 + jq nc, .return + push bc + cpl + ld c, a + ld a, h + sbc hl, hl + call __ishl + ex de, hl + ex (sp), hl + or a, a + sbc hl, de + ex (sp), hl + ex de, hl + jq pe, .overflow + jq c, .no_overflow + inc a +; jq .overflow + virtual + jr c, $ + load .jr_c : byte from $$ + end virtual + db .jr_c +.no_overflow: + add hl, hl +.overflow: + pop bc + call __iand + push hl + pop bc + ld h, a +.return: + ld a, h + pop hl + ret + +.return.zero: + ld bc, 0 + ld a, h + and a, 080h + pop hl + ret + + extern __iand + extern __ishl diff --git a/src/crt/fpsqrt.src b/src/crt/fpsqrt.src new file mode 100644 index 000000000..7f2fb6c6f --- /dev/null +++ b/src/crt/fpsqrt.src @@ -0,0 +1,111 @@ + assume adl=1 + + section .text + + public __fpsqrt + +; IEEE single precision square root +; aubc = sqrt(aubc) +__fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sqrt(bitcast(float, pair8_24_t, { in.BC, in.A }))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + push de, bc + ex (sp), hl + ld e, a + call __fppop1 + add hl, bc + or a, a + sbc hl, bc + jq z, .zero + rlca + jq c, .nan + inc e + jq z, .nonfinite + push hl + ex (sp), ix + sbc hl, hl + srl e + jq nc, .normalize.skip +.normalize.loop: + add ix, ix + adc hl, hl +.normalize.skip: + dec e + add ix, ix + adc hl, hl + jq z, .normalize.loop + push de + xor a, a + ex de, hl + sbc hl, hl + ld c, a + ld b, 25 + ; x in AUDEUIX, r in CUHL +.root.loop: + ex de, hl + ; r += 1 + inc de ; sets bit 0 so never overflows + ; x -= r << 24 + sbc hl, de + sbc a, c + jq nc, .root.onebit + ; x += r << 24 + add hl, de + adc a, c + ; r -= 2 + dec de + dec de +.root.onebit: + ; r += 1 + inc de + ; x <<= 2 + repeat 2 + add ix, ix + adc hl, hl + rla + end repeat + ex de, hl + ; r <<= 1 + add hl, hl + rl c ; clears carry + djnz .root.loop + ; Shift left by 5 + ld a, c + repeat 5 + add hl, hl + rla + end repeat + ; Set the low exponent bit of the result + pop de, ix + sra e + rla + rrca + ; Shift right by 8 + push af + inc sp + push hl + inc sp + pop bc + inc sp + ; Calculate the high exponent bits and unset sign bit + ld a, e + add a, 07Fh / 4 + 1 + ; Check whether to round up (never round-to-even because a root with the lowest mantissa bit set must be irrational) + inc l + pop hl, de + ret p + inc bc ; This never overflows into the exponent field + ret + +.nonfinite: + rrca +.zero: + ex (sp), hl + pop bc, de + ret + +.nan: + sbc a, a + set 7, b + pop hl, de + ret + + extern __fppop1 diff --git a/src/crt/fptemp.src b/src/crt/fptemp.src new file mode 100644 index 000000000..f82a5e8cc --- /dev/null +++ b/src/crt/fptemp.src @@ -0,0 +1,33 @@ + assume adl=1 + +;------------------------------------------------------------------------------- + + section .text + + public __fptod +__fptod := __ftod + + extern __ftod + +;------------------------------------------------------------------------------- + + section .text + + public __dtofp +__dtofp := __dtof + + extern __dtof + +;------------------------------------------------------------------------------- + + section .text + + public __dcmpo + public __dcmpu + +__dcmpo := __dcmp +__dcmpu := __dcmp + + extern __dcmp + +;------------------------------------------------------------------------------- diff --git a/src/crt/fptol.src b/src/crt/fptol.src new file mode 100644 index 000000000..d0f5b73f8 --- /dev/null +++ b/src/crt/fptol.src @@ -0,0 +1,54 @@ + assume adl=1 + + section .text + + public __fptol + public __fptoul + +; IEEE single precision to 32-bit integers +; aubc = long(aubc) +__fptoul: ; PREREQ: bitcast(float, pair8_24_t, { in.BC, in.A }) > -1.0f && bitcast(float, pair8_24_t, { in.BC, in.A }) < (UINT32_MAX/2+1)*2.0f CHECK: bitcast(uint32_t, pair8_24_t, { out.BC, out.A }) == (uint32_t)bitcast(float, pair8_24_t, { in.BC, in.A }) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY +__fptol: ; PREREQ: bitcast(float, pair8_24_t, { in.BC, in.A })-INT32_MIN > -1.0f && bitcast(float, pair8_24_t, { in.BC, in.A }) < (INT32_MAX/2+1)*2.0f CHECK: bitcast(int32_t, pair8_24_t, { out.BC, out.A }) == (int32_t)bitcast(float, pair8_24_t, { in.BC, in.A }) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + push de, bc + ex (sp), hl + ld d, a + ld e, a + call __fppop1 + ld a, e + sub a, 07Fh + cp a, 23 + 32 + jq nc, .return.zero + sub a, 23 + 1 + jq nc, .left + cpl + ld c, a + call __ishru + xor a, a + jq .finish +.left: + inc a + ld b, a + xor a, a +.loop: + add hl, hl + rla + djnz .loop +.finish: + ld e, a + bit 7, d + call nz, __lneg + ld a, e +.return: + ex (sp), hl + pop bc, de + ret + +.return.zero: + xor a, a + sbc hl, hl + jq .return + + extern __ishru + extern __lneg + + extern __fppop1 diff --git a/src/crt/fptoll.src b/src/crt/fptoll.src new file mode 100644 index 000000000..e3281d5b8 --- /dev/null +++ b/src/crt/fptoll.src @@ -0,0 +1,48 @@ + assume adl=1 + + section .text + + public __fptoll + public __fptoull + +; IEEE single precision to 64-bit integers +; bcudeuhl = longlong(euhl) +__fptoull: ; PREREQ: bitcast(float, pair8_24_t, { in.HL, in.E }) > -1.0f && bitcast(float, pair8_24_t, { in.HL, in.E }) < (UINT64_MAX/2+1)*2.0f CHECK: bitcast(uint64_t, tuple16_24_24_t, { out.HL, out.DE, out.BCS }) == (uint64_t)bitcast(float, pair8_24_t, { in.HL, in.E }) && out.A == in.A && out.IX == in.IX && out.IY == in.IY +__fptoll: ; PREREQ: bitcast(float, pair8_24_t, { in.HL, in.E })-INT64_MIN > -1.0f && bitcast(float, pair8_24_t, { in.HL, in.E }) < (INT64_MAX/2+1)*2.0f CHECK: bitcast(int64_t, tuple16_24_24_t, { out.HL, out.DE, out.BCS }) == (int64_t)bitcast(float, pair8_24_t, { in.HL, in.E }) && out.A == in.A && out.IX == in.IX && out.IY == in.IY + ld d, a + push de + call __fppop1 + ld a, e + ld de, 0 + sub a, 07Fh + cp a, 23 + 64 + jq nc, .return.zero + sub a, 23 + 1 + jq nc, .left + cpl + ld c, a + call __ishru + ld c, b + jq .finish +.left: + inc a + push af + inc sp + call __llshl + inc sp + inc sp +.finish: + pop af + ret p + jq __llneg + +.return.zero: + sbc hl, hl + pop af + ret + + extern __ishru + extern __llshl + extern __llneg + + extern __fppop1 diff --git a/src/crt/fptrunc.src b/src/crt/fptrunc.src new file mode 100644 index 000000000..d1bee098e --- /dev/null +++ b/src/crt/fptrunc.src @@ -0,0 +1,119 @@ + assume adl=1 + +;------------------------------------------------------------------------------- + + section .text + + public __fpfloor + +; IEEE single precision floor +; aubc = floor(aubc) +__fpfloor: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), floorf(bitcast(float, pair8_24_t, { in.BC, in.A }))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + cp a, 080h + jq c, __fptrunc + + private __fpfloor.roundup + +__fpfloor.roundup: + push bc + ex (sp), hl + adc hl, hl + ld h, a + rla + jq z, .mantissa.zero + sub a, 07Fh + jq c, .return.one + sub a, 24 + jq nc, .return + push bc + cpl + ld c, a + ld a, h + sbc hl, hl + call __ishl + ex (sp), hl + pop bc + dec hl + call __iand + or a, a + sbc hl, bc + sbc a, -1 + push hl + pop bc + ld h, a +.return: + ld a, h + pop hl + ret + +.mantissa.zero: + dec a + cp a, 07Fh - 1 + jq nc, .return +.return.one: + ld bc, 0800000h + ld a, h + or a, 07Fh shr 1 + pop hl + ret + +;------------------------------------------------------------------------------- + + section .text + + public __fpceil + +; IEEE single precision ceiling +; aubc = ceil(aubc) +__fpceil: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), ceilf(bitcast(float, pair8_24_t, { in.BC, in.A }))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + rlca + rrca + jq nc, __fpfloor.roundup + + require __fptrunc + +;------------------------------------------------------------------------------- + + section .text + + public __fptrunc + +; IEEE single precision truncation +; aubc = trunc(aubc) +__fptrunc: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), truncf(bitcast(float, pair8_24_t, { in.BC, in.A }))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + push bc + ex (sp), hl + add hl, hl + ld h, a + rla + sub a, 07Fh + jq c, .return.zero + sub a, 24 + jq nc, .return + ld l, c + cpl + ld c, a + ld a, l + push hl + sbc hl, hl + call __ishl + ld c, a + call __iand + ex (sp), hl + pop bc +.return: + ld a, h + pop hl + ret + +.return.zero: + ld bc, 0 + ld a, h + and a, 080h + pop hl + ret + +;------------------------------------------------------------------------------- + + extern __iand + extern __ishl diff --git a/src/crt/fputil.src b/src/crt/fputil.src new file mode 100644 index 000000000..8f8f9da96 --- /dev/null +++ b/src/crt/fputil.src @@ -0,0 +1,119 @@ + assume adl=1 + +;------------------------------------------------------------------------------- + + section .text + + public __fppop1 + public __fppop2 + +__fppop1: + ld bc, 0800000h +__fppop2: + sla e + jq z, .denormal + add hl, bc + ret nc + add hl, bc +.denormal: + inc e + ret + +;------------------------------------------------------------------------------- + + section .text + + public __fppack + public __fppack.normalize + public __fppack.normalized + +__fppack.normalize: + dec b + call nz, .entry +__fppack: + add hl, de + jq nc, .normalize +.normalized: + rrc l + rlc l + adc a, 07Fh + adc hl, de + ld a, b + adc a, e + srl c + rra + srl b + ret c + add hl, de + ret + +.normalize.entry: + add a, a + adc hl, hl + ret m + jq nz, .normalize.continue + or a, a + jq nz, .normalize.continue + ld b, 1 +.normalize.loop: + add a, a + adc hl, hl + ret m +.normalize.continue: + djnz .normalize.loop + add hl, de + ret + +;------------------------------------------------------------------------------- + + section .text + + public __fppack2 + public __fppack2.normalize + public __fppack2.normalized + +__fppack2.normalize: + dec b + call nz, .loop +__fppack2: + add hl, de + jq nc, .normalize +.normalized: + ld a, b + add ix, de + jq nc, .rounded + dec ix + add ix, de + jq nc, .round + bit 0, l + jq z, .rounded +.round: + scf + adc hl, de + adc a, e +.clear: + add hl, de + jq nc, .clear +.rounded: + cp a, 0FFh + jq z, .infinite + sla c + rra + ret nc + add hl, de + ret +.infinite: + sla c + rra + ex de, hl + ret + +.normalize.loop: + add ix, ix + adc hl, hl + ret m + djnz .normalize.loop + add hl, de + ret + +;------------------------------------------------------------------------------- diff --git a/src/crt/lltofp.src b/src/crt/lltofp.src new file mode 100644 index 000000000..570579460 --- /dev/null +++ b/src/crt/lltofp.src @@ -0,0 +1,71 @@ + assume adl=1 + +;------------------------------------------------------------------------------- + + section .text + + public __lltofp + +; IEEE single precision from 64-bit integers +; euhl = float(bcudeuhl) +__lltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)bitcast(int64_t, tuple16_24_24_t, { in.HL, in.DE, in.BCS })) && out.A == in.A && out.BC == in.BC && out.IX == in.IX && out.IY == in.IY + push af, bc + ld a, b + or a, a + call m, __llneg + jq __ulltofp.enter + +;------------------------------------------------------------------------------- + + section .text + + public __ulltofp + +__ulltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)bitcast(uint64_t, tuple16_24_24_t, { in.HL, in.DE, in.BCS })) && out.A == in.A && out.BC == in.BC && out.IX == in.IX && out.IY == in.IY + push af, bc + xor a, a +.enter: + inc b + djnz .upper + inc c + dec c + jq z, .lower +.upper: + push bc + push de + push hl + ld c, a + ld a, l + or a, h + inc sp + inc sp + pop hl + pop de + inc sp + or a, l + ld l, a + ld b, 07Fh + 63 +; jq .pack + virtual + jp c, $ + load .jp_c : byte from $$ + end virtual + db .jp_c +.lower: + ld c, a + ld b, 07Fh + 47 +.pack: + ex de, hl + push de + ex (sp), ix + ld de, 0800000h + call __fppack2 + ld e, a + pop ix, bc, af + ret + +;------------------------------------------------------------------------------- + + extern __llneg + + extern __fppack2 diff --git a/src/crt/ltofp.src b/src/crt/ltofp.src new file mode 100644 index 000000000..6048adefe --- /dev/null +++ b/src/crt/ltofp.src @@ -0,0 +1,58 @@ + assume adl=1 + +;------------------------------------------------------------------------------- + + section .text + + public __ultofp + +; IEEE single precision from 32-bit integers +; aubc = float(aubc) +__ultofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)bitcast(uint32_t, pair8_24_t, { in.BC, in.A })) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + push af + xor a, a +; jq __ltofp.enter + virtual + jr c, $ + load .jr_c : byte from $$ + end virtual + db .jr_c + + require __ltofp + +;------------------------------------------------------------------------------- + + section .text + + public __ltofp + +__ltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)bitcast(int32_t, pair8_24_t, { in.BC, in.A })) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY + push af +.enter: + rlca + inc sp + push bc + inc sp + ex (sp), hl + ld b, c + ld c, a + ld a, b + push de + jq nc, .positive + add hl, de + ex de, hl + neg + sbc hl, de +.positive: + ld de, 0800000h + ld b, 07Fh + 31 + call __fppack + pop de + ex (sp), hl + pop bc + inc sp + ret + +;------------------------------------------------------------------------------- + + extern __fppack diff --git a/src/libc/sqrtf.c b/src/libc/sqrtf.c index 0aa9b45b0..72f437a30 100644 --- a/src/libc/sqrtf.c +++ b/src/libc/sqrtf.c @@ -25,7 +25,7 @@ asm push de, hl, bc ret */ -float _f32_fast_div4(float x); +float _f32_fast_div4(float x) __attribute__((__const__, __leaf__, __nothrow__)); /** * @remarks Minimum ulp of -1 diff --git a/test/floating_point/ez80sf/autotest.json b/test/floating_point/ez80sf/autotest.json new file mode 100644 index 000000000..6dfa8370d --- /dev/null +++ b/test/floating_point/ez80sf/autotest.json @@ -0,0 +1,43 @@ +{ + "transfer_files": [ + "bin/DEMO.8xp" + ], + "target": { + "name": "DEMO", + "isASM": true + }, + "sequence": [ + "action|launch", + "delay|4000", + "hashWait|1", + "key|enter", + "delay|400", + "hashWait|2" + ], + "hashes": { + "1": { + "description": "All tests passed or GDB1 error", + "timeout": 6000, + "start": "vram_start", + "size": "vram_16_size", + "expected_CRCs": [ + "38E2AD5A", + "2C812DC2" + ] + }, + "2": { + "description": "Exit or GDB1 error", + "start": "vram_start", + "size": "vram_16_size", + "expected_CRCs": [ + "FFAF89BA", + "101734A5", + "9DA19F44", + "A32840C8", + "349F4775", + "271A9FBF", + "82FD0B1E" + ] + } + } +} diff --git a/test/floating_point/ez80sf/makefile b/test/floating_point/ez80sf/makefile new file mode 100644 index 000000000..3665be2f9 --- /dev/null +++ b/test/floating_point/ez80sf/makefile @@ -0,0 +1,20 @@ +# ---------------------------- +# Makefile Options +# ---------------------------- + +NAME = DEMO +ICON = icon.png +DESCRIPTION = "CE C Toolchain Demo" +COMPRESSED = NO + +COMMON_FLAGS = -Wall -Wextra -Wshadow -Wformat=2 -Wconversion -Wimplicit-float-conversion -Wimplicit-int-float-conversion +COMMON_FLAGS += -Oz -ffreestanding + +CFLAGS = ${COMMON_FLAGS} -std=c17 +CXXFLAGS = ${COMMON_FLAGS} -std=c++20 + +PREFER_OS_LIBC = NO + +# ---------------------------- + +include $(shell cedev-config --makefile) diff --git a/test/floating_point/ez80sf/src/link_test.s b/test/floating_point/ez80sf/src/link_test.s new file mode 100644 index 000000000..c3a17d2d9 --- /dev/null +++ b/test/floating_point/ez80sf/src/link_test.s @@ -0,0 +1,92 @@ + assume adl=1 + +;------------------------------------------------------------------------------- + + section .text + + public _link_test + +_link_test: + ld hl, __fpabs + ld hl, __fpsub + ld hl, __fpadd + ld hl, __fpcbrt + ld hl, __fpcmpu + ld hl, __fpcmpo + ld hl, __fpcmp + ld hl, __fpcopysign + ld hl, __fpcopy + ld hl, __fpdiv + ld hl, __fpmin + ld hl, __fpmax + ld hl, __fpmul + ld hl, __fpneg + ld hl, __fprem + ld hl, __fpround + ld hl, __fpsqrt + ld hl, __fptol + ld hl, __fptoul + ld hl, __fptoll + ld hl, __fptoull + ld hl, __fpfloor + ld hl, __fpceil + ld hl, __fptrunc + ld hl, __fppop1 + ld hl, __fppop2 + ld hl, __fppack + ld hl, __fppack.normalize + ld hl, __fppack.normalized + ld hl, __fppack2 + ld hl, __fppack2.normalize + ld hl, __fppack2.normalized + ld hl, __ltofp + ld hl, __ultofp + ld hl, __lltofp + ld hl, __ulltofp + + ; ld hl, __fptod + ; ld hl, __dtofp + + or a, a + sbc hl, hl + ret + + extern __fpabs + extern __fpsub + extern __fpadd + extern __fpcbrt + extern __fpcmpu + extern __fpcmpo + extern __fpcmp + extern __fpcopysign + extern __fpcopy + extern __fpdiv + extern __fpmin + extern __fpmax + extern __fpmul + extern __fpneg + extern __fprem + extern __fpround + extern __fpsqrt + extern __fptol + extern __fptoul + extern __fptoll + extern __fptoull + extern __fpfloor + extern __fpceil + extern __fptrunc + extern __fppop1 + extern __fppop2 + extern __fppack + extern __fppack.normalize + extern __fppack.normalized + extern __fppack2 + extern __fppack2.normalize + extern __fppack2.normalized + extern __ltofp + extern __ultofp + extern __lltofp + extern __ulltofp + + extern __fptod + extern __dtofp diff --git a/test/floating_point/ez80sf/src/main.c b/test/floating_point/ez80sf/src/main.c new file mode 100644 index 000000000..59c49451b --- /dev/null +++ b/test/floating_point/ez80sf/src/main.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//------------------------------------------------------------------------------ +// Config +//------------------------------------------------------------------------------ + +// define to 0 or 1 +#define DEBUG_DIAGNOSTICS 0 + +//------------------------------------------------------------------------------ +// Utility +//------------------------------------------------------------------------------ + +#define C(expr) if (!(expr)) { return __LINE__; } + +#define TEST(test) { ret = test; if (ret != 0) { return ret; }} + +#ifndef DEBUG_DIAGNOSTICS +#error "DEBUG_DIAGNOSTICS needs to be defined to 0 or 1" +#endif + +#if DEBUG_DIAGNOSTICS +#define test_printf printf +#else +#define test_printf(...) +#endif + +//------------------------------------------------------------------------------ +// Tests +//------------------------------------------------------------------------------ + +int link_test(void); + +int run_tests(void) { + int ret = 0; + + TEST(link_test()); + + /* passed all */ + return ret; +} + +int main(void) { + os_ClrHome(); + int failed_test = run_tests(); + if (failed_test != 0) { + char buf[sizeof("Failed test L-8388608\n")]; + boot_sprintf(buf, "Failed test L%d\n", failed_test); + fputs(buf, stdout); + } else { + fputs("All tests passed", stdout); + } + + while (!os_GetCSC()); + + return 0; +} From 1ef5e0b5ecf87304db8f7a0c25149cac7b1594b7 Mon Sep 17 00:00:00 2001 From: zerico <71151164+ZERICO2005@users.noreply.github.com> Date: Wed, 4 Feb 2026 14:56:27 -0700 Subject: [PATCH 02/13] trivial ez80sf to GAS conversions --- src/crt/dabs.src | 7 +- src/crt/fpabs.src | 7 +- src/crt/fpaddsub.src | 26 +++---- src/crt/fpcbrt.src | 25 +++---- src/crt/fpcmp.src | 17 +++-- src/crt/fpcopysign.src | 12 ++-- src/crt/fpdiv.src | 11 +-- src/crt/fpminmax.src | 12 ++-- src/crt/fpmul.src | 15 ++-- src/crt/fpneg.src | 7 +- src/crt/fprem.src | 17 ++--- src/crt/fpround.src | 11 +-- src/crt/fpsqrt.src | 17 ++--- src/crt/fptemp.src | 26 ++++--- src/crt/fptol.src | 16 +++-- src/crt/fptoll.src | 18 ++--- src/crt/fptrunc.src | 23 +++--- src/crt/fputil.src | 32 +++++---- src/crt/lltofp.src | 16 +++-- src/crt/ltofp.src | 14 ++-- test/floating_point/ez80sf/src/link_test.s | 82 +++++++++++----------- 21 files changed, 226 insertions(+), 185 deletions(-) diff --git a/src/crt/dabs.src b/src/crt/dabs.src index ec1d7ec4d..61b14e863 100644 --- a/src/crt/dabs.src +++ b/src/crt/dabs.src @@ -1,8 +1,9 @@ - assume adl=1 + .assume adl=1 - section .text + .section .text - public __dabs + .global __dabs + .type __dabs, @function ; assumes BC:UDE:UHL __dabs: diff --git a/src/crt/fpabs.src b/src/crt/fpabs.src index c3ef733fd..ee467f4fb 100644 --- a/src/crt/fpabs.src +++ b/src/crt/fpabs.src @@ -1,8 +1,9 @@ - assume adl=1 + .assume adl=1 - section .text + .section .text - public __fpabs + .global __fpabs + .type __fpabs, @function ; IEEE single precision absolute value ; aubc = |aubc| diff --git a/src/crt/fpaddsub.src b/src/crt/fpaddsub.src index 0b42a55b0..816281800 100644 --- a/src/crt/fpaddsub.src +++ b/src/crt/fpaddsub.src @@ -1,10 +1,11 @@ - assume adl=1 + .assume adl=1 ;------------------------------------------------------------------------------- - section .text + .section .text - public __fpsub + .global __fpsub + .type __fpsub, @function ; IEEE single precision subtraction ; aubc = aubc - euhl @@ -24,9 +25,10 @@ __fpsub: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ;------------------------------------------------------------------------------- - section .text + .section .text - public __fpadd + .global __fpadd + .type __fpadd, @function ; IEEE single precision addition ; aubc = aubc + euhl @@ -72,17 +74,17 @@ __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl .noshift1: srl b jq c, .noshift2 - repeat 2 + .rept 2 add hl, hl rla - end repeat + .endr .noshift2: srl b jq c, .noshift4 - repeat 4 + .rept 4 add hl, hl rla - end repeat + .endr .noshift4: ; Shift right by (amount + 7) / 8 * 8, truncating to 24 bits ; The last 2 bits shifted out are in A, while any remaining non-zero @@ -226,6 +228,6 @@ __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ;------------------------------------------------------------------------------- - extern __fppop1 - extern __fppop2 - extern __fppack + .extern __fppop1 + .extern __fppop2 + .extern __fppack diff --git a/src/crt/fpcbrt.src b/src/crt/fpcbrt.src index 5f559d10c..53d382b7c 100644 --- a/src/crt/fpcbrt.src +++ b/src/crt/fpcbrt.src @@ -1,8 +1,9 @@ - assume adl=1 + .assume adl=1 - section .text + .section .text - public __fpcbrt + .global __fpcbrt + .type __fpcbrt, @function ; IEEE single precision cube root ; aubc = cbrt(aubc) @@ -72,10 +73,10 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb add hl, bc rla inc bc - repeat 3 + .rept 3 add hl, bc adc a, 0 - end repeat + .endr ; r <<= 2 add hl, hl rla @@ -116,10 +117,10 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb sbc a, a ; Left shift high 32 bits of r by 2 ex de, hl - repeat 2 + .rept 2 add hl, hl rl c - end repeat + .endr ; Add carry byte to shifted high bits add hl, de ex de, hl @@ -129,17 +130,17 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb exx ; x <<= 3 xor a, a - repeat 3 + .rept 3 add ix, ix adc hl, hl rla - end repeat + .endr exx ex af, af' - repeat 3 + .rept 3 add hl, hl rla - end repeat + .endr ex af, af' or a, l ld l, a @@ -182,4 +183,4 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb ei ret - extern __fppop1 + .extern __fppop1 diff --git a/src/crt/fpcmp.src b/src/crt/fpcmp.src index 0eada9d8e..c5fbf7675 100644 --- a/src/crt/fpcmp.src +++ b/src/crt/fpcmp.src @@ -1,10 +1,11 @@ - assume adl=1 + .assume adl=1 ;------------------------------------------------------------------------------- - section .text + .section .text - public __fpcmpu + .global __fpcmpu + .type __fpcmpu, @function ; IEEE single precision unordered comparison ; z = euhl == aubc || isunordered(euhl, aubc) @@ -19,9 +20,10 @@ __fpcmpu: ; CHECK: out.flags.C == !isunordered(bitcast(float, pair8_24_t, { in.H ;------------------------------------------------------------------------------- - section .text + .section .text - public __fpcmpo + .global __fpcmpo + .type __fpcmpo, @function ; IEEE single precision ordered comparison ; z = euhl == aubc @@ -145,9 +147,10 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = ;------------------------------------------------------------------------------- - section .text + .section .text - public __fpcmp + .global __fpcmp + .type __fpcmp, @function ; IEEE single precision comparison (flag outputs for NaN inputs are undefined) ; z = euhl == aubc diff --git a/src/crt/fpcopysign.src b/src/crt/fpcopysign.src index 5b94f9d66..fd59a550c 100644 --- a/src/crt/fpcopysign.src +++ b/src/crt/fpcopysign.src @@ -1,10 +1,11 @@ - assume adl=1 + .assume adl=1 ;------------------------------------------------------------------------------- - section .text + .section .text - public __fpcopysign + .global __fpcopysign + .type __fpcopysign, @function ; IEEE single precision copy sign ; aubc = copysign(aubc, euhl) @@ -16,9 +17,10 @@ __fpcopysign: ; CHECK: bitcast(uint32_t, pair8_24_t, { out.BC, out.A }) == bitca ;------------------------------------------------------------------------------- - section .text + .section .text - public __fpcopy + .global __fpcopy + .type __fpcopy, @function ; IEEE single precision copy ; aubc = copy(aubc) diff --git a/src/crt/fpdiv.src b/src/crt/fpdiv.src index b9b2cf53e..e2f941bee 100644 --- a/src/crt/fpdiv.src +++ b/src/crt/fpdiv.src @@ -1,8 +1,9 @@ - assume adl=1 + .assume adl=1 - section .text + .section .text - public __fpdiv + .global __fpdiv + .type __fpdiv, @function ; IEEE single precision division ; aubc = aubc / euhl @@ -160,5 +161,5 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl pop bc, de ret - extern __fppop1 - extern __fppop2 + .extern __fppop1 + .extern __fppop2 diff --git a/src/crt/fpminmax.src b/src/crt/fpminmax.src index 692f58054..ae77d77e9 100644 --- a/src/crt/fpminmax.src +++ b/src/crt/fpminmax.src @@ -1,9 +1,11 @@ - assume adl=1 + .assume adl=1 - section .text + .section .text - public __fpmin - public __fpmax + .global __fpmin + .type __fpmin, @function + .global __fpmax + .type __fpmax, @function ; IEEE single precision minimum ; aubc = fmin(aubc, euhl) @@ -45,4 +47,4 @@ __fpmax: ; CHECK: sameignzerosign(bitcast(float, pair8_24_t, { out.BC, out.A }), .return: jq __fpmin.return - extern __fpcmpo + .extern __fpcmpo diff --git a/src/crt/fpmul.src b/src/crt/fpmul.src index 4949326eb..8863d4733 100644 --- a/src/crt/fpmul.src +++ b/src/crt/fpmul.src @@ -1,8 +1,9 @@ - assume adl=1 + .assume adl=1 - section .text + .section .text - public __fpmul + .global __fpmul + .type __fpmul, @function ; IEEE single precision multiplication ; aubc = aubc * euhl @@ -174,7 +175,7 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl pop af jq .return.pop - extern __fppop1 - extern __fppop2 - extern __fppack2.normalized - extern __fppack2 + .extern __fppop1 + .extern __fppop2 + .extern __fppack2.normalized + .extern __fppack2 diff --git a/src/crt/fpneg.src b/src/crt/fpneg.src index 2e671f0fa..29561bf97 100644 --- a/src/crt/fpneg.src +++ b/src/crt/fpneg.src @@ -1,8 +1,9 @@ - assume adl=1 + .assume adl=1 - section .text + .section .text - public __fpneg + .global __fpneg + .type __fpneg, @function ; IEEE single precision negation ; aubc = -aubc diff --git a/src/crt/fprem.src b/src/crt/fprem.src index e343252a2..ce4765b4e 100644 --- a/src/crt/fprem.src +++ b/src/crt/fprem.src @@ -1,8 +1,9 @@ - assume adl=1 + .assume adl=1 - section .text + .section .text - public __fprem + .global __fprem + .type __fprem, @function ; IEEE single precision remainder ; aubc = fmod(aubc, euhl) @@ -71,9 +72,9 @@ __fprem: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), fmodf(bitc ld a, 0FFh ret - extern __iremu + .extern __iremu - extern __fppop1 - extern __fppop2 - extern __fppack - extern __fpcmpo + .extern __fppop1 + .extern __fppop2 + .extern __fppack + .extern __fpcmpo diff --git a/src/crt/fpround.src b/src/crt/fpround.src index 665a9ec2b..c6ec1b72c 100644 --- a/src/crt/fpround.src +++ b/src/crt/fpround.src @@ -1,8 +1,9 @@ - assume adl=1 + .assume adl=1 - section .text + .section .text - public __fpround + .global __fpround + .type __fpround, @function ; IEEE single precision round ; aubc = round(aubc) @@ -57,5 +58,5 @@ __fpround: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), roundf(b pop hl ret - extern __iand - extern __ishl + .extern __iand + .extern __ishl diff --git a/src/crt/fpsqrt.src b/src/crt/fpsqrt.src index 7f2fb6c6f..f788c9ca3 100644 --- a/src/crt/fpsqrt.src +++ b/src/crt/fpsqrt.src @@ -1,8 +1,9 @@ - assume adl=1 + .assume adl=1 - section .text + .section .text - public __fpsqrt + .global __fpsqrt + .type __fpsqrt, @function ; IEEE single precision square root ; aubc = sqrt(aubc) @@ -57,11 +58,11 @@ __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sq ; r += 1 inc de ; x <<= 2 - repeat 2 + .rept 2 add ix, ix adc hl, hl rla - end repeat + .endr ex de, hl ; r <<= 1 add hl, hl @@ -69,10 +70,10 @@ __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sq djnz .root.loop ; Shift left by 5 ld a, c - repeat 5 + .rept 5 add hl, hl rla - end repeat + .endr ; Set the low exponent bit of the result pop de, ix sra e @@ -108,4 +109,4 @@ __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sq pop hl, de ret - extern __fppop1 + .extern __fppop1 diff --git a/src/crt/fptemp.src b/src/crt/fptemp.src index f82a5e8cc..8a1e949ef 100644 --- a/src/crt/fptemp.src +++ b/src/crt/fptemp.src @@ -1,33 +1,37 @@ - assume adl=1 + .assume adl=1 ;------------------------------------------------------------------------------- - section .text + .section .text - public __fptod + .global __fptod + .type __fptod, @function __fptod := __ftod - extern __ftod + .extern __ftod ;------------------------------------------------------------------------------- - section .text + .section .text - public __dtofp + .global __dtofp + .type __dtofp, @function __dtofp := __dtof - extern __dtof + .extern __dtof ;------------------------------------------------------------------------------- - section .text + .section .text - public __dcmpo - public __dcmpu + .global __dcmpo + .type __dcmpo, @function + .global __dcmpu + .type __dcmpu, @function __dcmpo := __dcmp __dcmpu := __dcmp - extern __dcmp + .extern __dcmp ;------------------------------------------------------------------------------- diff --git a/src/crt/fptol.src b/src/crt/fptol.src index d0f5b73f8..667aa04a2 100644 --- a/src/crt/fptol.src +++ b/src/crt/fptol.src @@ -1,9 +1,11 @@ - assume adl=1 + .assume adl=1 - section .text + .section .text - public __fptol - public __fptoul + .global __fptol + .type __fptol, @function + .global __fptoul + .type __fptoul, @function ; IEEE single precision to 32-bit integers ; aubc = long(aubc) @@ -48,7 +50,7 @@ __fptol: ; PREREQ: bitcast(float, pair8_24_t, { in.BC, in.A })-INT32_MIN > -1.0f sbc hl, hl jq .return - extern __ishru - extern __lneg + .extern __ishru + .extern __lneg - extern __fppop1 + .extern __fppop1 diff --git a/src/crt/fptoll.src b/src/crt/fptoll.src index e3281d5b8..6281c47c7 100644 --- a/src/crt/fptoll.src +++ b/src/crt/fptoll.src @@ -1,9 +1,11 @@ - assume adl=1 + .assume adl=1 - section .text + .section .text - public __fptoll - public __fptoull + .global __fptoll + .type __fptoll, @function + .global __fptoull + .type __fptoull, @function ; IEEE single precision to 64-bit integers ; bcudeuhl = longlong(euhl) @@ -41,8 +43,8 @@ __fptoll: ; PREREQ: bitcast(float, pair8_24_t, { in.HL, in.E })-INT64_MIN > -1.0 pop af ret - extern __ishru - extern __llshl - extern __llneg + .extern __ishru + .extern __llshl + .extern __llneg - extern __fppop1 + .extern __fppop1 diff --git a/src/crt/fptrunc.src b/src/crt/fptrunc.src index d1bee098e..efbb0be9f 100644 --- a/src/crt/fptrunc.src +++ b/src/crt/fptrunc.src @@ -1,10 +1,11 @@ - assume adl=1 + .assume adl=1 ;------------------------------------------------------------------------------- - section .text + .section .text - public __fpfloor + .global __fpfloor + .type __fpfloor, @function ; IEEE single precision floor ; aubc = floor(aubc) @@ -12,7 +13,7 @@ __fpfloor: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), floorf(b cp a, 080h jq c, __fptrunc - private __fpfloor.roundup + .local __fpfloor.roundup __fpfloor.roundup: push bc @@ -59,9 +60,10 @@ __fpfloor.roundup: ;------------------------------------------------------------------------------- - section .text + .section .text - public __fpceil + .global __fpceil + .type __fpceil, @function ; IEEE single precision ceiling ; aubc = ceil(aubc) @@ -74,9 +76,10 @@ __fpceil: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), ceilf(bit ;------------------------------------------------------------------------------- - section .text + .section .text - public __fptrunc + .global __fptrunc + .type __fptrunc, @function ; IEEE single precision truncation ; aubc = trunc(aubc) @@ -115,5 +118,5 @@ __fptrunc: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), truncf(b ;------------------------------------------------------------------------------- - extern __iand - extern __ishl + .extern __iand + .extern __ishl diff --git a/src/crt/fputil.src b/src/crt/fputil.src index 8f8f9da96..855ba5c5d 100644 --- a/src/crt/fputil.src +++ b/src/crt/fputil.src @@ -1,11 +1,13 @@ - assume adl=1 + .assume adl=1 ;------------------------------------------------------------------------------- - section .text + .section .text - public __fppop1 - public __fppop2 + .global __fppop1 + .type __fppop1, @function + .global __fppop2 + .type __fppop2, @function __fppop1: ld bc, 0800000h @@ -21,11 +23,14 @@ __fppop2: ;------------------------------------------------------------------------------- - section .text + .section .text - public __fppack - public __fppack.normalize - public __fppack.normalized + .global __fppack + .type __fppack, @function + .global __fppack.normalize + .type __fppack.normalize, @function + .global __fppack.normalized + .type __fppack.normalized, @function __fppack.normalize: dec b @@ -66,11 +71,14 @@ __fppack: ;------------------------------------------------------------------------------- - section .text + .section .text - public __fppack2 - public __fppack2.normalize - public __fppack2.normalized + .global __fppack2 + .type __fppack2, @function + .global __fppack2.normalize + .type __fppack2.normalize, @function + .global __fppack2.normalized + .type __fppack2.normalized, @function __fppack2.normalize: dec b diff --git a/src/crt/lltofp.src b/src/crt/lltofp.src index 570579460..a1fc4d114 100644 --- a/src/crt/lltofp.src +++ b/src/crt/lltofp.src @@ -1,10 +1,11 @@ - assume adl=1 + .assume adl=1 ;------------------------------------------------------------------------------- - section .text + .section .text - public __lltofp + .global __lltofp + .type __lltofp, @function ; IEEE single precision from 64-bit integers ; euhl = float(bcudeuhl) @@ -17,9 +18,10 @@ __lltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)bi ;------------------------------------------------------------------------------- - section .text + .section .text - public __ulltofp + .global __ulltofp + .type __ulltofp, @function __ulltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)bitcast(uint64_t, tuple16_24_24_t, { in.HL, in.DE, in.BCS })) && out.A == in.A && out.BC == in.BC && out.IX == in.IX && out.IY == in.IY push af, bc @@ -66,6 +68,6 @@ __ulltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)b ;------------------------------------------------------------------------------- - extern __llneg + .extern __llneg - extern __fppack2 + .extern __fppack2 diff --git a/src/crt/ltofp.src b/src/crt/ltofp.src index 6048adefe..d883fe367 100644 --- a/src/crt/ltofp.src +++ b/src/crt/ltofp.src @@ -1,10 +1,11 @@ - assume adl=1 + .assume adl=1 ;------------------------------------------------------------------------------- - section .text + .section .text - public __ultofp + .global __ultofp + .type __ultofp, @function ; IEEE single precision from 32-bit integers ; aubc = float(aubc) @@ -22,9 +23,10 @@ __ultofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)bi ;------------------------------------------------------------------------------- - section .text + .section .text - public __ltofp + .global __ltofp + .type __ltofp, @function __ltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)bitcast(int32_t, pair8_24_t, { in.BC, in.A })) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY push af @@ -55,4 +57,4 @@ __ltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)bit ;------------------------------------------------------------------------------- - extern __fppack + .extern __fppack diff --git a/test/floating_point/ez80sf/src/link_test.s b/test/floating_point/ez80sf/src/link_test.s index c3a17d2d9..cc7326799 100644 --- a/test/floating_point/ez80sf/src/link_test.s +++ b/test/floating_point/ez80sf/src/link_test.s @@ -1,10 +1,10 @@ - assume adl=1 + .assume adl=1 ;------------------------------------------------------------------------------- - section .text + .section .text - public _link_test + .global _link_test _link_test: ld hl, __fpabs @@ -51,42 +51,42 @@ _link_test: sbc hl, hl ret - extern __fpabs - extern __fpsub - extern __fpadd - extern __fpcbrt - extern __fpcmpu - extern __fpcmpo - extern __fpcmp - extern __fpcopysign - extern __fpcopy - extern __fpdiv - extern __fpmin - extern __fpmax - extern __fpmul - extern __fpneg - extern __fprem - extern __fpround - extern __fpsqrt - extern __fptol - extern __fptoul - extern __fptoll - extern __fptoull - extern __fpfloor - extern __fpceil - extern __fptrunc - extern __fppop1 - extern __fppop2 - extern __fppack - extern __fppack.normalize - extern __fppack.normalized - extern __fppack2 - extern __fppack2.normalize - extern __fppack2.normalized - extern __ltofp - extern __ultofp - extern __lltofp - extern __ulltofp + .extern __fpabs + .extern __fpsub + .extern __fpadd + .extern __fpcbrt + .extern __fpcmpu + .extern __fpcmpo + .extern __fpcmp + .extern __fpcopysign + .extern __fpcopy + .extern __fpdiv + .extern __fpmin + .extern __fpmax + .extern __fpmul + .extern __fpneg + .extern __fprem + .extern __fpround + .extern __fpsqrt + .extern __fptol + .extern __fptoul + .extern __fptoll + .extern __fptoull + .extern __fpfloor + .extern __fpceil + .extern __fptrunc + .extern __fppop1 + .extern __fppop2 + .extern __fppack + .extern __fppack.normalize + .extern __fppack.normalized + .extern __fppack2 + .extern __fppack2.normalize + .extern __fppack2.normalized + .extern __ltofp + .extern __ultofp + .extern __lltofp + .extern __ulltofp - extern __fptod - extern __dtofp + .extern __fptod + .extern __dtofp From d5fc5eb40e3d7b46bff012390fa7b2e6c62bbd03 Mon Sep 17 00:00:00 2001 From: zerico <71151164+ZERICO2005@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:22:17 -0700 Subject: [PATCH 03/13] ez80sf ported virtual and require to GAS --- src/crt/fpaddsub.src | 10 +++------- src/crt/fpcopysign.src | 6 ++++-- src/crt/fpminmax.src | 6 +----- src/crt/fpround.src | 6 +----- src/crt/fptrunc.src | 4 ++-- src/crt/lltofp.src | 6 +----- src/crt/ltofp.src | 8 ++------ 7 files changed, 14 insertions(+), 32 deletions(-) diff --git a/src/crt/fpaddsub.src b/src/crt/fpaddsub.src index 816281800..e793c1bea 100644 --- a/src/crt/fpaddsub.src +++ b/src/crt/fpaddsub.src @@ -15,17 +15,13 @@ __fpsub: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ccf rr e ; jq __fpadd.enter - virtual - ld d, 0 - load .ld_d : byte from $$ - end virtual - db .ld_d + db $16 ; ld d, * - require __fpadd + ; require __fpadd ;------------------------------------------------------------------------------- - .section .text + ; .section .text .global __fpadd .type __fpadd, @function diff --git a/src/crt/fpcopysign.src b/src/crt/fpcopysign.src index fd59a550c..9329457f3 100644 --- a/src/crt/fpcopysign.src +++ b/src/crt/fpcopysign.src @@ -13,11 +13,13 @@ __fpcopysign: ; CHECK: bitcast(uint32_t, pair8_24_t, { out.BC, out.A }) == bitca xor a, e and a, 07Fh xor a, e - jq __fpcopy + ; jq __fpcopy + + ; require __fpcopy ;------------------------------------------------------------------------------- - .section .text + ; .section .text .global __fpcopy .type __fpcopy, @function diff --git a/src/crt/fpminmax.src b/src/crt/fpminmax.src index ae77d77e9..538391cad 100644 --- a/src/crt/fpminmax.src +++ b/src/crt/fpminmax.src @@ -37,11 +37,7 @@ __fpmax: ; CHECK: sameignzerosign(bitcast(float, pair8_24_t, { out.BC, out.A }), jq nc, .nocarry ret po ; jq .return - virtual - jr nc, $ - load .jr_nc : byte from $$ - end virtual - db .jr_nc + db $30 ; jr nc, * .nocarry: ret pe .return: diff --git a/src/crt/fpround.src b/src/crt/fpround.src index c6ec1b72c..ad06d7768 100644 --- a/src/crt/fpround.src +++ b/src/crt/fpround.src @@ -33,11 +33,7 @@ __fpround: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), roundf(b jq c, .no_overflow inc a ; jq .overflow - virtual - jr c, $ - load .jr_c : byte from $$ - end virtual - db .jr_c + db $38 ; jr c, * .no_overflow: add hl, hl .overflow: diff --git a/src/crt/fptrunc.src b/src/crt/fptrunc.src index efbb0be9f..3a8a83e78 100644 --- a/src/crt/fptrunc.src +++ b/src/crt/fptrunc.src @@ -72,11 +72,11 @@ __fpceil: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), ceilf(bit rrca jq nc, __fpfloor.roundup - require __fptrunc + ; require __fptrunc ;------------------------------------------------------------------------------- - .section .text + ; .section .text .global __fptrunc .type __fptrunc, @function diff --git a/src/crt/lltofp.src b/src/crt/lltofp.src index a1fc4d114..64df673cd 100644 --- a/src/crt/lltofp.src +++ b/src/crt/lltofp.src @@ -48,11 +48,7 @@ __ulltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)b ld l, a ld b, 07Fh + 63 ; jq .pack - virtual - jp c, $ - load .jp_c : byte from $$ - end virtual - db .jp_c + db $DA ; jp c, * .lower: ld c, a ld b, 07Fh + 47 diff --git a/src/crt/ltofp.src b/src/crt/ltofp.src index d883fe367..da1ff3c84 100644 --- a/src/crt/ltofp.src +++ b/src/crt/ltofp.src @@ -13,13 +13,9 @@ __ultofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)bi push af xor a, a ; jq __ltofp.enter - virtual - jr c, $ - load .jr_c : byte from $$ - end virtual - db .jr_c + db $38 ; jr c, * - require __ltofp + ; require __ltofp ;------------------------------------------------------------------------------- From 6371e7c94a0654daeadb41042a84c82e925b8ebf Mon Sep 17 00:00:00 2001 From: zerico <71151164+ZERICO2005@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:02:15 -0700 Subject: [PATCH 04/13] ez80sf ported fasmg extensions to GAS --- src/crt/fpcbrt.src | 17 +++++++++++------ src/crt/fpdiv.src | 14 +++++++++----- src/crt/fpmul.src | 31 +++++++++++++++++++++++-------- src/crt/fprem.src | 9 ++++++--- src/crt/fpsqrt.src | 15 ++++++++++----- src/crt/fptol.src | 6 ++++-- src/crt/fptrunc.src | 2 +- src/crt/lltofp.src | 10 +++++++--- 8 files changed, 71 insertions(+), 33 deletions(-) diff --git a/src/crt/fpcbrt.src b/src/crt/fpcbrt.src index 53d382b7c..bb7521714 100644 --- a/src/crt/fpcbrt.src +++ b/src/crt/fpcbrt.src @@ -8,7 +8,8 @@ ; IEEE single precision cube root ; aubc = cbrt(aubc) __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cbrt(bitcast(float, pair8_24_t, { in.BC, in.A }))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY - push de, bc + push de + push bc ex (sp), hl ld e, a call __fppop1 @@ -20,7 +21,8 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb mlt de ld c, a ld a, i - push af, hl + push af + push hl ex (sp), ix or a, a sbc hl, hl @@ -62,7 +64,7 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb ; x in AUHL[UHL']UIX, r in CUDE[UDE'], q in UIY .root.loop: exx - lea bc, iy + lea bc, iy + 0 jq c, .root.zerobit ex af, af' ; q += 1 @@ -162,7 +164,8 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb sbc hl, hl inc hl add hl, bc - pop iy, bc + pop iy + pop bc ; Get final exponent after rounding ld a, b adc a, 07Fh - (07Fh / 3) - 10 @@ -174,11 +177,13 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb .return: sla c rra - pop ix, bc + pop ix + pop bc bit 2, c .nonfinite: ex (sp), hl - pop bc, de + pop bc + pop de ret z ei ret diff --git a/src/crt/fpdiv.src b/src/crt/fpdiv.src index e2f941bee..5a9ca6485 100644 --- a/src/crt/fpdiv.src +++ b/src/crt/fpdiv.src @@ -8,7 +8,8 @@ ; IEEE single precision division ; aubc = aubc / euhl __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(float, pair8_24_t, { in.BC, in.A }) / bitcast(float, pair8_24_t, { in.HL, in.E })) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY - push de, hl + push de + push hl xor a, e push af xor a, e @@ -70,7 +71,7 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl dec bc ld a, c inc b - ld bc, 0800000h or (23 shl 8) + ld bc, 0800000h | (23 << 8) jq z, .divide.entry.normal adc a, b ld b, a @@ -92,7 +93,9 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl .return.overflow: ld c, b .return.nonfinite: - pop af, hl, de + pop af + pop hl + pop de or a, 07Fh ret @@ -143,7 +146,7 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl .round: ccf .subsubnormal: - lea de, iy + lea de, iy + 0 pop iy sbc hl, hl inc hl @@ -158,7 +161,8 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl sla d rra ex (sp), hl - pop bc, de + pop bc + pop de ret .extern __fppop1 diff --git a/src/crt/fpmul.src b/src/crt/fpmul.src index 8863d4733..b51d310d9 100644 --- a/src/crt/fpmul.src +++ b/src/crt/fpmul.src @@ -8,7 +8,8 @@ ; IEEE single precision multiplication ; aubc = aubc * euhl __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(float, pair8_24_t, { in.BC, in.A }) * bitcast(float, pair8_24_t, { in.HL, in.E })) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY - push de, hl + push de + push hl xor a, e push af xor a, e @@ -31,7 +32,10 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl add a, e jq nc, .continue .overflow: - pop af, af, hl, de + pop af + pop af + pop hl + pop de or a, 07Fh ret .subtract: @@ -44,7 +48,8 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl dec a ld d, a .continue: - push hl, ix + push hl + push ix ld ix, -7 add ix, sp ld sp, ix @@ -117,19 +122,27 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl .normalized: ld (ix + 4), hl ld c, (ix + 17) - pop ix, hl + pop ix + pop hl inc sp ld b, a ld de, 0800000h add a, -1 call nc, __fppack2.normalized call c, __fppack2 - pop ix, bc, bc, bc + pop ix + pop bc + pop bc + pop bc ex (sp), hl - pop bc, de + pop bc + pop de ret .underflow: - pop af, af, hl, de + pop af + pop af + pop hl + pop de and a, 080h ld bc, 0 ret @@ -161,7 +174,9 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl sbc hl, bc jq z, .return.nan .return.2: - pop bc, af, bc + pop bc + pop af + pop bc push bc .return.pop: pop hl diff --git a/src/crt/fprem.src b/src/crt/fprem.src index ce4765b4e..c797bc510 100644 --- a/src/crt/fprem.src +++ b/src/crt/fprem.src @@ -14,7 +14,8 @@ __fprem: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), fmodf(bitc set 7, e ; euhl = -abs(EUHL) call __fpcmpo ; abs(AUBC) <=> abs(EUHL) jq m, .notge ; !(abs(AUBC) >= abs(EUHL)) - push hl, bc + push hl + push bc call __fppop1 ex (sp), hl ld a, e @@ -59,11 +60,13 @@ __fprem: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), fmodf(bitc xor a, a call __fppack ex (sp), hl - pop bc, de + pop bc + pop de ret .nan: - pop hl, hl + pop hl + pop hl .notge: ld a, d pop de diff --git a/src/crt/fpsqrt.src b/src/crt/fpsqrt.src index f788c9ca3..2d3926e5a 100644 --- a/src/crt/fpsqrt.src +++ b/src/crt/fpsqrt.src @@ -8,7 +8,8 @@ ; IEEE single precision square root ; aubc = sqrt(aubc) __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sqrt(bitcast(float, pair8_24_t, { in.BC, in.A }))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY - push de, bc + push de + push bc ex (sp), hl ld e, a call __fppop1 @@ -75,7 +76,8 @@ __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sq rla .endr ; Set the low exponent bit of the result - pop de, ix + pop de + pop ix sra e rla rrca @@ -91,7 +93,8 @@ __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sq add a, 07Fh / 4 + 1 ; Check whether to round up (never round-to-even because a root with the lowest mantissa bit set must be irrational) inc l - pop hl, de + pop hl + pop de ret p inc bc ; This never overflows into the exponent field ret @@ -100,13 +103,15 @@ __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sq rrca .zero: ex (sp), hl - pop bc, de + pop bc + pop de ret .nan: sbc a, a set 7, b - pop hl, de + pop hl + pop de ret .extern __fppop1 diff --git a/src/crt/fptol.src b/src/crt/fptol.src index 667aa04a2..eac24c0ff 100644 --- a/src/crt/fptol.src +++ b/src/crt/fptol.src @@ -11,7 +11,8 @@ ; aubc = long(aubc) __fptoul: ; PREREQ: bitcast(float, pair8_24_t, { in.BC, in.A }) > -1.0f && bitcast(float, pair8_24_t, { in.BC, in.A }) < (UINT32_MAX/2+1)*2.0f CHECK: bitcast(uint32_t, pair8_24_t, { out.BC, out.A }) == (uint32_t)bitcast(float, pair8_24_t, { in.BC, in.A }) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY __fptol: ; PREREQ: bitcast(float, pair8_24_t, { in.BC, in.A })-INT32_MIN > -1.0f && bitcast(float, pair8_24_t, { in.BC, in.A }) < (INT32_MAX/2+1)*2.0f CHECK: bitcast(int32_t, pair8_24_t, { out.BC, out.A }) == (int32_t)bitcast(float, pair8_24_t, { in.BC, in.A }) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY - push de, bc + push de + push bc ex (sp), hl ld d, a ld e, a @@ -42,7 +43,8 @@ __fptol: ; PREREQ: bitcast(float, pair8_24_t, { in.BC, in.A })-INT32_MIN > -1.0f ld a, e .return: ex (sp), hl - pop bc, de + pop bc + pop de ret .return.zero: diff --git a/src/crt/fptrunc.src b/src/crt/fptrunc.src index 3a8a83e78..55c201aa1 100644 --- a/src/crt/fptrunc.src +++ b/src/crt/fptrunc.src @@ -54,7 +54,7 @@ __fpfloor.roundup: .return.one: ld bc, 0800000h ld a, h - or a, 07Fh shr 1 + or a, 07Fh >> 1 pop hl ret diff --git a/src/crt/lltofp.src b/src/crt/lltofp.src index 64df673cd..59bb85340 100644 --- a/src/crt/lltofp.src +++ b/src/crt/lltofp.src @@ -10,7 +10,8 @@ ; IEEE single precision from 64-bit integers ; euhl = float(bcudeuhl) __lltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)bitcast(int64_t, tuple16_24_24_t, { in.HL, in.DE, in.BCS })) && out.A == in.A && out.BC == in.BC && out.IX == in.IX && out.IY == in.IY - push af, bc + push af + push bc ld a, b or a, a call m, __llneg @@ -24,7 +25,8 @@ __lltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)bi .type __ulltofp, @function __ulltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)bitcast(uint64_t, tuple16_24_24_t, { in.HL, in.DE, in.BCS })) && out.A == in.A && out.BC == in.BC && out.IX == in.IX && out.IY == in.IY - push af, bc + push af + push bc xor a, a .enter: inc b @@ -59,7 +61,9 @@ __ulltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)b ld de, 0800000h call __fppack2 ld e, a - pop ix, bc, af + pop ix + pop bc + pop af ret ;------------------------------------------------------------------------------- From 7f8004107524e7a47b0e9978973887cf4d03a797 Mon Sep 17 00:00:00 2001 From: zerico <71151164+ZERICO2005@users.noreply.github.com> Date: Wed, 4 Feb 2026 15:24:40 -0700 Subject: [PATCH 05/13] change trivial jq p/m/po/pe to jp --- src/crt/fpcmp.src | 2 +- src/crt/fpminmax.src | 2 +- src/crt/fprem.src | 2 +- src/crt/fpround.src | 2 +- src/crt/fptoll.src | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/crt/fpcmp.src b/src/crt/fpcmp.src index c5fbf7675..b579b4a5f 100644 --- a/src/crt/fpcmp.src +++ b/src/crt/fpcmp.src @@ -39,7 +39,7 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = ; Check if first operand could hold NaN, and if so, the second cannot on this code path inc e jq z, .checkFirstNan - jq pe, .checkFirstNan + jp pe, .checkFirstNan dec e .secondLargerAbs: cp a, 07Fh ; C = S = !sign(aubc), Z = 0 diff --git a/src/crt/fpminmax.src b/src/crt/fpminmax.src index 538391cad..33b56eb68 100644 --- a/src/crt/fpminmax.src +++ b/src/crt/fpminmax.src @@ -24,7 +24,7 @@ __fpmin: ; CHECK: sameignzerosign(bitcast(float, pair8_24_t, { out.BC, out.A }), __fpmax: ; CHECK: sameignzerosign(bitcast(float, pair8_24_t, { out.BC, out.A }), fmaxf(quiet(bitcast(float, pair8_24_t, { in.BC, in.A })), quiet(bitcast(float, pair8_24_t, { in.HL, in.E })))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY call __fpcmpo ret c - jq p, __fpmin.return + jp p, __fpmin.return .unordered: ; Compare the low 31 bits (ignoring sign) and return the smaller one, which is non-NaN if either one is sbc hl, bc diff --git a/src/crt/fprem.src b/src/crt/fprem.src index c797bc510..76fec2b1c 100644 --- a/src/crt/fprem.src +++ b/src/crt/fprem.src @@ -13,7 +13,7 @@ __fprem: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), fmodf(bitc set 7, a ; aubc = -abs(AUBC) set 7, e ; euhl = -abs(EUHL) call __fpcmpo ; abs(AUBC) <=> abs(EUHL) - jq m, .notge ; !(abs(AUBC) >= abs(EUHL)) + jp m, .notge ; !(abs(AUBC) >= abs(EUHL)) push hl push bc call __fppop1 diff --git a/src/crt/fpround.src b/src/crt/fpround.src index ad06d7768..667de086b 100644 --- a/src/crt/fpround.src +++ b/src/crt/fpround.src @@ -29,7 +29,7 @@ __fpround: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), roundf(b sbc hl, de ex (sp), hl ex de, hl - jq pe, .overflow + jp pe, .overflow jq c, .no_overflow inc a ; jq .overflow diff --git a/src/crt/fptoll.src b/src/crt/fptoll.src index 6281c47c7..6ecb7414c 100644 --- a/src/crt/fptoll.src +++ b/src/crt/fptoll.src @@ -36,7 +36,7 @@ __fptoll: ; PREREQ: bitcast(float, pair8_24_t, { in.HL, in.E })-INT64_MIN > -1.0 .finish: pop af ret p - jq __llneg + jp __llneg .return.zero: sbc hl, hl From 50668a7eb7b041d233c496d7f28b483c968b57cb Mon Sep 17 00:00:00 2001 From: zerico <71151164+ZERICO2005@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:35:30 -0700 Subject: [PATCH 06/13] ez80sf change jq --> jr --- src/crt/fpaddsub.src | 46 +++++++++++++++++++++--------------------- src/crt/fpcbrt.src | 16 +++++++-------- src/crt/fpcmp.src | 38 +++++++++++++++++------------------ src/crt/fpdiv.src | 48 ++++++++++++++++++++++---------------------- src/crt/fpminmax.src | 6 +++--- src/crt/fpmul.src | 34 +++++++++++++++---------------- src/crt/fprem.src | 8 ++++---- src/crt/fpround.src | 6 +++--- src/crt/fpsqrt.src | 12 +++++------ src/crt/fptol.src | 8 ++++---- src/crt/fptoll.src | 6 +++--- src/crt/fptrunc.src | 16 +++++++-------- src/crt/fputil.src | 20 +++++++++--------- src/crt/lltofp.src | 4 ++-- src/crt/ltofp.src | 2 +- 15 files changed, 135 insertions(+), 135 deletions(-) diff --git a/src/crt/fpaddsub.src b/src/crt/fpaddsub.src index e793c1bea..21f20f306 100644 --- a/src/crt/fpaddsub.src +++ b/src/crt/fpaddsub.src @@ -44,13 +44,13 @@ __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ld e, a call __fppop2 inc e - jq z, .nonfinite1 + jr z, .nonfinite1 inc d - jq z, .return2 + jr z, .return2 ld a, d sub a, e - jq z, .rounded - jq nc, .sorted + jr z, .rounded + jr nc, .sorted inc c ex (sp), hl ld a, e @@ -58,25 +58,25 @@ __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ld d, e .sorted: cp a, 26 - jq nc, .largest + jr nc, .largest ; Extend to 32 bits and shift left by ~(amount - 1) & 7 dec a ld b, a xor a, a srl b - jq c, .noshift1 + jr c, .noshift1 add hl, hl rla .noshift1: srl b - jq c, .noshift2 + jr c, .noshift2 .rept 2 add hl, hl rla .endr .noshift2: srl b - jq c, .noshift4 + jr c, .noshift4 .rept 4 add hl, hl rla @@ -90,11 +90,11 @@ __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl push hl inc sp ld a, l - jq nz, .shift16 + jr nz, .shift16 ; Shift by 8 for amounts between 1 and 8 pop hl inc sp - jq .rounded + jr .rounded .shift16: ; Shift by 16 for amounts between 9 and 16 @@ -102,7 +102,7 @@ __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl inc sp pop hl dec b - jq z, .flush + jr z, .flush .shift8more: ; Shift by 24 for amounts between 17 and 24 or a, e @@ -121,7 +121,7 @@ __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl pop de ex (sp), hl add.s hl, hl - jq nc, .add + jr nc, .add ld l, h add hl, bc ld c, l @@ -130,7 +130,7 @@ __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl .nonfinite1: inc d - jq z, .nonfinite + jr z, .nonfinite .return1: pop bc .return1.pop1: @@ -147,7 +147,7 @@ __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl .largest: ld a, d cp a, e - jq z, .return1 + jr z, .return1 .return2: pop bc .return2.pop1: @@ -157,14 +157,14 @@ __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl pop bc pop bc push bc - jq .return + jr .return .add: ld c, h pop hl add hl, de dec b - jq nc, .done + jr nc, .done ex de, hl sbc hl, hl add hl, sp @@ -174,12 +174,12 @@ __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl rr h rr l rra - jq nc, .flushed2 + jr nc, .flushed2 or a, 1 .flushed2: inc b inc b - jq z, .infinite + jr z, .infinite djnz .done ;always taken .borrow: @@ -189,8 +189,8 @@ __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ex de, hl neg sbc hl, de - jq c, .borrow - jq nz, .done + jr c, .borrow + jr nz, .done or a, a .done: ld de, 0800000h @@ -204,13 +204,13 @@ __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl .nonfinite: xor a, a sbc hl, bc - jq nz, .return1 + jr nz, .return1 pop hl sbc hl, bc - jq nz, .return2.pop1 + jr nz, .return2.pop1 pop de bit 7, d - jq z, .return1.pop2 + jr z, .return1.pop2 ld bc, 0C00000h .infinite: ld a, c diff --git a/src/crt/fpcbrt.src b/src/crt/fpcbrt.src index bb7521714..f4f25be47 100644 --- a/src/crt/fpcbrt.src +++ b/src/crt/fpcbrt.src @@ -14,7 +14,7 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb ld e, a call __fppop1 inc e - jq z, .nonfinite + jr z, .nonfinite dec e ld d, 0ABh ; multiplicative inverse of 3 modulo 256 ld b, d @@ -33,13 +33,13 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb add ix, ix adc hl, hl sub a, b - jq c, .modulo.loop - jq nz, .normalized + jr c, .modulo.loop + jr nz, .normalized dec d - jq z, .return + jr z, .return cp a, l inc a - jq nc, .modulo.loop + jr nc, .modulo.loop .normalized: add a, d ld b, a @@ -65,7 +65,7 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb .root.loop: exx lea bc, iy + 0 - jq c, .root.zerobit + jr c, .root.zerobit ex af, af' ; q += 1 inc iy @@ -85,7 +85,7 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb ; r += q add hl, bc adc a, 0 - jq .root.nextbit + jr .root.nextbit .root.zerobit: ; x += r << 24 add hl, de @@ -171,7 +171,7 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb adc a, 07Fh - (07Fh / 3) - 10 ; Set low exponent bit srl b - jq nc, .return + jr nc, .return ld de, 0800000h add hl, de .return: diff --git a/src/crt/fpcmp.src b/src/crt/fpcmp.src index b579b4a5f..0f1cdcb99 100644 --- a/src/crt/fpcmp.src +++ b/src/crt/fpcmp.src @@ -31,14 +31,14 @@ __fpcmpu: ; CHECK: out.flags.C == !isunordered(bitcast(float, pair8_24_t, { in.H ; s = !(euhl >= aubc) __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) == bitcast(float, pair8_24_t, { in.BC, in.A })) && out.flags.C == (bitcast(float, pair8_24_t, { in.HL, in.E }) < bitcast(float, pair8_24_t, { in.BC, in.A })) && out.flags.S == !(bitcast(float, pair8_24_t, { in.HL, in.E }) >= bitcast(float, pair8_24_t, { in.BC, in.A })) && out.A == in.A && out.BC == in.BC && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY xor a, e - jq z, .maybeEqual + jr z, .maybeEqual cp a, 080h - jq c, .signsMatch - jq z, .maybeBothZero + jr c, .signsMatch + jr z, .maybeBothZero xor a, e ; Check if first operand could hold NaN, and if so, the second cannot on this code path inc e - jq z, .checkFirstNan + jr z, .checkFirstNan jp pe, .checkFirstNan dec e .secondLargerAbs: @@ -50,7 +50,7 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = ld hl, 07FFFFFh add hl, bc pop hl - jq c, .unordered + jr c, .unordered cp a, 080h ; C = S = !sign(aubc), Z = 0 ret @@ -58,9 +58,9 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = xor a, e ; Compare upper 7 exponent bits, which are not equal cp a, e - jq nc, .secondLargerAbs + jr nc, .secondLargerAbs inc e - jq z, .checkFirstNan + jr z, .checkFirstNan dec e ; S = sign(euhl), Z = 0 because E > A rlca rrca ; C = sign(aubc), same as sign(euhl) on this code path @@ -75,7 +75,7 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = pop hl ex de, hl dec e ; S = sign(euhl), Z = 0 because (E & 07Fh) == 07Fh - jq c, .unordered + jr c, .unordered ret p ; C = sign(euhl) scf ; C = sign(euhl) ret @@ -86,10 +86,10 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = ; Check if upper 7 bits of both exponents are zero add a, a rra - jq nz, .notBothZero + jr nz, .notBothZero ; Check if low bit of both exponents and entire mantissas are 0 adc hl, bc - jq nz, .notBothZeroFixup + jr nz, .notBothZeroFixup ret nc ; Both inputs are zero, return Z=1, C=0, S=0 .notBothZeroFixup: or a, a @@ -102,8 +102,8 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = ; Check the larger exponent/mantissa for NaN sbc hl, bc add hl, bc - jq nc, .checkFirstNanInc - jq .checkSecondNan + jr nc, .checkFirstNanInc + jr .checkSecondNan .maybeEqual: ; Sign and upper 7 exponent bits are equal @@ -111,7 +111,7 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = inc a add a, a ld a, e - jq z, .checkBothNan + jr z, .checkBothNan or a, a .checkBothNanDone: ; Compare mantissas and low exponent bit @@ -131,13 +131,13 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = push hl ld hl, 07FFFFFh add hl, de - jq c, .gotFirstNan + jr c, .gotFirstNan sbc hl, de add hl, bc .gotFirstNan: pop hl ex de, hl - jq nc, .checkBothNanDone + jr nc, .checkBothNanDone .unordered: ; Carry is always set here rr a ; Z = 0, S = 1 @@ -157,9 +157,9 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = ; s = euhl < aubc = !(euhl >= aubc) __fpcmp: ; CHECK: (isunordered(bitcast(float, pair8_24_t, { in.HL, in.E }), bitcast(float, pair8_24_t, { in.BC, in.A })) || (out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) == bitcast(float, pair8_24_t, { in.BC, in.A })) && out.flags.S == (bitcast(float, pair8_24_t, { in.HL, in.E }) < bitcast(float, pair8_24_t, { in.BC, in.A })))) && out.A == in.A && out.BC == in.BC && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY sub a, e - jq z, .maybeEqual + jr z, .maybeEqual cp a, 080h - jq z, .maybeBothZero + jr z, .maybeBothZero ; Compare sign and upper 7 exponent bits, which are not equal add a, e inc e @@ -175,9 +175,9 @@ __fpcmp: ; CHECK: (isunordered(bitcast(float, pair8_24_t, { in.HL, in.E }), bitc add a, e add a, a rra - jq nz, .notBothZero + jr nz, .notBothZero adc hl, bc - jq c, .notBothZeroFixup + jr c, .notBothZeroFixup ret z ; Both inputs are zero, return Z=1, S=0 .notBothZeroFixup: or a, a diff --git a/src/crt/fpdiv.src b/src/crt/fpdiv.src index 5a9ca6485..9fb86b0e2 100644 --- a/src/crt/fpdiv.src +++ b/src/crt/fpdiv.src @@ -20,23 +20,23 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ld e, a call __fppop2 inc e - jq z, .nonfinite.1 + jr z, .nonfinite.1 ld a, d inc a - jq z, .nonfinite.2 + jr z, .nonfinite.2 add a, 080h dec d - jq nz, .exponent.adjust + jr nz, .exponent.adjust ex (sp), hl add hl, bc - jq c, .normalize.divisor.done + jr c, .normalize.divisor.done sbc hl, bc - jq z, .divisor.zero + jr z, .divisor.zero .normalize.divisor.loop: dec a add hl, hl add hl, bc - jq nc, .normalize.divisor.loop + jr nc, .normalize.divisor.loop .normalize.divisor.done: add hl, bc ex (sp), hl @@ -57,37 +57,37 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl add hl, de ; uhl=UHL .normalize.dividend.loop: add hl, de - jq c, .normalize.dividend.done + jr c, .normalize.dividend.done sbc hl, de - jq z, .dividend.zero + jr z, .dividend.zero dec bc add hl, hl - jq nc, .normalize.dividend.loop + jr nc, .normalize.dividend.loop add hl, de .normalize.dividend.done: cp a, b - jq nc, .return.overflow + jr nc, .return.overflow dec bc dec bc ld a, c inc b ld bc, 0800000h | (23 << 8) - jq z, .divide.entry.normal + jr z, .divide.entry.normal adc a, b ld b, a ld a, c - jq nc, .return.underflow + jr nc, .return.underflow push iy ld iy, 0 - jq nz, .divide.entry.subnormal + jr nz, .divide.entry.subnormal dec hl add hl, de - jq .subsubnormal + jr .subsubnormal .divisor.zero: pop de sbc hl, de - jq nz, .return.nonfinite + jr nz, .return.nonfinite .return.nan: inc b .return.overflow: @@ -102,21 +102,21 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl .nonfinite.1: inc d pop de - jq z, .return.nan + jr z, .return.nan push hl pop bc - jq .return.nonfinite + jr .return.nonfinite .nonfinite.2: pop hl dec hl add hl, bc - jq c, .return.nan + jr c, .return.nan .return.underflow: sbc hl, hl .dividend.zero: pop de - jq .return + jr .return .divide.entry.normal: push iy @@ -124,13 +124,13 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl .divide.loop: add iy, iy add hl, hl - jq c, .divide.overflow + jr c, .divide.overflow add hl, de - jq c, .divide.setbit + jr c, .divide.setbit sbc hl, de djnz .divide.loop add hl, hl - jq .divide.finish + jr .divide.finish .divide.overflow: add hl, de .divide.setbit: @@ -140,7 +140,7 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl add hl, hl inc hl .divide.finish: - jq c, .round + jr c, .round dec de add hl, de .round: @@ -155,7 +155,7 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ld e, a adc a, 1 srl e - jq nc, .return + jr nc, .return add hl, bc .return: sla d diff --git a/src/crt/fpminmax.src b/src/crt/fpminmax.src index 33b56eb68..99c803685 100644 --- a/src/crt/fpminmax.src +++ b/src/crt/fpminmax.src @@ -12,7 +12,7 @@ __fpmin: ; CHECK: sameignzerosign(bitcast(float, pair8_24_t, { out.BC, out.A }), fminf(quiet(bitcast(float, pair8_24_t, { in.BC, in.A })), quiet(bitcast(float, pair8_24_t, { in.HL, in.E })))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY call __fpcmpo ret p - jq nc, __fpmax.unordered + jr nc, __fpmax.unordered .return: push hl pop bc @@ -34,13 +34,13 @@ __fpmax: ; CHECK: sameignzerosign(bitcast(float, pair8_24_t, { out.BC, out.A }), ccf adc a, e ; Carry into bit 31 is equivalent to carry XOR overflow - jq nc, .nocarry + jr nc, .nocarry ret po ; jq .return db $30 ; jr nc, * .nocarry: ret pe .return: - jq __fpmin.return + jr __fpmin.return .extern __fpcmpo diff --git a/src/crt/fpmul.src b/src/crt/fpmul.src index b51d310d9..e7c9a3fa9 100644 --- a/src/crt/fpmul.src +++ b/src/crt/fpmul.src @@ -20,17 +20,17 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ld e, a call __fppop2 inc e - jq z, .nonfinite.1 + jr z, .nonfinite.1 inc d - jq z, .nonfinite.2 + jr z, .nonfinite.2 ld a, d ld d, b; 0 rlc e ccf rr e - jq nc, .subtract + jr nc, .subtract add a, e - jq nc, .continue + jr nc, .continue .overflow: pop af pop af @@ -40,10 +40,10 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ret .subtract: add a, e - jq z, .subnormal - jq c, .continue + jr z, .subnormal + jr c, .continue cp a, -23 - jq c, .underflow + jr c, .underflow .subnormal: dec a ld d, a @@ -102,7 +102,7 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl mlt bc add hl, bc cp a, d - jq nz, .normalized + jr nz, .normalized ld bc, (ix + 2) pop de .normalize: @@ -112,11 +112,11 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl rr c rr d rr e - jq nc, .flushed + jr nc, .flushed ld e, a .flushed: inc a - jq nz, .normalize + jr nz, .normalize push de ld (ix + 2), bc .normalized: @@ -148,31 +148,31 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ret .nonfinite: sbc hl, bc - jq z, .return.2 + jr z, .return.2 add hl, bc pop bc - jq .return.1 + jr .return.1 .nonfinite.1: inc d - jq z, .nonfinite + jr z, .nonfinite ex de, hl pop hl add hl, bc or a, a sbc hl, bc ex de, hl - jq nz, .return.1 + jr nz, .return.1 ld h, a .return.1: pop af ex (sp), hl pop bc - jq .return + jr .return .nonfinite.2: add hl, bc or a, a sbc hl, bc - jq z, .return.nan + jr z, .return.nan .return.2: pop bc pop af @@ -188,7 +188,7 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl pop bc set 7, b pop af - jq .return.pop + jr .return.pop .extern __fppop1 .extern __fppop2 diff --git a/src/crt/fprem.src b/src/crt/fprem.src index 76fec2b1c..fc632a7e5 100644 --- a/src/crt/fprem.src +++ b/src/crt/fprem.src @@ -32,7 +32,7 @@ __fprem: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), fmodf(bitc ex de, hl sbc hl, hl add hl, bc - jq nc, .nan ; Return if dividend non-finite or divisor zero + jr nc, .nan ; Return if dividend non-finite or divisor zero sbc hl, hl or a, a sbc hl, bc @@ -43,14 +43,14 @@ __fprem: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), fmodf(bitc inc b .rem.compare: add hl, de - jq c, .rem.norestore + jr c, .rem.norestore sbc hl, de .rem.norestore: dec b - jq z, .rem.finish + jr z, .rem.finish .rem.loop: add hl, hl - jq nc, .rem.compare + jr nc, .rem.compare add hl, de djnz .rem.loop .rem.finish: diff --git a/src/crt/fpround.src b/src/crt/fpround.src index 667de086b..9de98420d 100644 --- a/src/crt/fpround.src +++ b/src/crt/fpround.src @@ -14,9 +14,9 @@ __fpround: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), roundf(b ld h, a rla sub a, 07Fh - 1 - jq c, .return.zero + jr c, .return.zero sub a, 24 - jq nc, .return + jr nc, .return push bc cpl ld c, a @@ -30,7 +30,7 @@ __fpround: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), roundf(b ex (sp), hl ex de, hl jp pe, .overflow - jq c, .no_overflow + jr c, .no_overflow inc a ; jq .overflow db $38 ; jr c, * diff --git a/src/crt/fpsqrt.src b/src/crt/fpsqrt.src index 2d3926e5a..d8f7b33e6 100644 --- a/src/crt/fpsqrt.src +++ b/src/crt/fpsqrt.src @@ -16,16 +16,16 @@ __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sq add hl, bc or a, a sbc hl, bc - jq z, .zero + jr z, .zero rlca - jq c, .nan + jr c, .nan inc e - jq z, .nonfinite + jr z, .nonfinite push hl ex (sp), ix sbc hl, hl srl e - jq nc, .normalize.skip + jr nc, .normalize.skip .normalize.loop: add ix, ix adc hl, hl @@ -33,7 +33,7 @@ __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sq dec e add ix, ix adc hl, hl - jq z, .normalize.loop + jr z, .normalize.loop push de xor a, a ex de, hl @@ -48,7 +48,7 @@ __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sq ; x -= r << 24 sbc hl, de sbc a, c - jq nc, .root.onebit + jr nc, .root.onebit ; x += r << 24 add hl, de adc a, c diff --git a/src/crt/fptol.src b/src/crt/fptol.src index eac24c0ff..9631894a7 100644 --- a/src/crt/fptol.src +++ b/src/crt/fptol.src @@ -20,14 +20,14 @@ __fptol: ; PREREQ: bitcast(float, pair8_24_t, { in.BC, in.A })-INT32_MIN > -1.0f ld a, e sub a, 07Fh cp a, 23 + 32 - jq nc, .return.zero + jr nc, .return.zero sub a, 23 + 1 - jq nc, .left + jr nc, .left cpl ld c, a call __ishru xor a, a - jq .finish + jr .finish .left: inc a ld b, a @@ -50,7 +50,7 @@ __fptol: ; PREREQ: bitcast(float, pair8_24_t, { in.BC, in.A })-INT32_MIN > -1.0f .return.zero: xor a, a sbc hl, hl - jq .return + jr .return .extern __ishru .extern __lneg diff --git a/src/crt/fptoll.src b/src/crt/fptoll.src index 6ecb7414c..dd14f8bcb 100644 --- a/src/crt/fptoll.src +++ b/src/crt/fptoll.src @@ -18,14 +18,14 @@ __fptoll: ; PREREQ: bitcast(float, pair8_24_t, { in.HL, in.E })-INT64_MIN > -1.0 ld de, 0 sub a, 07Fh cp a, 23 + 64 - jq nc, .return.zero + jr nc, .return.zero sub a, 23 + 1 - jq nc, .left + jr nc, .left cpl ld c, a call __ishru ld c, b - jq .finish + jr .finish .left: inc a push af diff --git a/src/crt/fptrunc.src b/src/crt/fptrunc.src index 55c201aa1..516e8eb66 100644 --- a/src/crt/fptrunc.src +++ b/src/crt/fptrunc.src @@ -11,7 +11,7 @@ ; aubc = floor(aubc) __fpfloor: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), floorf(bitcast(float, pair8_24_t, { in.BC, in.A }))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY cp a, 080h - jq c, __fptrunc + jr c, __fptrunc .local __fpfloor.roundup @@ -21,11 +21,11 @@ __fpfloor.roundup: adc hl, hl ld h, a rla - jq z, .mantissa.zero + jr z, .mantissa.zero sub a, 07Fh - jq c, .return.one + jr c, .return.one sub a, 24 - jq nc, .return + jr nc, .return push bc cpl ld c, a @@ -50,7 +50,7 @@ __fpfloor.roundup: .mantissa.zero: dec a cp a, 07Fh - 1 - jq nc, .return + jr nc, .return .return.one: ld bc, 0800000h ld a, h @@ -70,7 +70,7 @@ __fpfloor.roundup: __fpceil: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), ceilf(bitcast(float, pair8_24_t, { in.BC, in.A }))) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY rlca rrca - jq nc, __fpfloor.roundup + jr nc, __fpfloor.roundup ; require __fptrunc @@ -90,9 +90,9 @@ __fptrunc: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), truncf(b ld h, a rla sub a, 07Fh - jq c, .return.zero + jr c, .return.zero sub a, 24 - jq nc, .return + jr nc, .return ld l, c cpl ld c, a diff --git a/src/crt/fputil.src b/src/crt/fputil.src index 855ba5c5d..cf65a460a 100644 --- a/src/crt/fputil.src +++ b/src/crt/fputil.src @@ -13,7 +13,7 @@ __fppop1: ld bc, 0800000h __fppop2: sla e - jq z, .denormal + jr z, .denormal add hl, bc ret nc add hl, bc @@ -37,7 +37,7 @@ __fppack.normalize: call nz, .entry __fppack: add hl, de - jq nc, .normalize + jr nc, .normalize .normalized: rrc l rlc l @@ -56,9 +56,9 @@ __fppack: add a, a adc hl, hl ret m - jq nz, .normalize.continue + jr nz, .normalize.continue or a, a - jq nz, .normalize.continue + jr nz, .normalize.continue ld b, 1 .normalize.loop: add a, a @@ -85,26 +85,26 @@ __fppack2.normalize: call nz, .loop __fppack2: add hl, de - jq nc, .normalize + jr nc, .normalize .normalized: ld a, b add ix, de - jq nc, .rounded + jr nc, .rounded dec ix add ix, de - jq nc, .round + jr nc, .round bit 0, l - jq z, .rounded + jr z, .rounded .round: scf adc hl, de adc a, e .clear: add hl, de - jq nc, .clear + jr nc, .clear .rounded: cp a, 0FFh - jq z, .infinite + jr z, .infinite sla c rra ret nc diff --git a/src/crt/lltofp.src b/src/crt/lltofp.src index 59bb85340..8f238e335 100644 --- a/src/crt/lltofp.src +++ b/src/crt/lltofp.src @@ -15,7 +15,7 @@ __lltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)bi ld a, b or a, a call m, __llneg - jq __ulltofp.enter + jr __ulltofp.enter ;------------------------------------------------------------------------------- @@ -33,7 +33,7 @@ __ulltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)b djnz .upper inc c dec c - jq z, .lower + jr z, .lower .upper: push bc push de diff --git a/src/crt/ltofp.src b/src/crt/ltofp.src index da1ff3c84..2d06d7cdf 100644 --- a/src/crt/ltofp.src +++ b/src/crt/ltofp.src @@ -36,7 +36,7 @@ __ltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)bit ld c, a ld a, b push de - jq nc, .positive + jr nc, .positive add hl, de ex de, hl neg From 46547b99498ffe1648032bf4b013575f3670d734 Mon Sep 17 00:00:00 2001 From: zerico <71151164+ZERICO2005@users.noreply.github.com> Date: Wed, 4 Feb 2026 16:58:13 -0700 Subject: [PATCH 07/13] ez80sf fix out of range jr --> jp --- src/crt/fpcbrt.src | 4 ++-- src/crt/fpmul.src | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/crt/fpcbrt.src b/src/crt/fpcbrt.src index f4f25be47..c0ef4511c 100644 --- a/src/crt/fpcbrt.src +++ b/src/crt/fpcbrt.src @@ -14,7 +14,7 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb ld e, a call __fppop1 inc e - jr z, .nonfinite + jp z, .nonfinite dec e ld d, 0ABh ; multiplicative inverse of 3 modulo 256 ld b, d @@ -36,7 +36,7 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb jr c, .modulo.loop jr nz, .normalized dec d - jr z, .return + jp z, .return cp a, l inc a jr nc, .modulo.loop diff --git a/src/crt/fpmul.src b/src/crt/fpmul.src index e7c9a3fa9..6f1d705f5 100644 --- a/src/crt/fpmul.src +++ b/src/crt/fpmul.src @@ -20,9 +20,9 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ld e, a call __fppop2 inc e - jr z, .nonfinite.1 + jp z, .nonfinite.1 inc d - jr z, .nonfinite.2 + jp z, .nonfinite.2 ld a, d ld d, b; 0 rlc e @@ -43,7 +43,7 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl jr z, .subnormal jr c, .continue cp a, -23 - jr c, .underflow + jp c, .underflow .subnormal: dec a ld d, a From 37f7a20fcb4cdbba802fcf2148047f38700d4d63 Mon Sep 17 00:00:00 2001 From: zerico <71151164+ZERICO2005@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:12:22 -0700 Subject: [PATCH 08/13] fixed local/private ez80sf labels --- src/crt/fpaddsub.src | 3 ++- src/crt/fpcmp.src | 20 ++++++++++++-------- src/crt/fpminmax.src | 16 ++++++++++------ src/crt/fptrunc.src | 10 ++++++---- src/crt/fputil.src | 20 +++++++++++--------- src/crt/lltofp.src | 3 ++- src/crt/ltofp.src | 3 ++- 7 files changed, 45 insertions(+), 30 deletions(-) diff --git a/src/crt/fpaddsub.src b/src/crt/fpaddsub.src index 21f20f306..6bddc0b2d 100644 --- a/src/crt/fpaddsub.src +++ b/src/crt/fpaddsub.src @@ -30,7 +30,8 @@ __fpsub: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ; aubc = aubc + euhl __fpadd: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(float, pair8_24_t, { in.BC, in.A }) + bitcast(float, pair8_24_t, { in.HL, in.E })) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY push de -.enter: + .local __fpadd.enter +__fpadd.enter: push hl push bc xor a, e diff --git a/src/crt/fpcmp.src b/src/crt/fpcmp.src index 0f1cdcb99..e9e827cb7 100644 --- a/src/crt/fpcmp.src +++ b/src/crt/fpcmp.src @@ -157,36 +157,40 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = ; s = euhl < aubc = !(euhl >= aubc) __fpcmp: ; CHECK: (isunordered(bitcast(float, pair8_24_t, { in.HL, in.E }), bitcast(float, pair8_24_t, { in.BC, in.A })) || (out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) == bitcast(float, pair8_24_t, { in.BC, in.A })) && out.flags.S == (bitcast(float, pair8_24_t, { in.HL, in.E }) < bitcast(float, pair8_24_t, { in.BC, in.A })))) && out.A == in.A && out.BC == in.BC && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY sub a, e - jr z, .maybeEqual + jr z, __fpcmp.maybeEqual cp a, 080h - jr z, .maybeBothZero + jr z, __fpcmp.maybeBothZero ; Compare sign and upper 7 exponent bits, which are not equal add a, e inc e dec e ; S = sign(euhl), Z = 0 because E > A ret c -.notBothZero: + .local __fpcmp.notBothZero +__fpcmp.notBothZero: cp a, 080h ; S = !sign(aubc) ret nz cp a, e ; S = !sign(aubc), Z = 0 because A == 080h and A > E and A - E != 080h ret -.maybeBothZero: + .local __fpcmp.maybeBothZero +__fpcmp.maybeBothZero: add a, e add a, a rra - jr nz, .notBothZero + jr nz, __fpcmp.notBothZero adc hl, bc - jr c, .notBothZeroFixup + jr c, __fpcmp.notBothZeroFixup ret z ; Both inputs are zero, return Z=1, S=0 -.notBothZeroFixup: + .local __fpcmp.notBothZeroFixup +__fpcmp.notBothZeroFixup: or a, a sbc hl, bc dec a ; S = !sign(aubc), Z = 0 because (A & 07Fh) == 0 cpl ; Restore A, preserve S and Z ret -.maybeEqual: + .local __fpcmp.maybeEqual +__fpcmp.maybeEqual: ld a, e sbc hl, bc add hl, bc diff --git a/src/crt/fpminmax.src b/src/crt/fpminmax.src index 99c803685..201ebf789 100644 --- a/src/crt/fpminmax.src +++ b/src/crt/fpminmax.src @@ -13,7 +13,8 @@ __fpmin: ; CHECK: sameignzerosign(bitcast(float, pair8_24_t, { out.BC, out.A }), call __fpcmpo ret p jr nc, __fpmax.unordered -.return: + .local __fpmin.return +__fpmin.return: push hl pop bc ld a, e @@ -25,7 +26,8 @@ __fpmax: ; CHECK: sameignzerosign(bitcast(float, pair8_24_t, { out.BC, out.A }), call __fpcmpo ret c jp p, __fpmin.return -.unordered: + .local __fpmax.unordered +__fpmax.unordered: ; Compare the low 31 bits (ignoring sign) and return the smaller one, which is non-NaN if either one is sbc hl, bc ccf @@ -34,13 +36,15 @@ __fpmax: ; CHECK: sameignzerosign(bitcast(float, pair8_24_t, { out.BC, out.A }), ccf adc a, e ; Carry into bit 31 is equivalent to carry XOR overflow - jr nc, .nocarry + jr nc, __fpmax.nocarry ret po -; jq .return +; jq __fpmax.return db $30 ; jr nc, * -.nocarry: + .local __fpmax.nocarry +__fpmax.nocarry: ret pe -.return: + .local __fpmax.return +__fpmax.return: jr __fpmin.return .extern __fpcmpo diff --git a/src/crt/fptrunc.src b/src/crt/fptrunc.src index 516e8eb66..e5d920b93 100644 --- a/src/crt/fptrunc.src +++ b/src/crt/fptrunc.src @@ -90,9 +90,9 @@ __fptrunc: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), truncf(b ld h, a rla sub a, 07Fh - jr c, .return.zero + jr c, __fptrunc.return.zero sub a, 24 - jr nc, .return + jr nc, __fptrunc.return ld l, c cpl ld c, a @@ -104,12 +104,14 @@ __fptrunc: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), truncf(b call __iand ex (sp), hl pop bc -.return: + .local __fptrunc.return +__fptrunc.return: ld a, h pop hl ret -.return.zero: + .local __fptrunc.return.zero +__fptrunc.return.zero: ld bc, 0 ld a, h and a, 080h diff --git a/src/crt/fputil.src b/src/crt/fputil.src index cf65a460a..be8302ef5 100644 --- a/src/crt/fputil.src +++ b/src/crt/fputil.src @@ -34,11 +34,11 @@ __fppop2: __fppack.normalize: dec b - call nz, .entry + call nz, __fppack.normalize.entry __fppack: add hl, de - jr nc, .normalize -.normalized: + jr nc, __fppack.normalize +__fppack.normalized: rrc l rlc l adc a, 07Fh @@ -52,7 +52,8 @@ __fppack: add hl, de ret -.normalize.entry: + .local __fppack.normalize.entry +__fppack.normalize.entry: add a, a adc hl, hl ret m @@ -82,11 +83,11 @@ __fppack: __fppack2.normalize: dec b - call nz, .loop + call nz, __fppack2.normalize.loop __fppack2: add hl, de - jr nc, .normalize -.normalized: + jr nc, __fppack2.normalize +__fppack2.normalized: ld a, b add ix, de jr nc, .rounded @@ -116,11 +117,12 @@ __fppack2: ex de, hl ret -.normalize.loop: + .local __fppack2.normalize.loop +__fppack2.normalize.loop: add ix, ix adc hl, hl ret m - djnz .normalize.loop + djnz __fppack2.normalize.loop add hl, de ret diff --git a/src/crt/lltofp.src b/src/crt/lltofp.src index 8f238e335..31e707ab3 100644 --- a/src/crt/lltofp.src +++ b/src/crt/lltofp.src @@ -28,7 +28,8 @@ __ulltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)b push af push bc xor a, a -.enter: + .local __ulltofp.enter +__ulltofp.enter: inc b djnz .upper inc c diff --git a/src/crt/ltofp.src b/src/crt/ltofp.src index 2d06d7cdf..955c5f4da 100644 --- a/src/crt/ltofp.src +++ b/src/crt/ltofp.src @@ -26,7 +26,8 @@ __ultofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)bi __ltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)bitcast(int32_t, pair8_24_t, { in.BC, in.A })) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY push af -.enter: + .local __ltofp.enter +__ltofp.enter: rlca inc sp push bc From 3f76e39c9a87350d744738394838da34a449a0d8 Mon Sep 17 00:00:00 2001 From: zerico <71151164+ZERICO2005@users.noreply.github.com> Date: Mon, 9 Feb 2026 11:12:32 -0700 Subject: [PATCH 09/13] Fixed ez80 local (.L) labels --- src/crt/fpaddsub.src | 102 +++++++++++++++++++++---------------------- src/crt/fpcbrt.src | 32 +++++++------- src/crt/fpcmp.src | 58 ++++++++++++------------ src/crt/fpdiv.src | 96 ++++++++++++++++++++-------------------- src/crt/fpmul.src | 66 ++++++++++++++-------------- src/crt/fprem.src | 24 +++++----- src/crt/fpround.src | 18 ++++---- src/crt/fpsqrt.src | 28 ++++++------ src/crt/fptol.src | 20 ++++----- src/crt/fptoll.src | 12 ++--- src/crt/fptrunc.src | 14 +++--- src/crt/fputil.src | 32 +++++++------- src/crt/lltofp.src | 12 ++--- src/crt/ltofp.src | 4 +- 14 files changed, 259 insertions(+), 259 deletions(-) diff --git a/src/crt/fpaddsub.src b/src/crt/fpaddsub.src index 6bddc0b2d..4622778d1 100644 --- a/src/crt/fpaddsub.src +++ b/src/crt/fpaddsub.src @@ -45,44 +45,44 @@ __fpadd.enter: ld e, a call __fppop2 inc e - jr z, .nonfinite1 + jr z, .L.nonfinite1 inc d - jr z, .return2 + jr z, .L.return2 ld a, d sub a, e - jr z, .rounded - jr nc, .sorted + jr z, .L.rounded + jr nc, .L.sorted inc c ex (sp), hl ld a, e sub a, d ld d, e -.sorted: +.L.sorted: cp a, 26 - jr nc, .largest + jr nc, .L.largest ; Extend to 32 bits and shift left by ~(amount - 1) & 7 dec a ld b, a xor a, a srl b - jr c, .noshift1 + jr c, .L.noshift1 add hl, hl rla -.noshift1: +.L.noshift1: srl b - jr c, .noshift2 + jr c, .L.noshift2 .rept 2 add hl, hl rla .endr -.noshift2: +.L.noshift2: srl b - jr c, .noshift4 + jr c, .L.noshift4 .rept 4 add hl, hl rla .endr -.noshift4: +.L.noshift4: ; Shift right by (amount + 7) / 8 * 8, truncating to 24 bits ; The last 2 bits shifted out are in A, while any remaining non-zero ; bits are aggregated into the lower bits of A @@ -91,81 +91,81 @@ __fpadd.enter: push hl inc sp ld a, l - jr nz, .shift16 + jr nz, .L.shift16 ; Shift by 8 for amounts between 1 and 8 pop hl inc sp - jr .rounded + jr .L.rounded -.shift16: +.L.shift16: ; Shift by 16 for amounts between 9 and 16 ld e, h inc sp pop hl dec b - jr z, .flush -.shift8more: + jr z, .L.flush +.L.shift8more: ; Shift by 24 for amounts between 17 and 24 or a, e ld e, l ld l, h ld h, 0 ; Shift by 32 for amount of 25 - djnz .shift8more -.flush: + djnz .L.shift8more +.L.flush: sub a, 1 sbc a, a inc a or a, e -.rounded: +.L.rounded: ld b, d pop de ex (sp), hl add.s hl, hl - jr nc, .add + jr nc, .L.add ld l, h add hl, bc ld c, l pop hl - djnz .subtract ;always taken + djnz .L.subtract ;always taken -.nonfinite1: +.L.nonfinite1: inc d - jr z, .nonfinite -.return1: + jr z, .L.nonfinite +.L.return1: pop bc -.return1.pop1: +.L.return1.pop1: pop de ld a, d -.return1.pop2: +.L.return1.pop2: xor a, e pop bc -.return: +.L.return: pop hl pop de ret -.largest: +.L.largest: ld a, d cp a, e - jr z, .return1 -.return2: + jr z, .L.return1 +.L.return2: pop bc -.return2.pop1: +.L.return2.pop1: pop de -.return2.pop2: +.L.return2.pop2: ld a, e pop bc pop bc push bc - jr .return + jr .L.return -.add: +.L.add: ld c, h pop hl add hl, de dec b - jr nc, .done + jr nc, .L.done ex de, hl sbc hl, hl add hl, sp @@ -175,25 +175,25 @@ __fpadd.enter: rr h rr l rra - jr nc, .flushed2 + jr nc, .L.flushed2 or a, 1 -.flushed2: +.L.flushed2: inc b inc b - jr z, .infinite - djnz .done ;always taken + jr z, .L.infinite + djnz .L.done ;always taken -.borrow: +.L.borrow: inc c add hl, de -.subtract: +.L.subtract: ex de, hl neg sbc hl, de - jr c, .borrow - jr nz, .done + jr c, .L.borrow + jr nz, .L.done or a, a -.done: +.L.done: ld de, 0800000h call nz, __fppack pop bc @@ -202,20 +202,20 @@ __fpadd.enter: pop de ret -.nonfinite: +.L.nonfinite: xor a, a sbc hl, bc - jr nz, .return1 + jr nz, .L.return1 pop hl sbc hl, bc - jr nz, .return2.pop1 + jr nz, .L.return2.pop1 pop de bit 7, d - jr z, .return1.pop2 + jr z, .L.return1.pop2 ld bc, 0C00000h -.infinite: +.L.infinite: ld a, c - ld c, b ;0, also note BCU=080h from __fppop1 or 0C0h from .nonfinite + ld c, b ;0, also note BCU=080h from __fppop1 or 0C0h from .L.nonfinite rrca or a, 07Fh pop hl diff --git a/src/crt/fpcbrt.src b/src/crt/fpcbrt.src index c0ef4511c..a97ee06d3 100644 --- a/src/crt/fpcbrt.src +++ b/src/crt/fpcbrt.src @@ -14,7 +14,7 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb ld e, a call __fppop1 inc e - jp z, .nonfinite + jp z, .L.nonfinite dec e ld d, 0ABh ; multiplicative inverse of 3 modulo 256 ld b, d @@ -28,19 +28,19 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb sbc hl, hl ld a, e ld d, 10 ; maximum normalization iterations to determine a zero -.modulo.loop: +.L.modulo.loop: ; x <<= 1 add ix, ix adc hl, hl sub a, b - jr c, .modulo.loop - jr nz, .normalized + jr c, .L.modulo.loop + jr nz, .L.normalized dec d - jp z, .return + jp z, .L.return cp a, l inc a - jr nc, .modulo.loop -.normalized: + jr nc, .L.modulo.loop +.L.normalized: add a, d ld b, a push bc @@ -62,10 +62,10 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb sbc hl, hl ld b, 24 ; x in AUHL[UHL']UIX, r in CUDE[UDE'], q in UIY -.root.loop: +.L.root.loop: exx lea bc, iy + 0 - jr c, .root.zerobit + jr c, .L.root.zerobit ex af, af' ; q += 1 inc iy @@ -85,8 +85,8 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb ; r += q add hl, bc adc a, 0 - jr .root.nextbit -.root.zerobit: + jr .L.root.nextbit +.L.root.zerobit: ; x += r << 24 add hl, de exx @@ -106,7 +106,7 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb or a, a sbc hl, bc sbc a, 0 -.root.nextbit: +.L.root.nextbit: ; r <<= 1 add hl, hl rla @@ -157,7 +157,7 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb exx sbc hl, de sbc a, c - djnz .root.loop + djnz .L.root.loop ; Apply rounding (never round-to-even because a root with the lowest mantissa bit set must be irrational) ; q += !carry exx @@ -171,16 +171,16 @@ __fpcbrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)cb adc a, 07Fh - (07Fh / 3) - 10 ; Set low exponent bit srl b - jr nc, .return + jr nc, .L.return ld de, 0800000h add hl, de -.return: +.L.return: sla c rra pop ix pop bc bit 2, c -.nonfinite: +.L.nonfinite: ex (sp), hl pop bc pop de diff --git a/src/crt/fpcmp.src b/src/crt/fpcmp.src index e9e827cb7..812adbc94 100644 --- a/src/crt/fpcmp.src +++ b/src/crt/fpcmp.src @@ -31,43 +31,43 @@ __fpcmpu: ; CHECK: out.flags.C == !isunordered(bitcast(float, pair8_24_t, { in.H ; s = !(euhl >= aubc) __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) == bitcast(float, pair8_24_t, { in.BC, in.A })) && out.flags.C == (bitcast(float, pair8_24_t, { in.HL, in.E }) < bitcast(float, pair8_24_t, { in.BC, in.A })) && out.flags.S == !(bitcast(float, pair8_24_t, { in.HL, in.E }) >= bitcast(float, pair8_24_t, { in.BC, in.A })) && out.A == in.A && out.BC == in.BC && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY xor a, e - jr z, .maybeEqual + jr z, .L.maybeEqual cp a, 080h - jr c, .signsMatch - jr z, .maybeBothZero + jr c, .L.signsMatch + jr z, .L.maybeBothZero xor a, e ; Check if first operand could hold NaN, and if so, the second cannot on this code path inc e - jr z, .checkFirstNan - jp pe, .checkFirstNan + jr z, .L.checkFirstNan + jp pe, .L.checkFirstNan dec e -.secondLargerAbs: +.L.secondLargerAbs: cp a, 07Fh ; C = S = !sign(aubc), Z = 0 ret c ; Return if A less than 07Fh ret pe ; Return if A between 080h and 0FEh -.checkSecondNan: +.L.checkSecondNan: push hl ld hl, 07FFFFFh add hl, bc pop hl - jr c, .unordered + jr c, .L.unordered cp a, 080h ; C = S = !sign(aubc), Z = 0 ret -.signsMatch: +.L.signsMatch: xor a, e ; Compare upper 7 exponent bits, which are not equal cp a, e - jr nc, .secondLargerAbs + jr nc, .L.secondLargerAbs inc e - jr z, .checkFirstNan + jr z, .L.checkFirstNan dec e ; S = sign(euhl), Z = 0 because E > A rlca rrca ; C = sign(aubc), same as sign(euhl) on this code path ret po ; Return if E != 07Fh -.checkFirstNanInc: +.L.checkFirstNanInc: inc e -.checkFirstNan: +.L.checkFirstNan: ex de, hl push hl ld hl, 07FFFFFh @@ -75,26 +75,26 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = pop hl ex de, hl dec e ; S = sign(euhl), Z = 0 because (E & 07Fh) == 07Fh - jr c, .unordered + jr c, .L.unordered ret p ; C = sign(euhl) scf ; C = sign(euhl) ret -.maybeBothZero: +.L.maybeBothZero: ; Upper 7 bits of exponents are equal, but sign differs xor a, e ; Check if upper 7 bits of both exponents are zero add a, a rra - jr nz, .notBothZero + jr nz, .L.notBothZero ; Check if low bit of both exponents and entire mantissas are 0 adc hl, bc - jr nz, .notBothZeroFixup + jr nz, .L.notBothZeroFixup ret nc ; Both inputs are zero, return Z=1, C=0, S=0 -.notBothZeroFixup: +.L.notBothZeroFixup: or a, a sbc hl, bc -.notBothZero: +.L.notBothZero: ; Check if upper 7 bits of both exponents are one cp a, 07Fh ; C = S = !sign(aubc), Z = 0 ret c ; Return if less than 07Fh @@ -102,18 +102,18 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = ; Check the larger exponent/mantissa for NaN sbc hl, bc add hl, bc - jr nc, .checkFirstNanInc - jr .checkSecondNan + jr nc, .L.checkFirstNanInc + jr .L.checkSecondNan -.maybeEqual: +.L.maybeEqual: ; Sign and upper 7 exponent bits are equal ld a, e inc a add a, a ld a, e - jr z, .checkBothNan + jr z, .L.checkBothNan or a, a -.checkBothNanDone: +.L.checkBothNanDone: ; Compare mantissas and low exponent bit sbc hl, bc add hl, bc @@ -126,19 +126,19 @@ __fpcmpo: ; CHECK: out.flags.Z == (bitcast(float, pair8_24_t, { in.HL, in.E }) = ld a, e ret -.checkBothNan: +.L.checkBothNan: ex de, hl push hl ld hl, 07FFFFFh add hl, de - jr c, .gotFirstNan + jr c, .L.gotFirstNan sbc hl, de add hl, bc -.gotFirstNan: +.L.gotFirstNan: pop hl ex de, hl - jr nc, .checkBothNanDone -.unordered: + jr nc, .L.checkBothNanDone +.L.unordered: ; Carry is always set here rr a ; Z = 0, S = 1 rla ; Restore A diff --git a/src/crt/fpdiv.src b/src/crt/fpdiv.src index 9fb86b0e2..9e5da5123 100644 --- a/src/crt/fpdiv.src +++ b/src/crt/fpdiv.src @@ -20,27 +20,27 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ld e, a call __fppop2 inc e - jr z, .nonfinite.1 + jr z, .L.nonfinite.1 ld a, d inc a - jr z, .nonfinite.2 + jr z, .L.nonfinite.2 add a, 080h dec d - jr nz, .exponent.adjust + jr nz, .L.exponent.adjust ex (sp), hl add hl, bc - jr c, .normalize.divisor.done + jr c, .L.normalize.divisor.done sbc hl, bc - jr z, .divisor.zero -.normalize.divisor.loop: + jr z, .L.divisor.zero +.L.normalize.divisor.loop: dec a add hl, hl add hl, bc - jr nc, .normalize.divisor.loop -.normalize.divisor.done: + jr nc, .L.normalize.divisor.loop +.L.normalize.divisor.done: add hl, bc ex (sp), hl -.exponent.adjust: +.L.exponent.adjust: ex de, hl ; ude=UHL, uhl=UDE ld h, b rl b @@ -55,97 +55,97 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl sbc hl, de ; uhl=-UDE ex de, hl ; ude=-UDE, uhl=UHL+UDE add hl, de ; uhl=UHL -.normalize.dividend.loop: +.L.normalize.dividend.loop: add hl, de - jr c, .normalize.dividend.done + jr c, .L.normalize.dividend.done sbc hl, de - jr z, .dividend.zero + jr z, .L.dividend.zero dec bc add hl, hl - jr nc, .normalize.dividend.loop + jr nc, .L.normalize.dividend.loop add hl, de -.normalize.dividend.done: +.L.normalize.dividend.done: cp a, b - jr nc, .return.overflow + jr nc, .L.return.overflow dec bc dec bc ld a, c inc b ld bc, 0800000h | (23 << 8) - jr z, .divide.entry.normal + jr z, .L.divide.entry.normal adc a, b ld b, a ld a, c - jr nc, .return.underflow + jr nc, .L.return.underflow push iy ld iy, 0 - jr nz, .divide.entry.subnormal + jr nz, .L.divide.entry.subnormal dec hl add hl, de - jr .subsubnormal + jr .L.subsubnormal -.divisor.zero: +.L.divisor.zero: pop de sbc hl, de - jr nz, .return.nonfinite -.return.nan: + jr nz, .L.return.nonfinite +.L.return.nan: inc b -.return.overflow: +.L.return.overflow: ld c, b -.return.nonfinite: +.L.return.nonfinite: pop af pop hl pop de or a, 07Fh ret -.nonfinite.1: +.L.nonfinite.1: inc d pop de - jr z, .return.nan + jr z, .L.return.nan push hl pop bc - jr .return.nonfinite + jr .L.return.nonfinite -.nonfinite.2: +.L.nonfinite.2: pop hl dec hl add hl, bc - jr c, .return.nan -.return.underflow: + jr c, .L.return.nan +.L.return.underflow: sbc hl, hl -.dividend.zero: +.L.dividend.zero: pop de - jr .return + jr .L.return -.divide.entry.normal: +.L.divide.entry.normal: push iy ld iyl, b -.divide.loop: +.L.divide.loop: add iy, iy add hl, hl - jr c, .divide.overflow + jr c, .L.divide.overflow add hl, de - jr c, .divide.setbit + jr c, .L.divide.setbit sbc hl, de - djnz .divide.loop + djnz .L.divide.loop add hl, hl - jr .divide.finish -.divide.overflow: + jr .L.divide.finish +.L.divide.overflow: add hl, de -.divide.setbit: -.divide.entry.subnormal: +.L.divide.setbit: +.L.divide.entry.subnormal: inc iy - djnz .divide.loop + djnz .L.divide.loop add hl, hl inc hl -.divide.finish: - jr c, .round +.L.divide.finish: + jr c, .L.round dec de add hl, de -.round: +.L.round: ccf -.subsubnormal: +.L.subsubnormal: lea de, iy + 0 pop iy sbc hl, hl @@ -155,9 +155,9 @@ __fpdiv: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ld e, a adc a, 1 srl e - jr nc, .return + jr nc, .L.return add hl, bc -.return: +.L.return: sla d rra ex (sp), hl diff --git a/src/crt/fpmul.src b/src/crt/fpmul.src index 6f1d705f5..dbd0797c4 100644 --- a/src/crt/fpmul.src +++ b/src/crt/fpmul.src @@ -20,34 +20,34 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ld e, a call __fppop2 inc e - jp z, .nonfinite.1 + jp z, .L.nonfinite.1 inc d - jp z, .nonfinite.2 + jp z, .L.nonfinite.2 ld a, d ld d, b; 0 rlc e ccf rr e - jr nc, .subtract + jr nc, .L.subtract add a, e - jr nc, .continue -.overflow: + jr nc, .L.continue +.L.overflow: pop af pop af pop hl pop de or a, 07Fh ret -.subtract: +.L.subtract: add a, e - jr z, .subnormal - jr c, .continue + jr z, .L.subnormal + jr c, .L.continue cp a, -23 - jp c, .underflow -.subnormal: + jp c, .L.underflow +.L.subnormal: dec a ld d, a -.continue: +.L.continue: push hl push ix ld ix, -7 @@ -102,24 +102,24 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl mlt bc add hl, bc cp a, d - jr nz, .normalized + jr nz, .L.normalized ld bc, (ix + 2) pop de -.normalize: +.L.normalize: srl h rr l rr b rr c rr d rr e - jr nc, .flushed + jr nc, .L.flushed ld e, a -.flushed: +.L.flushed: inc a - jr nz, .normalize + jr nz, .L.normalize push de ld (ix + 2), bc -.normalized: +.L.normalized: ld (ix + 4), hl ld c, (ix + 17) pop ix @@ -138,7 +138,7 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl pop bc pop de ret -.underflow: +.L.underflow: pop af pop af pop hl @@ -146,49 +146,49 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl and a, 080h ld bc, 0 ret -.nonfinite: +.L.nonfinite: sbc hl, bc - jr z, .return.2 + jr z, .L.return.2 add hl, bc pop bc - jr .return.1 -.nonfinite.1: + jr .L.return.1 +.L.nonfinite.1: inc d - jr z, .nonfinite + jr z, .L.nonfinite ex de, hl pop hl add hl, bc or a, a sbc hl, bc ex de, hl - jr nz, .return.1 + jr nz, .L.return.1 ld h, a -.return.1: +.L.return.1: pop af ex (sp), hl pop bc - jr .return -.nonfinite.2: + jr .L.return +.L.nonfinite.2: add hl, bc or a, a sbc hl, bc - jr z, .return.nan -.return.2: + jr z, .L.return.nan +.L.return.2: pop bc pop af pop bc push bc -.return.pop: +.L.return.pop: pop hl -.return: +.L.return: pop de or a, 07Fh ret -.return.nan: +.L.return.nan: pop bc set 7, b pop af - jr .return.pop + jr .L.return.pop .extern __fppop1 .extern __fppop2 diff --git a/src/crt/fprem.src b/src/crt/fprem.src index fc632a7e5..325940c12 100644 --- a/src/crt/fprem.src +++ b/src/crt/fprem.src @@ -13,7 +13,7 @@ __fprem: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), fmodf(bitc set 7, a ; aubc = -abs(AUBC) set 7, e ; euhl = -abs(EUHL) call __fpcmpo ; abs(AUBC) <=> abs(EUHL) - jp m, .notge ; !(abs(AUBC) >= abs(EUHL)) + jp m, .L.notge ; !(abs(AUBC) >= abs(EUHL)) push hl push bc call __fppop1 @@ -32,7 +32,7 @@ __fprem: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), fmodf(bitc ex de, hl sbc hl, hl add hl, bc - jr nc, .nan ; Return if dividend non-finite or divisor zero + jr nc, .L.nan ; Return if dividend non-finite or divisor zero sbc hl, hl or a, a sbc hl, bc @@ -41,19 +41,19 @@ __fprem: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), fmodf(bitc call m, __iremu ; If divisor subnormal, modulo the mantissas ld b, a inc b -.rem.compare: +.L.rem.compare: add hl, de - jr c, .rem.norestore + jr c, .L.rem.norestore sbc hl, de -.rem.norestore: +.L.rem.norestore: dec b - jr z, .rem.finish -.rem.loop: + jr z, .L.rem.finish +.L.rem.loop: add hl, hl - jr nc, .rem.compare + jr nc, .L.rem.compare add hl, de - djnz .rem.loop -.rem.finish: + djnz .L.rem.loop +.L.rem.finish: pop bc rlc c ld de, 0800000h @@ -64,10 +64,10 @@ __fprem: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), fmodf(bitc pop de ret -.nan: +.L.nan: pop hl pop hl -.notge: +.L.notge: ld a, d pop de ret c ; abs(AUBC) < abs(EUHL) diff --git a/src/crt/fpround.src b/src/crt/fpround.src index 9de98420d..f1792ad5f 100644 --- a/src/crt/fpround.src +++ b/src/crt/fpround.src @@ -14,9 +14,9 @@ __fpround: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), roundf(b ld h, a rla sub a, 07Fh - 1 - jr c, .return.zero + jr c, .L.return.zero sub a, 24 - jr nc, .return + jr nc, .L.return push bc cpl ld c, a @@ -29,25 +29,25 @@ __fpround: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), roundf(b sbc hl, de ex (sp), hl ex de, hl - jp pe, .overflow - jr c, .no_overflow + jp pe, .L.overflow + jr c, .L.no_overflow inc a -; jq .overflow +; jq .L.overflow db $38 ; jr c, * -.no_overflow: +.L.no_overflow: add hl, hl -.overflow: +.L.overflow: pop bc call __iand push hl pop bc ld h, a -.return: +.L.return: ld a, h pop hl ret -.return.zero: +.L.return.zero: ld bc, 0 ld a, h and a, 080h diff --git a/src/crt/fpsqrt.src b/src/crt/fpsqrt.src index d8f7b33e6..48d448304 100644 --- a/src/crt/fpsqrt.src +++ b/src/crt/fpsqrt.src @@ -16,24 +16,24 @@ __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sq add hl, bc or a, a sbc hl, bc - jr z, .zero + jr z, .L.zero rlca - jr c, .nan + jr c, .L.nan inc e - jr z, .nonfinite + jr z, .L.nonfinite push hl ex (sp), ix sbc hl, hl srl e - jr nc, .normalize.skip -.normalize.loop: + jr nc, .L.normalize.skip +.L.normalize.loop: add ix, ix adc hl, hl -.normalize.skip: +.L.normalize.skip: dec e add ix, ix adc hl, hl - jr z, .normalize.loop + jr z, .L.normalize.loop push de xor a, a ex de, hl @@ -41,21 +41,21 @@ __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sq ld c, a ld b, 25 ; x in AUDEUIX, r in CUHL -.root.loop: +.L.root.loop: ex de, hl ; r += 1 inc de ; sets bit 0 so never overflows ; x -= r << 24 sbc hl, de sbc a, c - jr nc, .root.onebit + jr nc, .L.root.onebit ; x += r << 24 add hl, de adc a, c ; r -= 2 dec de dec de -.root.onebit: +.L.root.onebit: ; r += 1 inc de ; x <<= 2 @@ -68,7 +68,7 @@ __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sq ; r <<= 1 add hl, hl rl c ; clears carry - djnz .root.loop + djnz .L.root.loop ; Shift left by 5 ld a, c .rept 5 @@ -99,15 +99,15 @@ __fpsqrt: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), (float)sq inc bc ; This never overflows into the exponent field ret -.nonfinite: +.L.nonfinite: rrca -.zero: +.L.zero: ex (sp), hl pop bc pop de ret -.nan: +.L.nan: sbc a, a set 7, b pop hl diff --git a/src/crt/fptol.src b/src/crt/fptol.src index 9631894a7..cf2c70015 100644 --- a/src/crt/fptol.src +++ b/src/crt/fptol.src @@ -20,37 +20,37 @@ __fptol: ; PREREQ: bitcast(float, pair8_24_t, { in.BC, in.A })-INT32_MIN > -1.0f ld a, e sub a, 07Fh cp a, 23 + 32 - jr nc, .return.zero + jr nc, .L.return.zero sub a, 23 + 1 - jr nc, .left + jr nc, .L.left cpl ld c, a call __ishru xor a, a - jr .finish -.left: + jr .L.finish +.L.left: inc a ld b, a xor a, a -.loop: +.L.loop: add hl, hl rla - djnz .loop -.finish: + djnz .L.loop +.L.finish: ld e, a bit 7, d call nz, __lneg ld a, e -.return: +.L.return: ex (sp), hl pop bc pop de ret -.return.zero: +.L.return.zero: xor a, a sbc hl, hl - jr .return + jr .L.return .extern __ishru .extern __lneg diff --git a/src/crt/fptoll.src b/src/crt/fptoll.src index dd14f8bcb..09bafe1e2 100644 --- a/src/crt/fptoll.src +++ b/src/crt/fptoll.src @@ -18,27 +18,27 @@ __fptoll: ; PREREQ: bitcast(float, pair8_24_t, { in.HL, in.E })-INT64_MIN > -1.0 ld de, 0 sub a, 07Fh cp a, 23 + 64 - jr nc, .return.zero + jr nc, .L.return.zero sub a, 23 + 1 - jr nc, .left + jr nc, .L.left cpl ld c, a call __ishru ld c, b - jr .finish -.left: + jr .L.finish +.L.left: inc a push af inc sp call __llshl inc sp inc sp -.finish: +.L.finish: pop af ret p jp __llneg -.return.zero: +.L.return.zero: sbc hl, hl pop af ret diff --git a/src/crt/fptrunc.src b/src/crt/fptrunc.src index e5d920b93..1386e838a 100644 --- a/src/crt/fptrunc.src +++ b/src/crt/fptrunc.src @@ -21,11 +21,11 @@ __fpfloor.roundup: adc hl, hl ld h, a rla - jr z, .mantissa.zero + jr z, .L.mantissa.zero sub a, 07Fh - jr c, .return.one + jr c, .L.return.one sub a, 24 - jr nc, .return + jr nc, .L.return push bc cpl ld c, a @@ -42,16 +42,16 @@ __fpfloor.roundup: push hl pop bc ld h, a -.return: +.L.return: ld a, h pop hl ret -.mantissa.zero: +.L.mantissa.zero: dec a cp a, 07Fh - 1 - jr nc, .return -.return.one: + jr nc, .L.return +.L.return.one: ld bc, 0800000h ld a, h or a, 07Fh >> 1 diff --git a/src/crt/fputil.src b/src/crt/fputil.src index be8302ef5..e882d7d55 100644 --- a/src/crt/fputil.src +++ b/src/crt/fputil.src @@ -13,11 +13,11 @@ __fppop1: ld bc, 0800000h __fppop2: sla e - jr z, .denormal + jr z, .L.denormal add hl, bc ret nc add hl, bc -.denormal: +.L.denormal: inc e ret @@ -57,16 +57,16 @@ __fppack.normalize.entry: add a, a adc hl, hl ret m - jr nz, .normalize.continue + jr nz, .L.normalize.continue or a, a - jr nz, .normalize.continue + jr nz, .L.normalize.continue ld b, 1 -.normalize.loop: +.L.normalize.loop: add a, a adc hl, hl ret m -.normalize.continue: - djnz .normalize.loop +.L.normalize.continue: + djnz .L.normalize.loop add hl, de ret @@ -90,28 +90,28 @@ __fppack2: __fppack2.normalized: ld a, b add ix, de - jr nc, .rounded + jr nc, .L.rounded dec ix add ix, de - jr nc, .round + jr nc, .L.round bit 0, l - jr z, .rounded -.round: + jr z, .L.rounded +.L.round: scf adc hl, de adc a, e -.clear: +.L.clear: add hl, de - jr nc, .clear -.rounded: + jr nc, .L.clear +.L.rounded: cp a, 0FFh - jr z, .infinite + jr z, .L.infinite sla c rra ret nc add hl, de ret -.infinite: +.L.infinite: sla c rra ex de, hl diff --git a/src/crt/lltofp.src b/src/crt/lltofp.src index 31e707ab3..898bfb145 100644 --- a/src/crt/lltofp.src +++ b/src/crt/lltofp.src @@ -31,11 +31,11 @@ __ulltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)b .local __ulltofp.enter __ulltofp.enter: inc b - djnz .upper + djnz .L.upper inc c dec c - jr z, .lower -.upper: + jr z, .L.lower +.L.upper: push bc push de push hl @@ -50,12 +50,12 @@ __ulltofp.enter: or a, l ld l, a ld b, 07Fh + 63 -; jq .pack +; jq .L.pack db $DA ; jp c, * -.lower: +.L.lower: ld c, a ld b, 07Fh + 47 -.pack: +.L.pack: ex de, hl push de ex (sp), ix diff --git a/src/crt/ltofp.src b/src/crt/ltofp.src index 955c5f4da..4af3c1350 100644 --- a/src/crt/ltofp.src +++ b/src/crt/ltofp.src @@ -37,12 +37,12 @@ __ltofp.enter: ld c, a ld a, b push de - jr nc, .positive + jr nc, .L.positive add hl, de ex de, hl neg sbc hl, de -.positive: +.L.positive: ld de, 0800000h ld b, 07Fh + 31 call __fppack From 593e7304636702297bd16707e9d726a906bc83d1 Mon Sep 17 00:00:00 2001 From: zerico <71151164+ZERICO2005@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:20:04 -0700 Subject: [PATCH 10/13] moved fpmul labels into jr range --- src/crt/fpmul.src | 109 +++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/src/crt/fpmul.src b/src/crt/fpmul.src index dbd0797c4..b166870e5 100644 --- a/src/crt/fpmul.src +++ b/src/crt/fpmul.src @@ -5,6 +5,58 @@ .global __fpmul .type __fpmul, @function +.L.underflow: + pop af + pop af + pop hl + pop de + and a, 080h + ld bc, 0 + ret +.L.nonfinite: + sbc hl, bc + jr z, .L.return.2 + add hl, bc + pop bc + jr .L.return.1 +.L.nonfinite.1: + inc d + jr z, .L.nonfinite + ex de, hl + pop hl + add hl, bc + or a, a + sbc hl, bc + ex de, hl + jr nz, .L.return.1 + ld h, a +.L.return.1: + pop af + ex (sp), hl + pop bc + jr .L.return +.L.nonfinite.2: + add hl, bc + or a, a + sbc hl, bc + jr z, .L.return.nan +.L.return.2: + pop bc + pop af + pop bc + push bc +.L.return.pop: + pop hl +.L.return: + pop de + or a, 07Fh + ret +.L.return.nan: + pop bc + set 7, b + pop af + jr .L.return.pop + ; IEEE single precision multiplication ; aubc = aubc * euhl __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(float, pair8_24_t, { in.BC, in.A }) * bitcast(float, pair8_24_t, { in.HL, in.E })) && out.DE == in.DE && out.HL == in.HL && out.IX == in.IX && out.IY == in.IY @@ -20,9 +72,9 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ld e, a call __fppop2 inc e - jp z, .L.nonfinite.1 + jr z, .L.nonfinite.1 inc d - jp z, .L.nonfinite.2 + jr z, .L.nonfinite.2 ld a, d ld d, b; 0 rlc e @@ -43,7 +95,7 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl jr z, .L.subnormal jr c, .L.continue cp a, -23 - jp c, .L.underflow + jr c, .L.underflow .L.subnormal: dec a ld d, a @@ -138,57 +190,6 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl pop bc pop de ret -.L.underflow: - pop af - pop af - pop hl - pop de - and a, 080h - ld bc, 0 - ret -.L.nonfinite: - sbc hl, bc - jr z, .L.return.2 - add hl, bc - pop bc - jr .L.return.1 -.L.nonfinite.1: - inc d - jr z, .L.nonfinite - ex de, hl - pop hl - add hl, bc - or a, a - sbc hl, bc - ex de, hl - jr nz, .L.return.1 - ld h, a -.L.return.1: - pop af - ex (sp), hl - pop bc - jr .L.return -.L.nonfinite.2: - add hl, bc - or a, a - sbc hl, bc - jr z, .L.return.nan -.L.return.2: - pop bc - pop af - pop bc - push bc -.L.return.pop: - pop hl -.L.return: - pop de - or a, 07Fh - ret -.L.return.nan: - pop bc - set 7, b - pop af - jr .L.return.pop .extern __fppop1 .extern __fppop2 From a271431cc4f725a355d21363e4637daefaecc67c Mon Sep 17 00:00:00 2001 From: zerico <71151164+ZERICO2005@users.noreply.github.com> Date: Mon, 9 Feb 2026 12:24:35 -0700 Subject: [PATCH 11/13] optimized fpmul multiplication --- src/crt/fpmul.src | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/crt/fpmul.src b/src/crt/fpmul.src index b166870e5..20a32faff 100644 --- a/src/crt/fpmul.src +++ b/src/crt/fpmul.src @@ -76,7 +76,7 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl inc d jr z, .L.nonfinite.2 ld a, d - ld d, b; 0 + ld d, b ; ld d, 0 rlc e ccf rr e @@ -133,26 +133,28 @@ __fpmul: ; CHECK: same(bitcast(float, pair8_24_t, { out.BC, out.A }), bitcast(fl ld bc, (ix + 12) mlt bc add hl, bc + ld (ix + 2), hl - ld hl, (ix + 3) - inc hl - dec.s hl - ld c, (ix + 11) - ld b, (ix + 15) - mlt bc + ld b, (ix + 4) + ld c, h + ld l, (ix + 11) + ld h, (ix + 15) + mlt hl ; clears UHL add hl, bc + ld c, (ix + 12) ld b, (ix + 14) mlt bc add hl, bc + ld (ix + 3), hl - ld hl, (ix + 4) - inc hl - dec.s hl - ld c, (ix + 12) - ld b, (ix + 15) - mlt bc + ld b, (ix + 5) + ld c, h + ld l, (ix + 12) + ld h, (ix + 15) + mlt hl ; clears UHL add hl, bc + cp a, d jr nz, .L.normalized ld bc, (ix + 2) From d14f160afdc72e1301b9f1bc85d2d8c5935af6eb Mon Sep 17 00:00:00 2001 From: zerico <71151164+ZERICO2005@users.noreply.github.com> Date: Tue, 24 Feb 2026 18:27:50 -0700 Subject: [PATCH 12/13] switched ftoll and (u)lltof to ez80sf --- src/crt/fptoll.src | 6 ++++++ src/crt/ftoll.c | 22 ---------------------- src/crt/ftoll.src | 24 ------------------------ src/crt/lltof.c | 13 ------------- src/crt/lltof.src | 23 ----------------------- src/crt/lltofp.src | 6 ++++++ src/crt/ulltof.c | 13 ------------- src/crt/ulltof.src | 23 ----------------------- 8 files changed, 12 insertions(+), 118 deletions(-) delete mode 100644 src/crt/ftoll.c delete mode 100644 src/crt/ftoll.src delete mode 100644 src/crt/lltof.c delete mode 100644 src/crt/lltof.src delete mode 100644 src/crt/ulltof.c delete mode 100644 src/crt/ulltof.src diff --git a/src/crt/fptoll.src b/src/crt/fptoll.src index 09bafe1e2..154c4db40 100644 --- a/src/crt/fptoll.src +++ b/src/crt/fptoll.src @@ -2,6 +2,10 @@ .section .text + .global __ftoll + .type __ftoll, @function + .global __ftoull + .type __ftoull, @function .global __fptoll .type __fptoll, @function .global __fptoull @@ -9,6 +13,8 @@ ; IEEE single precision to 64-bit integers ; bcudeuhl = longlong(euhl) +__ftoull: +__ftoll: __fptoull: ; PREREQ: bitcast(float, pair8_24_t, { in.HL, in.E }) > -1.0f && bitcast(float, pair8_24_t, { in.HL, in.E }) < (UINT64_MAX/2+1)*2.0f CHECK: bitcast(uint64_t, tuple16_24_24_t, { out.HL, out.DE, out.BCS }) == (uint64_t)bitcast(float, pair8_24_t, { in.HL, in.E }) && out.A == in.A && out.IX == in.IX && out.IY == in.IY __fptoll: ; PREREQ: bitcast(float, pair8_24_t, { in.HL, in.E })-INT64_MIN > -1.0f && bitcast(float, pair8_24_t, { in.HL, in.E }) < (INT64_MAX/2+1)*2.0f CHECK: bitcast(int64_t, tuple16_24_24_t, { out.HL, out.DE, out.BCS }) == (int64_t)bitcast(float, pair8_24_t, { in.HL, in.E }) && out.A == in.A && out.IX == in.IX && out.IY == in.IY ld d, a diff --git a/src/crt/ftoll.c b/src/crt/ftoll.c deleted file mode 100644 index b88ead5e3..000000000 --- a/src/crt/ftoll.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include -#include - -/** - * @brief the exact same routine is used for (long long)float and - * (unsigned long long)float. If the input float is out of range, - * then the conversion is UB anyways. - */ -long long _ftoll_c(float x) -{ - const union { float f; uint32_t u; struct { uint32_t mantissa: FLT_MANT_DIG - 1, exponent: 8, sign: 1; }; } parts = { .f = x }; - const uint8_t exponent = parts.exponent, bias = (1 << 7) - 1; - const uint24_t mantissa = UINT24_C(1) << (FLT_MANT_DIG - 1) | parts.mantissa; - if (exponent < bias) return 0; - if (exponent <= bias + FLT_MANT_DIG - 1) { - const long long result = mantissa >> (bias + FLT_MANT_DIG - 1 - exponent); - return parts.sign ? -result : result; - } - const long long result = (long long)mantissa << (exponent - (bias + FLT_MANT_DIG - 1)); - return parts.sign ? -result : result; -} diff --git a/src/crt/ftoll.src b/src/crt/ftoll.src deleted file mode 100644 index c7389a1ed..000000000 --- a/src/crt/ftoll.src +++ /dev/null @@ -1,24 +0,0 @@ - .assume adl=1 - - .section .text - - .global __ftoll - .type __ftoll, @function - .global __ftoull - .type __ftoull, @function - -; __ftoll_c correctly handles all non-UB cases for both -; (long long)float and (unsigned long long)float -__ftoll: -__ftoull: - ld d, a - push iy - push de - push hl - call __ftoll_c - pop af - pop af - pop iy - ret - - .extern __ftoll_c diff --git a/src/crt/lltof.c b/src/crt/lltof.c deleted file mode 100644 index 4d5c9a84a..000000000 --- a/src/crt/lltof.c +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include -#include - -float _lltof_c(long long x) -{ - uint8_t exponent = x ? __builtin_clrsbll(x) : LLONG_WIDTH - 1; - if (exponent >= LLONG_WIDTH - LONG_WIDTH) { - return (float)((long)x); - } - exponent = LLONG_WIDTH - LONG_WIDTH - exponent; - return ldexpf((float)((long)(x >> exponent)), exponent); -} diff --git a/src/crt/lltof.src b/src/crt/lltof.src deleted file mode 100644 index 18dfd4e94..000000000 --- a/src/crt/lltof.src +++ /dev/null @@ -1,23 +0,0 @@ - .assume adl=1 - - .section .text - .global __lltof - .type __lltof, @function - -__lltof: - push af - push iy - push bc - push de - push hl - call __lltof_c - pop af - ld a, e - pop de - ld e, a - pop bc - pop iy - pop af - ret - - .extern __lltof_c diff --git a/src/crt/lltofp.src b/src/crt/lltofp.src index 898bfb145..b53ebfbe8 100644 --- a/src/crt/lltofp.src +++ b/src/crt/lltofp.src @@ -4,11 +4,14 @@ .section .text + .global __lltof + .type __lltof, @function .global __lltofp .type __lltofp, @function ; IEEE single precision from 64-bit integers ; euhl = float(bcudeuhl) +__lltof: __lltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)bitcast(int64_t, tuple16_24_24_t, { in.HL, in.DE, in.BCS })) && out.A == in.A && out.BC == in.BC && out.IX == in.IX && out.IY == in.IY push af push bc @@ -21,9 +24,12 @@ __lltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)bi .section .text + .global __ulltof + .type __ulltof, @function .global __ulltofp .type __ulltofp, @function +__ulltof: __ulltofp: ; CHECK: same(bitcast(float, pair8_24_t, { out.HL, out.E }), (float)bitcast(uint64_t, tuple16_24_24_t, { in.HL, in.DE, in.BCS })) && out.A == in.A && out.BC == in.BC && out.IX == in.IX && out.IY == in.IY push af push bc diff --git a/src/crt/ulltof.c b/src/crt/ulltof.c deleted file mode 100644 index 568ad7ddd..000000000 --- a/src/crt/ulltof.c +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include -#include - -float _ulltof_c(unsigned long long x) -{ - uint8_t exponent = x ? __builtin_clzll(x) : ULLONG_WIDTH; - if (exponent >= ULLONG_WIDTH - ULONG_WIDTH) { - return (float)((unsigned long)x); - } - exponent = ULLONG_WIDTH - ULONG_WIDTH - exponent; - return ldexpf((float)((unsigned long)(x >> exponent)), exponent); -} diff --git a/src/crt/ulltof.src b/src/crt/ulltof.src deleted file mode 100644 index 6ae1d6214..000000000 --- a/src/crt/ulltof.src +++ /dev/null @@ -1,23 +0,0 @@ - .assume adl=1 - - .section .text - .global __ulltof - .type __ulltof, @function - -__ulltof: - push af - push iy - push bc - push de - push hl - call __ulltof_c - pop af - ld a, e - pop de - ld e, a - pop bc - pop iy - pop af - ret - - .extern __ulltof_c From 01f1a2f012ca1f30c430d99432fe8a6edff3df48 Mon Sep 17 00:00:00 2001 From: zerico <71151164+ZERICO2005@users.noreply.github.com> Date: Tue, 24 Feb 2026 18:42:35 -0700 Subject: [PATCH 13/13] renamed dtof/ftod to dtofp/fptod --- src/crt/{dtof.src => dtofp.src} | 7 ++-- src/crt/fptemp.src | 37 ---------------------- src/crt/{ftod.src => fptod.src} | 3 ++ test/floating_point/ez80sf/src/link_test.s | 4 +-- 4 files changed, 10 insertions(+), 41 deletions(-) rename src/crt/{dtof.src => dtofp.src} (97%) delete mode 100644 src/crt/fptemp.src rename src/crt/{ftod.src => fptod.src} (97%) diff --git a/src/crt/dtof.src b/src/crt/dtofp.src similarity index 97% rename from src/crt/dtof.src rename to src/crt/dtofp.src index 6cfdb2138..1ffde7ed2 100644 --- a/src/crt/dtof.src +++ b/src/crt/dtofp.src @@ -4,9 +4,11 @@ .global __dtof .type __dtof, @function + .global __dtofp + .type __dtofp, @function - .local __dtof_helper -__dtof_helper: + .local __dtofp_helper +__dtofp_helper: ; Moving this block of code to be behind __dtof ensures that ; .L.ret_copysign can always be reached by jr in all paths. .L.overflow: @@ -54,6 +56,7 @@ __dtof_helper: ; Quiet NaN: Quiet bit preserved. No signals raised. ; NaN Payloads: Copies the most significant payload bits. The LSB of mantissa is set if payload bits were discarded/truncated out. __dtof: +__dtofp: bit 7, b push af ; preserve A and signbit push bc diff --git a/src/crt/fptemp.src b/src/crt/fptemp.src deleted file mode 100644 index 8a1e949ef..000000000 --- a/src/crt/fptemp.src +++ /dev/null @@ -1,37 +0,0 @@ - .assume adl=1 - -;------------------------------------------------------------------------------- - - .section .text - - .global __fptod - .type __fptod, @function -__fptod := __ftod - - .extern __ftod - -;------------------------------------------------------------------------------- - - .section .text - - .global __dtofp - .type __dtofp, @function -__dtofp := __dtof - - .extern __dtof - -;------------------------------------------------------------------------------- - - .section .text - - .global __dcmpo - .type __dcmpo, @function - .global __dcmpu - .type __dcmpu, @function - -__dcmpo := __dcmp -__dcmpu := __dcmp - - .extern __dcmp - -;------------------------------------------------------------------------------- diff --git a/src/crt/ftod.src b/src/crt/fptod.src similarity index 97% rename from src/crt/ftod.src rename to src/crt/fptod.src index 2a640d559..ef08ae9d4 100644 --- a/src/crt/ftod.src +++ b/src/crt/fptod.src @@ -4,11 +4,14 @@ .global __ftod .type __ftod, @function + .global __fptod + .type __fptod, @function ; input E:UHL (float) ; ouput BC:UDE:UHL (long double) ; NaN payloads are bitshifted __ftod: +__fptod: sla e ; extract signbit push af srl e diff --git a/test/floating_point/ez80sf/src/link_test.s b/test/floating_point/ez80sf/src/link_test.s index cc7326799..c675c0a6e 100644 --- a/test/floating_point/ez80sf/src/link_test.s +++ b/test/floating_point/ez80sf/src/link_test.s @@ -44,8 +44,8 @@ _link_test: ld hl, __lltofp ld hl, __ulltofp - ; ld hl, __fptod - ; ld hl, __dtofp + ld hl, __fptod + ld hl, __dtofp or a, a sbc hl, hl