Skip to content

Commit d13be1a

Browse files
ZERICO2005mateoconlechuga
authored andcommitted
added swab to <unistd.h>
1 parent 15cf48e commit d13be1a

6 files changed

Lines changed: 299 additions & 0 deletions

File tree

src/libc/include/unistd.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,17 @@
1414
#define STDOUT_FILENO 1
1515
#define STDERR_FILENO 2
1616

17+
#ifndef _SSIZE_T_DEFINED
18+
#define _SSIZE_T_DEFINED
19+
typedef __PTRDIFF_TYPE__ ssize_t;
20+
#endif /* _SSIZE_T_DEFINED */
21+
1722
__BEGIN_DECLS
1823

1924
int isatty(int fd);
2025

26+
void swab(const void *__restrict src, void *__restrict dst, ssize_t count);
27+
2128
__END_DECLS
2229

2330
#endif /* _UNISTD_H */

src/libc/swab.src

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
.assume adl=1
2+
3+
.section .text
4+
5+
.global _swab
6+
.type _swab, @function
7+
8+
.if 1
9+
10+
; void swab(const void *__restrict src, void *__restrict dst, ssize_t count)
11+
_swab:
12+
; swab has unspecified behaviour when count is odd:
13+
; - this implementation treats an odd count as if it were count - 1
14+
; - does nothing when count <= 1 or count is negative
15+
ld iy, 0
16+
add iy, sp
17+
sra (iy + 11)
18+
ret m ; do nothing when negative
19+
ld bc, (iy + 9)
20+
rr b
21+
rr c
22+
; BC = count / 2
23+
sbc hl, hl
24+
adc hl, bc
25+
ret z ; count <= 1
26+
ld de, (iy + 6) ; DE = dst
27+
ld hl, (iy + 3) ; HL = src
28+
.L.loop:
29+
ld a, (hl) ; A = src.lo
30+
inc hl
31+
ldi ; dst.lo = src.hi
32+
ld (de), a ; dst.hi = A
33+
inc de
34+
jp pe, .L.loop
35+
ret
36+
37+
.else
38+
39+
; void swab(const void *__restrict src, void *__restrict dst, ssize_t count)
40+
_swab:
41+
; swab has unspecified behaviour when count is odd:
42+
; - this implementation will copy dst[count - 1] to src[count - 1] when count is odd
43+
; - does nothing when count <= 0 or count is negative
44+
ld iy, 0
45+
add iy, sp
46+
sra (iy + 11)
47+
ret m ; do nothing when negative
48+
ld bc, (iy + 9)
49+
rr b
50+
rr c
51+
; BC = count / 2
52+
sbc hl, hl
53+
adc hl, bc
54+
; Carry is set when count is odd
55+
ld de, (iy + 6) ; DE = dst
56+
ld hl, (iy + 3) ; HL = src
57+
jr z, .L.finish
58+
.L.loop:
59+
ld a, (hl) ; A = src.lo
60+
inc hl
61+
ldi ; dst.lo = src.hi
62+
ld (de), a ; dst.hi = A
63+
inc de
64+
jp pe, .L.loop
65+
.L.finish:
66+
ret nc ; even count
67+
; copy one more byte
68+
ld a, (hl)
69+
ld (de), a
70+
ret
71+
72+
.endif

test/standalone/swab/autotest.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"transfer_files":
3+
[
4+
"bin/DEMO.8xp"
5+
],
6+
"target":
7+
{
8+
"name": "DEMO",
9+
"isASM": true
10+
},
11+
"sequence":
12+
[
13+
"action|launch",
14+
"delay|500",
15+
"hashWait|1",
16+
"key|enter",
17+
"delay|300",
18+
"hashWait|2"
19+
],
20+
"hashes":
21+
{
22+
"1":
23+
{
24+
"description": "All tests passed",
25+
"start": "vram_start",
26+
"size": "vram_16_size",
27+
"expected_CRCs": [ "38E2AD5A" ]
28+
},
29+
"2":
30+
{
31+
"description": "Test homescreen cleared",
32+
"start": "vram_start",
33+
"size": "vram_16_size",
34+
"expected_CRCs": [ "FFAF89BA", "101734A5", "9DA19F44", "A32840C8", "349F4775" ]
35+
}
36+
}
37+
}

test/standalone/swab/makefile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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 -ffreestanding -Oz
12+
CXXFLAGS = -Wall -Wextra -ffreestanding -Oz
13+
14+
# ----------------------------
15+
16+
include $(shell cedev-config --makefile)

