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
1 change: 1 addition & 0 deletions src/libc/header_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@
#include <tgmath.h>
#include <time.h>
#include <wchar.h>
#include <wctype.h>

/* Tests for conflicts */
36 changes: 36 additions & 0 deletions src/libc/include/__wchar_def.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#ifndef _WCHAR_DEF_H
#define _WCHAR_DEF_H

#include <cdefs.h>

#ifndef _WCHAR_T_DEFINED
#define _WCHAR_T_DEFINED
#ifndef __cplusplus
typedef __WCHAR_TYPE__ wchar_t;
#endif /* __cplusplus */
#endif /* _WCHAR_T_DEFINED */

#ifndef _WINT_T_DEFINED
#define _WINT_T_DEFINED
typedef __WINT_TYPE__ wint_t;
#endif /* _WINT_T_DEFINED */

#ifndef _WCHAR_LIMITS_DEFINED
#define _WCHAR_LIMITS_DEFINED
#define WCHAR_MIN (~__WCHAR_MAX__)
#define WCHAR_MAX __WCHAR_MAX__
#define WCHAR_WIDTH __WCHAR_WIDTH__
#endif /* _WCHAR_LIMITS_DEFINED */

#ifndef _WINT_LIMITS_DEFINED
#define _WINT_LIMITS_DEFINED
#define WINT_MIN (~__WINT_MAX__)
#define WINT_MAX __WINT_MAX__
#define WINT_WIDTH __WINT_WIDTH__
#endif /* _WINT_LIMITS_DEFINED */

#ifndef WEOF
#define WEOF -1
#endif

#endif /* _WCHAR_DEF_H */
13 changes: 8 additions & 5 deletions src/libc/include/stdint.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,18 @@ typedef __UINTPTR_TYPE__ uintptr_t;
#define SIZE_MAX __SIZE_MAX__
#define SIZE_WIDTH __SIZE_WIDTH__

#define WINT_MIN (~__WINT_MAX__)
#define WINT_MAX __WINT_MAX__
#define WINT_WIDTH __WINT_WIDTH__

#ifndef _WCHAR_LIMITS_DEFINED
#define _WCHAR_LIMITS_DEFINED
#define WCHAR_MIN (~__WCHAR_MAX__)
#define WCHAR_MAX __WCHAR_MAX__
#define WCHAR_WIDTH __WCHAR_WIDTH__
#endif
#endif /* _WCHAR_LIMITS_DEFINED */

#ifndef _WINT_LIMITS_DEFINED
#define _WINT_LIMITS_DEFINED
#define WINT_MIN (~__WINT_MAX__)
#define WINT_MAX __WINT_MAX__
#define WINT_WIDTH __WINT_WIDTH__
#endif /* _WINT_LIMITS_DEFINED */

#endif/*_STDINT_H*/
22 changes: 2 additions & 20 deletions src/libc/include/wchar.h
Original file line number Diff line number Diff line change
@@ -1,25 +1,7 @@
#ifndef _WCHAR_H
#define _WCHAR_H

#include <cdefs.h>

#ifndef _WCHAR_T_DEFINED
#define _WCHAR_T_DEFINED
#ifndef __cplusplus
typedef __WCHAR_TYPE__ wchar_t;
#endif /* __cplusplus */
#endif /* _WCHAR_T_DEFINED */

#ifndef _WCHAR_LIMITS_DEFINED
#define _WCHAR_LIMITS_DEFINED
#define WCHAR_WIDTH __WCHAR_WIDTH__
#define WCHAR_MIN (~__WCHAR_MAX__)
#define WCHAR_MAX __WCHAR_MAX__
#endif

#ifndef WEOF
#define WEOF -1
#endif
#include <__wchar_def.h>

__BEGIN_DECLS

Expand Down Expand Up @@ -75,7 +57,7 @@ size_t wcslen(const wchar_t *s)
__attribute__((nonnull(1)));

size_t wcsnlen(const wchar_t *s, size_t maxlen)
__attribute__((nonnull(1)));
__NOEXCEPT __attribute__((nonnull(1))) __attribute__((__pure__));

int wcscmp(const wchar_t *s1, const wchar_t *s2)
__attribute__((nonnull(1, 2)));
Expand Down
38 changes: 38 additions & 0 deletions src/libc/include/wctype.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef _WCTYPE_H
#define _WCTYPE_H

#include <__wchar_def.h>

__BEGIN_DECLS

int iswalnum(wint_t wc);

int iswalpha(wint_t wc);

int iswblank(wint_t wc);

int iswcntrl(wint_t wc);

int iswdigit(wint_t wc);

int iswgraph(wint_t wc);

int iswlower(wint_t wc);

int iswprint(wint_t wc);

int iswpunct(wint_t wc);

int iswspace(wint_t wc);

int iswupper(wint_t wc);

int iswxdigit(wint_t wc);

wint_t towlower(wint_t wc);

wint_t towupper(wint_t wc);

__END_DECLS

#endif /* _WCTYPE_H */
23 changes: 23 additions & 0 deletions src/libc/wcslen.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
assume adl=1

section .text

public _wcslen

