Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

strncasecmp fix and optimizations #480

Merged
merged 2 commits into from
Mar 19, 2024
Merged
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
2 changes: 0 additions & 2 deletions src/libc/os.src
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ _strlen := 0000D4h
_strncat := 0000D8h
public _strncmp
_strncmp := 0000DCh
public _strcasecmp
_strcasecmp := 021E3Ch
public _strncpy
_strncpy := 0000E0h
public _strpbrk
Expand Down
95 changes: 95 additions & 0 deletions src/libc/strcasecmp.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
assume adl=1

section .text
public _strcasecmp

if PREFER_OS_LIBC

_strcasecmp := 021E3Ch

else

_strcasecmp:
pop iy
pop de
ex (sp), hl
push de
ld b, 1+'z'-'a'
ld c, 'a'-'A'
jr .loop_entry
.loop:
cp a, (hl)
jr z, .done
.loop_nonnull:
inc hl
inc de
.loop_entry:
ld a, (de)
xor a, (hl)
jr z, .loop
cp a, c
jr nz, .mismatch
or a, (hl)
sub a, 'a'
cp a, b
jr c, .loop_nonnull

end if

section .text
public _strcasecmp.mismatch
public _strcasecmp.done
_strcasecmp.mismatch:
ld l, (hl)
call _tolower.internal
ex de, hl
ld l, (hl)
call _tolower.internal
ld a, l
sub a, e
_strcasecmp.done:
sbc hl, hl
ld l, a
jp (iy)

section .text
public _strncasecmp
_strncasecmp:
pop iy
pop de
pop hl
pop bc
push bc
push de
push hl

scf
sbc hl, hl
add hl, bc
ex (sp), hl

call c, .loop_entry
jr c, _strcasecmp.mismatch
sbc hl, hl
jp (iy)

.checkcase:
or a, (hl)
sub a, 'a'
add a, -(1+'z'-'a')
ret c
.loop:
cpi
ret po
ret z
inc de
.loop_entry:
ld a, (de)
xor a, (hl)
jr z, .loop
cp a, 'a'-'A'
jr z, .checkcase
scf
ret

extern _tolower.internal
48 changes: 0 additions & 48 deletions src/libc/strncasecmp.src

This file was deleted.

16 changes: 6 additions & 10 deletions src/libc/tolower.src
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,20 @@
section .text
public _tolower

if PREFER_OS_LIBC

_tolower := 021E34h

else

_tolower:
pop de
ex (sp), hl
push de
require _tolower.internal

section .text
public _tolower.internal
; ASM interface: input/output char in L, destroys AF
_tolower.internal:
ld a, l
sub a, 'A'
cp a, 1+'Z'-'A'
ret nc

add a, 'a'
ld l, a
mateoconlechuga marked this conversation as resolved.
Show resolved Hide resolved
set 5, l
ret

end if
16 changes: 6 additions & 10 deletions src/libc/toupper.src
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,20 @@
section .text
public _toupper

if PREFER_OS_LIBC

_toupper := 021E38h

else

_toupper:
pop de
ex (sp), hl
push de
require _toupper.internal

section .text
public _toupper.internal
; ASM interface: input/output char in L, destroys AF
.internal:
ld a, l
sub a, 'a'
cp a, 1+'z'-'a'
ret nc

add a, 'A'
ld l, a
res 5, l
ret

end if
39 changes: 39 additions & 0 deletions test/regression/bug0005/autotest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"transfer_files": [
"bin/DEMO.8xp"
],
"target": {
"name": "DEMO",
"isASM": true
},
"sequence": [
"action|launch",
"delay|200",
"hashWait|1",
"key|enter",
"delay|300",
"hashWait|2"
],
"hashes": {
"1": {
"description": "Output should be 0 1 0 1 -1 -1|0 0 1 0 -1 -1 0 1",
"start": "vram_start",
"size": "vram_16_size",
"expected_CRCs": [
"BC4B41AB"
]
},
"2": {
"description": "Exit",
"start": "vram_start",
"size": "vram_16_size",
"expected_CRCs": [
"FFAF89BA",
"101734A5",
"9DA19F44",
"A32840C8",
"349F4775"
]
}
}
}
18 changes: 18 additions & 0 deletions test/regression/bug0005/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# ----------------------------
# Makefile Options
# ----------------------------

NAME = DEMO
ICON = icon.png
DESCRIPTION = "CE C Toolchain Demo"
COMPRESSED = NO
ARCHIVED = NO

CFLAGS = -Wall -Wextra -Oz
CXXFLAGS = -Wall -Wextra -Oz

PREFER_OS_LIBC = NO

# ----------------------------

include $(shell cedev-config --makefile)
45 changes: 45 additions & 0 deletions test/regression/bug0005/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <ti/screen.h>
#include <ti/getcsc.h>
#include <string.h>
#include <stdio.h>

void test(const char *a, const char *b)
{
int cmp = strcasecmp(a, b);
cmp = cmp < 0 ? -1 : (cmp > 0);
printf("%d ", cmp);
}

void testn(const char *a, const char *b, size_t n)
{
int cmp = strncasecmp(a, b, n);
cmp = cmp < 0 ? -1 : (cmp > 0);
printf("%d ", cmp);
}

int main(void)
{
os_ClrHome();

test("", "");
test("a", "");
test("abc", "ABC");
test("bad", "Apple");
test("bRiCk", "Bring");
test("bad", "Badger");
printf("\n");

testn("abc", "ABC", 3);
testn("bad", "Apple", 0);
testn("bad", "Apple", 6);
testn("bRiCk", "Bring", 3);
testn("bRiCk", "Bring", 4);
testn("bad", "Badger", 6);
testn("Hello", "HELLO WORLD!", 5);
testn("Hello", "HELLO WORLD!", 12);
printf("\n");

while (!os_GetCSC());

return 0;
}
Loading