Skip to content

Commit afded7e

Browse files
committed
implemented fminf/fmaxf in assembly
1 parent af35bd7 commit afded7e

File tree

7 files changed

+4396
-32
lines changed

7 files changed

+4396
-32
lines changed

src/libc/fmin.c

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/libc/fminmaxf.src

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
assume adl=1
2+
3+
; fminf and fmaxf treat signed zeros as -0.0f < +0.0f.
4+
;
5+
; The same result will be returned no matter the order of the arguments unless
6+
; both arguments are NaN.
7+
;
8+
; If both values are NaN, a NaN value will be returned. However, it is
9+
; unspecified whether the first, second, or a different NaN is returned.
10+
11+
;-------------------------------------------------------------------------------
12+
13+
section .text
14+
15+
public _fminf
16+
public _fmin
17+
18+
_fmin:
19+
_fminf:
20+
ld iy, 0
21+
add iy, sp
22+
ld bc, $010000
23+
ld de, (iy + 4) ; upper 24 bits of X
24+
ld hl, (iy + 10) ; upper 24 bits of Y
25+
xor a, a
26+
add hl, hl ; Y
27+
adc a, b
28+
ex de, hl
29+
add hl, hl ; X
30+
sbc a, b
31+
; (X+, Y+): A = 0 NC Z ; compare
32+
; (X-, Y-): A = 0 NC Z ; invert compare
33+
; (X-, Y+): A = -1 C NZ ; X < Y
34+
; (X+, Y-): A = +1 NC NZ ; X > Y
35+
jr nz, .different_sign
36+
; .same_sign:
37+
sbc hl, de ; X - Y
38+
add hl, de
39+
jr nz, .x_and_y_diff
40+
ld a, (iy + 3)
41+
cp a, (iy + 9)
42+
.x_and_y_diff:
43+
sbc a, a
44+
xor a, (iy + 6) ; invert the comparison
45+
add a, a
46+
.different_sign:
47+
jr c, _fminmaxf_common.no_swap
48+
; .swap:
49+
ex de, hl
50+
add hl, bc ; overflows for NaN and Inf
51+
jr c, _fminmaxf_common.y_maybe_NaN
52+
53+
;-------------------------------------------------------------------------------
54+
55+
section .text
56+
57+
private _fminmaxf_common.no_swap
58+
private _fminmaxf_common.y_maybe_NaN
59+
60+
_fminmaxf_common:
61+
.return_y:
62+
ld hl, (iy + 9)
63+
ld e, (iy + 12)
64+
ret
65+
66+
.y_maybe_NaN:
67+
ld a, l
68+
or a, h
69+
or a, (iy + 9)
70+
jr z, .return_y ; infinity
71+
; jr .return_x
72+
73+
.no_swap:
74+
add hl, bc ; overflows for NaN and Inf
75+
jr c, .x_maybe_NaN
76+
.return_x:
77+
ld hl, (iy + 3)
78+
ld e, (iy + 6)
79+
ret
80+
81+
.x_maybe_NaN:
82+
ld a, l
83+
or a, h
84+
or a, (iy + 3)
85+
jr z, .return_x ; infinity
86+
jr .return_y
87+
88+
;-------------------------------------------------------------------------------
89+
90+
section .text
91+
92+
public _fmaxf
93+
public _fmax
94+
95+
_fmax:
96+
_fmaxf:
97+
ld iy, 0
98+
add iy, sp
99+
ld bc, $010000
100+
ld de, (iy + 4) ; upper 24 bits of X
101+
ld hl, (iy + 10) ; upper 24 bits of Y
102+
xor a, a
103+
add hl, hl ; Y
104+
adc a, b
105+
ex de, hl
106+
add hl, hl ; X
107+
sbc a, b
108+
; (X+, Y+): A = 0 NC Z ; compare
109+
; (X-, Y-): A = 0 NC Z ; invert compare
110+
; (X-, Y+): A = -1 C NZ ; X < Y
111+
; (X+, Y-): A = +1 NC NZ ; X > Y
112+
jr nz, .different_sign
113+
; .same_sign:
114+
sbc hl, de ; X - Y
115+
add hl, de
116+
jr nz, .x_and_y_diff
117+
ld a, (iy + 3)
118+
cp a, (iy + 9)
119+
.x_and_y_diff:
120+
sbc a, a
121+
xor a, (iy + 6) ; invert the comparison
122+
add a, a
123+
.different_sign:
124+
jr nc, _fminmaxf_common.no_swap
125+
; .swap:
126+
ex de, hl
127+
add hl, bc ; overflows for NaN and Inf
128+
jr c, _fminmaxf_common.y_maybe_NaN
129+
.return_y:
130+
ld hl, (iy + 9)
131+
ld e, (iy + 12)
132+
ret
Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <math.h>
22

3-
float fmaxf(float x, float y) {
3+
long double fmaxl(long double x, long double y) {
44
return
55
isless(x, y) ? y :
66
isless(y, x) ? x :
@@ -11,15 +11,13 @@ float fmaxf(float x, float y) {
1111
signbit(x) ? y : x;
1212
}
1313

14-
double fmax(double, double) __attribute__((alias("fmaxf")));
15-
16-
long double fmaxl(long double x, long double y) {
14+
long double fminl(long double x, long double y) {
1715
return
18-
isless(x, y) ? y :
19-
isless(y, x) ? x :
16+
isless(x, y) ? x :
17+
isless(y, x) ? y :
2018
/* attempts to return a non-NaN value */
2119
isnan(x) ? y :
2220
isnan(y) ? x :
2321
/* arguments are equal or signed zero */
24-
signbit(x) ? y : x;
22+
signbit(x) ? x : y;
2523
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{
2+
"transfer_files": [
3+
"bin/DEMO.8xp"
4+
],
5+
"target": {
6+
"name": "DEMO",
7+
"isASM": true
8+
},
9+
"sequence": [
10+
"action|launch",
11+
"delay|4000",
12+
"hashWait|1",
13+
"key|enter",
14+
"delay|400",
15+
"hashWait|2"
16+
],
17+
"hashes": {
18+
"1": {
19+
"description": "All tests passed or GDB1 error",
20+
"timeout": 6000,
21+
"start": "vram_start",
22+
"size": "vram_16_size",
23+
"expected_CRCs": [
24+
"38E2AD5A",
25+
"2C812DC2"
26+
]
27+
},
28+
"2": {
29+
"description": "Exit or GDB1 error",
30+
"start": "vram_start",
31+
"size": "vram_16_size",
32+
"expected_CRCs": [
33+
"FFAF89BA",
34+
"101734A5",
35+
"9DA19F44",
36+
"A32840C8",
37+
"349F4775",
38+
"271A9FBF",
39+
"82FD0B1E"
40+
]
41+
}
42+
}
43+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# ----------------------------
2+
# Makefile Options
3+
# ----------------------------
4+
5+
NAME = DEMO
6+
ICON = icon.png
7+
DESCRIPTION = "CE C Toolchain Demo"
8+
COMPRESSED = NO
9+
10+
COMMON_FLAGS = -Wall -Wextra -Wshadow -Wformat=2 -Wconversion -Wimplicit-float-conversion -Wimplicit-int-float-conversion
11+
COMMON_FLAGS += -Oz -ffreestanding
12+
13+
CFLAGS = ${COMMON_FLAGS} -std=c17
14+
CXXFLAGS = ${COMMON_FLAGS} -std=c++20
15+
16+
PREFER_OS_LIBC = NO
17+
18+
# ----------------------------
19+
20+
include $(shell cedev-config --makefile)

0 commit comments

Comments
 (0)