Skip to content

Commit 6353419

Browse files
ZERICO2005mateoconlechuga
authored andcommitted
implemented i48div
1 parent 2a97b66 commit 6353419

File tree

4 files changed

+278
-2
lines changed

4 files changed

+278
-2
lines changed

src/libc/i48div.src

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,31 @@
22

33
section .text
44

5-
; public _i48div
5+
public _i48div
66

77
; i48div_t i48div(int48_t numer, int48_t denom);
8-
; _i48div:
8+
_i48div:
9+
; TODO: __i48dvrmu is called twice here
10+
push ix
11+
ld ix, 0
12+
add ix, sp
13+
ld hl, (ix + 9)
14+
ld de, (ix + 12)
15+
ld bc, (ix + 15)
16+
ld iy, (ix + 18)
17+
ld ix, (ix + 6)
18+
push hl
19+
push de
20+
call __i48divs
21+
ld (ix + 0), hl
22+
ld (ix + 3), de
23+
pop de
24+
pop hl
25+
call __i48rems
26+
ld (ix + 6), hl
27+
ld (ix + 9), de
28+
pop ix
29+
ret
30+
31+
extern __i48divs
32+
extern __i48rems
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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|1000",
12+
"hashWait|1",
13+
"key|enter",
14+
"delay|300",
15+
"hashWait|2"
16+
],
17+
"hashes": {
18+
"1": {
19+
"description": "All tests passed",
20+
"timeout": 5000,
21+
"start": "vram_start",
22+
"size": "vram_16_size",
23+
"expected_CRCs": [
24+
"38E2AD5A"
25+
]
26+
},
27+
"2": {
28+
"description": "Exit",
29+
"start": "vram_start",
30+
"size": "vram_16_size",
31+
"expected_CRCs": [
32+
"FFAF89BA",
33+
"101734A5",
34+
"9DA19F44",
35+
"A32840C8",
36+
"349F4775"
37+
]
38+
}
39+
}
40+
}

test/standalone/i48div/makefile

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# ----------------------------
2+
# Makefile Options
3+
# ----------------------------
4+
5+
NAME = DEMO
6+
ICON = icon.png
7+
DESCRIPTION = "CE C Toolchain Demo"
8+
COMPRESSED = NO
9+
ARCHIVED = NO
10+
11+
CFLAGS = -Wall -Wextra -Wshadow -Wconversion -Wformat=2 -Wno-sign-conversion -Oz
12+
CXXFLAGS = -Wall -Wextra -Wshadow -Wconversion -Wformat=2 -Wno-sign-conversion -Oz
13+
14+
PREFER_OS_LIBC = NO
15+
PREFER_OS_CRT = NO
16+
17+
# ----------------------------
18+
19+
include $(shell cedev-config --makefile)

