Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/crt/dabs.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.assume adl=1

.section .text

.global __dabs
.type __dabs, @function

; assumes BC:UDE:UHL
__dabs:
res 7, b
ret
64 changes: 64 additions & 0 deletions src/crt/dcmpo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <math.h>
#include <stdbool.h>
#include <stdint.h>

typedef union {
struct {
uint8_t carry : 1;
uint8_t : 5;
uint8_t zero : 1;
uint8_t sign : 1;
};
uint8_t bin;
} Flags;

typedef union {
long double flt;
uint64_t bin;
} F64_pun;

typedef struct {
long double x;
uint8_t x_padding;
unsigned int const return_address;
long double y;
uint8_t y_padding;
} f64_cmp_arg;

uint8_t _dcmpo_c(f64_cmp_arg const *__restrict const arg) {
F64_pun x, y;
x.flt = arg->x;
y.flt = arg->y;
Flags flags;
if (_isnanl(x.flt) || _isnanl(y.flt)) {
flags.zero = 0;
flags.carry = 0;
flags.sign = 1;
return flags.bin;
}
bool x_sign = _signbitl(x.flt);
bool y_sign = _signbitl(y.flt);
if (x_sign != y_sign) {
if (_iszerol(x.flt) && _iszerol(y.flt)) {
flags.zero = 1;
flags.carry = 0;
flags.sign = 0;
return flags.bin;
}
flags.zero = 0;
flags.carry = x_sign ? 1 : 0;
flags.sign = x_sign ? 1 : 0;
return flags.bin;
}
if (x.bin == y.bin) {
flags.zero = 1;
flags.carry = 0;
flags.sign = 0;
return flags.bin;
}
bool cmp_less = ((x.bin < y.bin) != x_sign);
flags.zero = 0;
flags.carry = cmp_less ? 1 : 0;
flags.sign = cmp_less ? 1 : 0;
return flags.bin;
}
68 changes: 68 additions & 0 deletions src/crt/dcmpo.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
.assume adl=1

.section .text.__dcmpo

.global __dcmpo
.type __dcmpo, @function

__dcmpo:
push bc
push de
push hl
or a, a
sbc hl, hl
add hl, sp
push iy
push af
push hl ; f64_cmp_arg*
call __dcmpo_c
ld l, a
pop af
pop af
pop iy

; Set the comparison flags
ld h, a
ex (sp), hl
pop af

pop de
pop bc
ret

.section .text.__dcmpu

.global __dcmpu
.type __dcmpu, @function

__dcmpu:
push bc
push de
push hl
or a, a
sbc hl, hl
add hl, sp
push iy
push af
push hl ; f64_cmp_arg*
call __dcmpo_c
ld l, a
pop af
pop af
pop iy

; Set the comparison flags
ld h, a
ex (sp), hl
pop af

pop de
pop bc
ret c ; If BC:UDE:UHL < (SP64): C = 1, Z = 0
scf
ret p ; If BC:UDE:UHL >= (SP64): C = 1, Z = (BC:UDE:UHL == (SP64))
cp a, a ; If unordered: C = 0, Z = 1
ret

; uint8_t _dcmpo_c(f64_cmp_arg const *__restrict const arg)
.extern __dcmpo_c
7 changes: 5 additions & 2 deletions src/crt/dtof.src → src/crt/dtofp.src
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down
12 changes: 12 additions & 0 deletions src/crt/fpabs.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.assume adl=1

.section .text

.global __fpabs
.type __fpabs, @function

; 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
Loading
Loading