; size_t wcslen(const wchar_t *str)
_wcslen:
pop bc
ex (sp), hl
push bc
ld bc, 1
xor a, a
dec hl
.loop:
inc hl
cpi
jr nz, .loop
cp a, (hl)
jr nz, .loop
sbc hl, hl
sbc hl, bc
ret
44 changes: 44 additions & 0 deletions src/libc/wcsnlen.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
assume adl=1

section .text

public _wcsnlen

; size_t wcsnlen(const wchar_t *str, size_t maxlen)
_wcsnlen:
ld hl, 6
add hl, sp
ld bc, (hl)
dec hl
dec hl
dec hl
ld de, (hl)
xor a, a
sbc hl, hl
adc hl, bc
ret z
ex de, hl
call .loop_start
ex de, hl
; return maxlen unless str[maxlen - 1] == L'\0'
ret nz ; low byte was non-zero
ld a, (de)
cp a, c ; cp a, 0
ret nz ; high byte was non-zero
dec hl
; ret ; We can use the RET PO below since overflow won't be set
.loop_lo:
ret po
.loop_hi:
inc hl
.loop_start:
cpi
jr nz, .loop_lo
ret po
cp a, (hl)
jr nz, .loop_hi
ex de, hl
pop de ; reset SP
scf
sbc hl, bc
ret
39 changes: 39 additions & 0 deletions src/libc/wmemchr.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
assume adl=1

section .text

public _wmemchr

; wchar_t *wmemchr(const wchar_t *ptr, int ch, size_t count)
_wmemchr:
ld iy, 0
add iy, sp
ld hl, (iy + 9)
adc hl, hl ; count *= 2
ret z ; return NULL
push hl
pop bc ; BC = count * 2
ld hl, (iy + 3)
ld de, (iy + 6) ; E = lower byte, D = upper byte
call .loop_start
.ret_null:
or a, a
sbc hl, hl
ret

.loop_start:
.no_match:
ld a, e
.loop:
cpir
ret po ; return NULL
; repeat until BC is odd
bit 0, c
jr z, .loop
; lower byte matches, now check the upper byte
ld a, d
xor a, (hl)
jr nz, .no_match
pop bc ; reset SP
dec hl
ret
46 changes: 46 additions & 0 deletions src/libc/wmemcmp.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
assume adl=1

section .text

public _wmemcmp

; int wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n)
_wmemcmp:
ld iy, 0
add iy, sp
ld bc, (iy + 9)
sbc hl, hl
adc hl, bc ; count *= 2
ret z ; return 0
ld de, (iy + 3)
ld hl, (iy + 6)
.loop:
ld a, (de)
xor a, (hl)
inc hl
inc de
ld a, (de)
jr nz, .low_diff
cpi
jr nz, .high_diff
inc de
jp pe, .loop
sbc hl, hl
ret

.high_diff:
dec hl
.low_diff:
; compare high bytes
sub a, (hl) ; s1 - s2
jr nz, .skip_low_check
; compare low bytes
dec de
ld a, (de)
dec hl
sub a, (hl) ; s1 - s2
.skip_low_check:
sbc hl, hl
; A is non-zero here
ld l, a
ret
32 changes: 32 additions & 0 deletions src/libc/wmemcpy.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
assume adl=1

section .text

public _wmemcpy

; CC: !count ? 19*r(PC) + 9*r(SPL) + 3*w(SPL) + 1
; : 25*r(PC) + 18*r(SPL) + 12*w(SPL) + count*(r(src) + w(dest) + 1)
; C: wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, size_t count) {
_wmemcpy:
; C: size_t count2 = count * sizeof(wchar_t);
ld hl, 9
add hl, sp
ld hl, (hl) ; hl = count
adc hl, hl ; hl = count * 2
; = count2
; C: if (count2) {
pop iy ; iy = ret
jr z, .zero
; C: __ldir(src, dest, count2);
pop de ; de = dest
ex (sp), hl ; hl = src
pop bc ; bc = count2
push bc
push de
ldir
; C: }
.zero:
; C: return dest;
ex (sp), hl
jp (iy)
; C: }
16 changes: 16 additions & 0 deletions src/libc/wmemmove.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
assume adl=1

section .text

public _wmemmove

; wchar_t *wmemmove(wchar_t *dest, const wchar_t *src, size_t count)
_wmemmove:
ld hl, 9
add hl, sp
ld iy, (hl)
add iy, iy ; count *= 2
ld (hl), iy
jp _memmove

extern _memmove
40 changes: 40 additions & 0 deletions src/libc/wmemset.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
assume adl=1

section .text

public _wmemset

; wchar_t *wmemset(wchar_t *dst, wchar_t ch, size_t count)
_wmemset:
pop iy, hl, de, bc
push bc, de, hl, iy
; BC = count
; DE = ch
; HL = dst

; count *= sizeof(wchar_t)
cpi ; hl++ bc--
add hl, bc ; HL = (dst + 1) + (count - 1) = dst + count
ret c ; bc is zero
add hl, bc ; HL = dst + count + (count - 1) = dst + 2 * count - 1

; hl += (count - 1) * 2 + 1
; count -= 2
ld (hl), d ; upper 8 bits
dec hl
ld (hl), e ; lower 8 bits
ret po ; only one element needs to be written

; write multiple elements
push hl
pop de
inc hl
dec de

push bc
; use lddr twice
lddr
pop bc
lddr
dec hl
ret
Loading
Loading