Skip to content

Commit b572736

Browse files
ZERICO2005mateoconlechuga
authored andcommitted
Fixed __ftoull
1 parent ce6a219 commit b572736

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

src/crt/ftoll.src

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
assume adl=1
22

33
section .text
4-
public __ftoll, __ftoull
4+
5+
public __ftoll
56
__ftoll:
6-
__ftoull:
77
ld d, a
88
push iy, de, hl
99
call __ftoll_c

src/crt/ftoull.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
#include <stdbool.h>
2+
#include <stdint.h>
3+
4+
typedef union F32_pun {
5+
float flt;
6+
uint32_t bin;
7+
struct {
8+
uint24_t UHL;
9+
uint8_t E;
10+
} reg;
11+
} F32_pun;
12+
13+
#define Float32_pos_one UINT32_C(0x3F800000)
14+
#define Float32_bias 127
15+
#define Float32_mant_bits 23
16+
#define Float32_u64_max_exp 64
17+
18+
// this should be easy to rewrite in assembly
19+
uint64_t _ftoull_c(float x) {
20+
F32_pun val;
21+
val.flt = x;
22+
// if trunc(x) is zero or x is negative
23+
if ((int32_t)val.bin < (int32_t)Float32_pos_one) {
24+
/* undefined return value for negative inputs */
25+
return 0;
26+
}
27+
// signbit is zero here
28+
uint8_t expon = (uint8_t)(val.bin >> 23);
29+
// doesn't underflow since 1.0 - Float32_bias gives us an exponent of zero
30+
expon -= Float32_bias;
31+
if (expon >= Float32_u64_max_exp) {
32+
/* undefined return value for overflow */
33+
return 0;
34+
}
35+
// sets the LSB of the exponent since x is normalized
36+
uint24_t mant = val.reg.UHL | 0x800000;
37+
if (expon < Float32_mant_bits) {
38+
mant >>= Float32_mant_bits - expon;
39+
return mant;
40+
}
41+
/* expon >= 23 or [23, 63] */
42+
return (uint64_t)mant << (expon - Float32_mant_bits);
43+
}

src/crt/ftoull.src

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
assume adl=1
2+
3+
section .text
4+
5+
public __ftoull
6+
__ftoull:
7+
ld d, a
8+
push iy, de, hl
9+
call __ftoull_c
10+
pop af, af, iy
11+
ret
12+
13+
extern __ftoull_c

0 commit comments

Comments
 (0)