test/standalone/i48div/src/main.c

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
#include <ti/screen.h>
2+
#include <ti/getcsc.h>
3+
#include <sys/util.h>
4+
#include <assert.h>
5+
#include <stdio.h>
6+
#include <stdbool.h>
7+
#include <stddef.h>
8+
#include <stdint.h>
9+
#include <stdlib.h>
10+
#include <string.h>
11+
#include <limits.h>
12+
#include <ti/sprintf.h>
13+
#include <ez80_builtin.h>
14+
15+
//------------------------------------------------------------------------------
16+
// Config
17+
//------------------------------------------------------------------------------
18+
19+
#define RANDOM_TEST_COUNT 256
20+
21+
// define to 0 or 1
22+
#define DEBUG_DIAGNOSTICS 0
23+
24+
#define AUTOTEST_SEED 0x7184CE
25+
26+
//------------------------------------------------------------------------------
27+
// Tests
28+
//------------------------------------------------------------------------------
29+
30+
#define C(expr) if (!(expr)) { return __LINE__; }
31+
32+
#define TEST(test) { ret = test; if (ret != 0) { return ret; }}
33+
34+
#ifndef DEBUG_DIAGNOSTICS
35+
#error "DEBUG_DIAGNOSTICS needs to be defined to 0 or 1"
36+
#endif
37+
38+
#if RANDOM_TEST_COUNT < 4
39+
#error "RANDOM_TEST_COUNT is out of range"
40+
#endif
41+
42+
#if DEBUG_DIAGNOSTICS
43+
#define test_printf printf
44+
#else
45+
#define test_printf(...)
46+
#endif
47+
48+
static_assert(RAND_MAX == INT_MAX, "RAND_MAX has changed");
49+
50+
#define rand8() ((int8_t)rand())
51+
52+
#define rand16() ((int16_t)rand())
53+
54+
__attribute__((__unused__)) static int24_t rand24(void) {
55+
union {
56+
int24_t u24;
57+
struct {
58+
uint16_t lo16;
59+
uint8_t hi8;
60+
} part;
61+
} split;
62+
split.part.lo16 = (uint16_t)rand();
63+
split.part.hi8 = (uint8_t)rand();
64+
return split.u24;
65+
}
66+
67+
__attribute__((__unused__)) static int32_t rand32(void) {
68+
union {
69+
int32_t u32;
70+
uint16_t u16[2];
71+
} split;
72+
split.u16[0] = (uint16_t)rand();
73+
split.u16[1] = (uint16_t)rand();
74+
return split.u32;
75+
}
76+
77+
__attribute__((__unused__)) static int48_t rand48(void) {
78+
union {
79+
int48_t u48;
80+
uint16_t u16[3];
81+
} split;
82+
split.u16[0] = (uint16_t)rand();
83+
split.u16[1] = (uint16_t)rand();
84+
split.u16[2] = (uint16_t)rand();
85+
return split.u48;
86+
}
87+
88+
__attribute__((__unused__)) static int64_t rand64(void) {
89+
union {
90+
int64_t u64;
91+
uint16_t u16[4];
92+
} split;
93+
split.u16[0] = (uint16_t)rand();
94+
split.u16[1] = (uint16_t)rand();
95+
split.u16[2] = (uint16_t)rand();
96+
split.u16[3] = (uint16_t)rand();
97+
return split.u64;
98+
}
99+
100+
static bool test_i48div(int48_t x, int48_t y) {
101+
if (y == 0) {
102+
// division by zero
103+
return true;
104+
}
105+
lldiv_t truth = lldiv((int64_t)x, (int64_t)y);
106+
i48div_t guess = i48div(x, y);
107+
if (
108+
((uint48_t)truth.quot != (uint48_t)guess.quot) ||
109+
((uint48_t)truth.rem != (uint48_t)guess.rem)
110+
) {
111+
test_printf(
112+
"XN: %012llX\nYD: %012llX\n"\
113+
"GQ: %012llX\nGR: %012llX\n"\
114+
"TQ: %012llX\nTR: %012llX\n",
115+
(uint64_t)(uint48_t)x , (uint64_t)(uint48_t)y,
116+
(uint64_t)(uint48_t)guess.quot, (uint64_t)(uint48_t)guess.rem,
117+
(uint64_t)(uint48_t)truth.quot, (uint64_t)(uint48_t)truth.rem
118+
);
119+
return false;
120+
}
121+
return true;
122+
}
123+
124+
int run_tests(void) {
125+
srand(AUTOTEST_SEED);
126+
127+
C(test_i48div( 0, 1));
128+
C(test_i48div( 1, 1));
129+
C(test_i48div( -1, 1));
130+
C(test_i48div( INT48_MAX, 1));
131+
C(test_i48div(-INT48_MAX, 1));
132+
C(test_i48div( INT48_MIN, 1));
133+
C(test_i48div( 0, -1));
134+
C(test_i48div( 1, -1));
135+
C(test_i48div( -1, -1));
136+
C(test_i48div( INT48_MAX, -1));
137+
C(test_i48div(-INT48_MAX, -1));
138+
C(test_i48div( INT48_MIN, -1));
139+
C(test_i48div( 0, INT48_MAX));
140+
C(test_i48div( 1, INT48_MAX));
141+
C(test_i48div( -1, INT48_MAX));
142+
C(test_i48div( 0, -INT48_MAX));
143+
C(test_i48div( 1, -INT48_MAX));
144+
C(test_i48div( -1, -INT48_MAX));
145+
C(test_i48div( 0, INT48_MIN));
146+
C(test_i48div( 1, INT48_MIN));
147+
C(test_i48div( -1, INT48_MIN));
148+
C(test_i48div( INT48_MAX, INT48_MAX));
149+
C(test_i48div( INT48_MAX, -INT48_MAX));
150+
C(test_i48div( INT48_MAX, INT48_MIN));
151+
C(test_i48div(-INT48_MAX, INT48_MAX));
152+
C(test_i48div(-INT48_MAX, -INT48_MAX));
153+
C(test_i48div(-INT48_MAX, INT48_MIN));
154+
C(test_i48div( INT48_MIN, INT48_MAX));
155+
C(test_i48div( INT48_MIN, -INT48_MAX));
156+
C(test_i48div( INT48_MIN, INT48_MIN));
157+
158+
for (int i = 0; i < RANDOM_TEST_COUNT; i++) {
159+
if (!test_i48div(rand48(), rand48())) {
160+
return __LINE__;
161+
}
162+
}
163+
164+
for (int i = 0; i < RANDOM_TEST_COUNT; i++) {
165+
if (!test_i48div(rand48(), rand24())) {
166+
return __LINE__;
167+
}
168+
}
169+
170+
for (int i = 0; i < RANDOM_TEST_COUNT; i++) {
171+
if (!test_i48div(rand48(), rand8())) {
172+
return __LINE__;
173+
}
174+
}
175+
176+
return 0;
177+
}
178+
179+
int main(void) {
180+
os_ClrHome();
181+
int failed_test = run_tests();
182+
if (failed_test != 0) {
183+
char buf[sizeof("Failed test L-8388608\n")];
184+
boot_sprintf(buf, "Failed test L%d\n", failed_test);
185+
fputs(buf, stdout);
186+
} else {
187+
fputs("All tests passed", stdout);
188+
}
189+
190+
while (!os_GetCSC());
191+
192+
return 0;
193+
}

0 commit comments

Comments
 (0)