test/standalone/swab/src/main.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#include <stdio.h>
2+
#include <ti/screen.h>
3+
#include <ti/getcsc.h>
4+
#include <ti/sprintf.h>
5+
#include <sys/util.h>
6+
7+
int run_tests(void);
8+
9+
int main(void) {
10+
os_ClrHome();
11+
int failed_test = run_tests();
12+
if (failed_test != 0) {
13+
char buf[sizeof("Failed test L-8388608")];
14+
boot_sprintf(buf, "Failed test L%d", failed_test);
15+
puts(buf);
16+
} else {
17+
puts("All tests passed");
18+
}
19+
20+
while (!os_GetCSC());
21+
22+
return 0;
23+
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
#include <unistd.h>
2+
#include <string.h>
3+
#include <limits.h>
4+
#include <alloca.h>
5+
6+
#define C(expr) if (!(expr)) { return __LINE__; }
7+
8+
int run_tests(void) {
9+
const unsigned char src[7] = {
10+
0, 1, 2, 3, 4, 5, 6
11+
};
12+
const unsigned char pattern[7] = {
13+
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6
14+
};
15+
unsigned char dst[7];
16+
17+
// swab does nothing if count is 0 or negative
18+
19+
memcpy(dst, pattern, sizeof(dst));
20+
swab(&src[2], &dst[2], 0);
21+
C(memcmp(dst, pattern, sizeof(dst)) == 0);
22+
23+
memcpy(dst, pattern, sizeof(dst));
24+
swab(&src[2], &dst[2], -1);
25+
C(memcmp(dst, pattern, sizeof(dst)) == 0);
26+
27+
memcpy(dst, pattern, sizeof(dst));
28+
swab(&src[2], &dst[2], INT_MIN);
29+
C(memcmp(dst, pattern, sizeof(dst)) == 0);
30+
31+
// test non-zero amounts
32+
33+
memcpy(dst, pattern, sizeof(dst));
34+
swab(&src[2], &dst[2], 1);
35+
C(dst[0] == 0xF0);
36+
C(dst[1] == 0xF1);
37+
// dst[2] is undefined
38+
C(dst[3] == 0xF3);
39+
C(dst[4] == 0xF4);
40+
C(dst[5] == 0xF5);
41+
C(dst[6] == 0xF6);
42+
43+
memcpy(dst, pattern, sizeof(dst));
44+
swab(&src[2], &dst[2], 2);
45+
C(dst[0] == 0xF0);
46+
C(dst[1] == 0xF1);
47+
C(dst[2] == 3);
48+
C(dst[3] == 2);
49+
C(dst[4] == 0xF4);
50+
C(dst[5] == 0xF5);
51+
C(dst[6] == 0xF6);
52+
53+
memcpy(dst, pattern, sizeof(dst));
54+
swab(&src[2], &dst[2], 3);
55+
C(dst[0] == 0xF0);
56+
C(dst[1] == 0xF1);
57+
C(dst[2] == 3);
58+
C(dst[3] == 2);
59+
// dst[4] is undefined
60+
C(dst[5] == 0xF5);
61+
C(dst[6] == 0xF6);
62+
63+
memcpy(dst, pattern, sizeof(dst));
64+
swab(&src[1], &dst[1], 4);
65+
C(dst[0] == 0xF0);
66+
C(dst[1] == 2);
67+
C(dst[2] == 1);
68+
C(dst[3] == 4);
69+
C(dst[4] == 3);
70+
C(dst[5] == 0xF5);
71+
C(dst[6] == 0xF6);
72+
73+
memcpy(dst, pattern, sizeof(dst));
74+
swab(&src[1], &dst[1], 4);
75+
C(dst[0] == 0xF0);
76+
C(dst[1] == 2);
77+
C(dst[2] == 1);
78+
C(dst[3] == 4);
79+
C(dst[4] == 3);
80+
C(dst[5] == 0xF5);
81+
C(dst[6] == 0xF6);
82+
83+
memcpy(dst, pattern, sizeof(dst));
84+
swab(&src[2], &dst[2], 4);
85+
C(dst[0] == 0xF0);
86+
C(dst[1] == 0xF1);
87+
C(dst[2] == 3);
88+
C(dst[3] == 2);
89+
C(dst[4] == 5);
90+
C(dst[5] == 4);
91+
C(dst[6] == 0xF6);
92+
93+
memcpy(dst, pattern, sizeof(dst));
94+
swab(&src[1], &dst[1], 5);
95+
C(dst[0] == 0xF0);
96+
C(dst[1] == 2);
97+
C(dst[2] == 1);
98+
C(dst[3] == 4);
99+
C(dst[4] == 3);
100+
// dst[5] is undefined
101+
C(dst[6] == 0xF6);
102+
103+
/* large test */ {
104+
unsigned char * large_src = alloca(256);
105+
unsigned char * large_dst = alloca(256);
106+
107+
// setup src
108+
for (int i = 0; i < 256; i++) {
109+
large_src[i] = (unsigned char)i;
110+
}
111+
112+
// setup canary
113+
large_dst[255] = 42;
114+
swab(large_src, large_dst, 255);
115+
116+
// large_dst[254] is undefined
117+
for (int i = 0; i < 254; i++) {
118+
if (i % 2 == 0) {
119+
C(large_src[i] == large_dst[i + 1]);
120+
} else {
121+
C(large_src[i] == large_dst[i - 1]);
122+
}
123+
}
124+
125+
// test that the canary was not overwritten
126+
C(large_dst[255] == 42);
127+
swab(large_src, large_dst, 256);
128+
for (int i = 0; i < 256; i++) {
129+
if (i % 2 == 0) {
130+
C(large_src[i] == large_dst[i + 1]);
131+
} else {
132+
C(large_src[i] == large_dst[i - 1]);
133+
}
134+
}
135+
136+
// swab is an involute function
137+
swab(large_dst, large_src, 256);
138+
for (int i = 0; i < 256; i++) {
139+
C(large_src[i] == (unsigned char)i);
140+
}
141+
}
142+
143+
return 0;
144+
}

0 commit comments

Comments
 (0)