diff options
Diffstat (limited to 'zap')
-rw-r--r-- | zap/include-priv/zap/priv.h | 19 | ||||
-rw-r--r-- | zap/include/zap/base.h | 68 | ||||
-rw-r--r-- | zap/src/fastimpl.c | 16 | ||||
-rw-r--r-- | zap/src/fndbyte.c | 77 | ||||
-rw-r--r-- | zap/src/fndchr.c | 71 | ||||
-rw-r--r-- | zap/src/memcmp.c | 21 | ||||
-rw-r--r-- | zap/src/memcpy.c | 141 | ||||
-rw-r--r-- | zap/src/memdup.c | 22 | ||||
-rw-r--r-- | zap/src/memeq.c | 110 | ||||
-rw-r--r-- | zap/src/memfill.c | 58 | ||||
-rw-r--r-- | zap/src/strcmp.c | 21 | ||||
-rw-r--r-- | zap/src/strcpy.c | 69 | ||||
-rw-r--r-- | zap/src/strdup.c | 17 | ||||
-rw-r--r-- | zap/src/streq.c | 81 | ||||
-rw-r--r-- | zap/src/strfill.c | 11 | ||||
-rw-r--r-- | zap/src/strlen.c | 56 |
16 files changed, 858 insertions, 0 deletions
diff --git a/zap/include-priv/zap/priv.h b/zap/include-priv/zap/priv.h new file mode 100644 index 0000000..b051589 --- /dev/null +++ b/zap/include-priv/zap/priv.h @@ -0,0 +1,19 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#if !defined(zap_hdr_priv) +#define zap_hdr_priv + +#include <zap/base.h> + +#include <stddef.h> +#include <stdint.h> + +#if (defined(sus_cmpl_gnu) || defined(sus_cmpl_llvm)) && defined(sus_os_unix) && !defined(zap_priv_noasm) && (defined(sus_arch_amd64) || defined(sus_arch_ia32)) +#define zap_priv_fastimpl +#endif + +#endif diff --git a/zap/include/zap/base.h b/zap/include/zap/base.h new file mode 100644 index 0000000..48e0fb1 --- /dev/null +++ b/zap/include/zap/base.h @@ -0,0 +1,68 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> +#include <susinfo.h> + +#if !defined(zap_hdr_base) +#define zap_hdr_base + +#define zap_typlit_s10(_lit) ((int_least16_t)( _lit)) +#define zap_typlit_s20(_lit) ((int_least32_t)( _lit)) +#define zap_typlit_s40(_lit) ((int_least64_t)( _lit)) +#define zap_typlit_s8( _lit) ((int_least8_t)( _lit)) +#define zap_typlit_u10(_lit) ((uint_least16_t)(_lit)) +#define zap_typlit_u20(_lit) ((uint_least32_t)(_lit)) +#define zap_typlit_u40(_lit) ((uint_least64_t)(_lit)) +#define zap_typlit_u8( _lit) ((uint_least8_t)( _lit)) +#define zap_typlit_usz(_lit) ((size_t)( _lit)) + +#define zap_ver zap_typlit_u64(0xB) + +#if defined(sus_lang_asm) + +.extern zap_fndbyte +.extern zap_fndchr +.extern zap_memcmp +.extern zap_memcpy +.extern zap_memeq +.extern zap_memfill +.extern zap_strcmp +.extern zap_strcpy +.extern zap_streq +.extern zap_strfill +.extern zap_strlen + +#else + +#if defined(sus_lang_cxx) +extern "C" { +#endif + +extern bool const zap_fastimpl; + +sus_attr_alloc sus_attr_allocsz(0x2) sus_attr_hot sus_attr_nothrw sus_attr_useret void * zap_memdup( void const * ptr, size_t num); +sus_attr_hot sus_attr_nothrw sus_attr_useret size_t zap_fndbyte( void const * ptr, size_t num, uint_least8_t byte); +sus_attr_hot sus_attr_nothrw sus_attr_useret size_t zap_fndchr( char const * str, char chr); +sus_attr_hot sus_attr_nothrw sus_attr_useret int_least8_t zap_memcmp( void const * lstr,size_t num, void const * rstr); +sus_attr_hot sus_attr_nothrw void zap_memcpy( void const * in, size_t num, void * out); +sus_attr_hot sus_attr_nothrw sus_attr_useret bool zap_memeq( void const * lptr,size_t num, void const * rptr); +sus_attr_hot sus_attr_nothrw void zap_memfill( void * ptr, size_t num, uint_least8_t val); +sus_attr_hot sus_attr_nothrw sus_attr_useret int_least8_t zap_strcmp( char const * lstr,char const * rstr); +sus_attr_hot sus_attr_nothrw sus_attr_useret size_t zap_strcpy( char const * in, char * out); +sus_attr_alloc sus_attr_hot sus_attr_nothrw sus_attr_useret char * zap_strdup( char const * str); +sus_attr_hot sus_attr_nothrw sus_attr_useret bool zap_streq( char const * lstr,char const * rstr); +sus_attr_hot sus_attr_nothrw void zap_strfill( char * lstr,char chr); +sus_attr_hot sus_attr_nothrw sus_attr_useret size_t zap_strlen( char const * str); + +#endif +#if defined(sus_lang_cxx) +} +#endif + +#endif diff --git a/zap/src/fastimpl.c b/zap/src/fastimpl.c new file mode 100644 index 0000000..71ded00 --- /dev/null +++ b/zap/src/fastimpl.c @@ -0,0 +1,16 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stdbool.h> +#include <stdint.h> + +#if defined(zap_priv_fastimpl) +bool const zap_fastimpl = true; +#else +bool const zap_fastimpl = false; +#endif diff --git a/zap/src/fndbyte.c b/zap/src/fndbyte.c new file mode 100644 index 0000000..85fc14d --- /dev/null +++ b/zap/src/fndbyte.c @@ -0,0 +1,77 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stddef.h> +#include <stdint.h> + +#if defined(zap_priv_fastimpl) +__asm__ ( + ".global zap_fndbyte\n" + + "zap_fndbyte:\n" + /* + void const * ptr + size_t num + uint_least8_t byte + */ +#if defined(sus_arch_amd64) + /* rax: Address of the current element. */ + "movq %rdi,%rax\n" + /* rsi: Address of the element after the last element. */ + "addq %rdi,%rsi\n" + /* rcx: Current element. */ + ".loop:\n" + "cmpq %rax,%rsi\n" + "je .nfnd\n" /* We have went through the entire array without finding the byte. */ + "movb (%rax),%cl\n" + "cmpb %cl,%dl\n" + "je .fnd\n" /* We have found the byte. */ + "incq %rax\n" + "jmp .loop\n" + ".fnd:\n" + "subq %rdi,%rax\n" + "ret\n" + ".nfnd:\n" + "movq $0xFFFFFFFFFFFFFFFF,%rax\n" + "ret\n" +#elif defined(sus_arch_ia32) + /* eax: Address of the current element. */ + "movl 0x4(%esp),%eax\n" + /* ecx: Address of the element after the last element. */ + "movl 0x8(%esp),%ecx\n" + "addl %eax,%ecx\n" + /* edx: Byte value. */ + "movb 0xC(%esp),%dl\n" + /* ebx: Current element. */ + "pushl %ebx\n" + ".loop:\n" + "cmpl %eax,%ecx\n" + "je .nfnd\n" /* We have went through the entire array without finding the byte. */ + "movb (%eax),%bl\n" + "cmpb %bl,%dl\n" + "je .fnd\n" /* We have found the byte. */ + "incl %eax\n" + "jmp .loop\n" + ".fnd:\n" + "popl %ebx\n" + "subl 0x4(%esp),%eax\n" + "ret\n" + ".nfnd:\n" + "popl %ebx\n" + "movl $0xFFFFFFFF,%eax\n" + "ret\n" +#endif +); +#else +size_t zap_fndbyte(void const * const _ptr,size_t const _num,uint_least8_t const _byte) { + uint_least8_t const * ptr = (uint_least8_t const *)_ptr; + uint_least8_t const * const afterbuf = ptr + _num; + for (;ptr != afterbuf;++ptr) {sus_unlikely (*ptr == _byte) {return ptr - (uint_least8_t const *)_ptr;}} + return zap_typlit_usz(-0x1); +} +#endif diff --git a/zap/src/fndchr.c b/zap/src/fndchr.c new file mode 100644 index 0000000..cd5458f --- /dev/null +++ b/zap/src/fndchr.c @@ -0,0 +1,71 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stddef.h> +#include <stdint.h> + +#if defined(zap_priv_fastimpl) +__asm__ ( + ".global zap_fndchr\n" + + "zap_fndchr:\n" + /* + char const * str + char chr + */ +#if defined(sus_arch_amd64) + /* rax: Address of the current character. */ + "movq %rdi,%rax\n" + /* rdx: Current character. */ + ".loop:\n" + "movb (%rax),%dl\n" + "cmpb %dl,%sil\n" + "je .fnd\n" /* Exit loop if we have found the character. */ + "testb %dl,%dl\n" + "je .nfnd\n" /* We encountered the null-terminator but not the specified character. */ + "incq %rax\n" + "jmp .loop\n" + ".fnd:\n" + "subq %rdi,%rax\n" + "ret\n" + ".nfnd:\n" + "movq $0xFFFFFFFFFFFFFFFF,%rax\n" + "ret\n" +#elif defined(sus_arch_ia32) + /* eax: Address of the current character. */ + "movl 0x4(%esp),%eax\n" + /* ecx: Character. */ + "movb 0x8(%esp),%cl\n" + /* edx: Current character. */ + ".loop:\n" + "movb (%eax),%dl\n" + "cmpb %dl,%cl\n" + "je .fnd\n" /* Exit loop if we have found the character. */ + "testb %dl,%dl\n" + "je .nfnd\n" /* We encountered the null-terminator but not the specified character. */ + "incl %eax\n" + "jmp .loop\n" + ".fnd:\n" + "subl 0x4(%esp),%eax\n" + "ret\n" + ".nfnd:\n" + "movl $0xFFFFFFFF,%eax\n" + "ret\n" +#endif +); +#else +size_t zap_fndchr(char const * const _str,char const _chr) { + char const * pos = _str; + for (;;++pos) { + char const chr = *pos; + sus_unlikely (chr == _chr) {return (size_t)(pos - _str);} + sus_unlikely (chr == '\x0') {return zap_typlit_usz(-0x1);} + } + sus_unreach(); +} +#endif diff --git a/zap/src/memcmp.c b/zap/src/memcmp.c new file mode 100644 index 0000000..810bab0 --- /dev/null +++ b/zap/src/memcmp.c @@ -0,0 +1,21 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stddef.h> + +int_least8_t zap_memcmp(void const * const _lstr,size_t const _num,void const * const _rstr) { + unsigned char const * lpos = (unsigned char const *)_lstr; + unsigned char const * rpos = (unsigned char const *)_rstr; + unsigned char const * const afterlbuf = lpos + _num; + for (;lpos != afterlbuf;++lpos,++rpos) { + unsigned char const lbyte = *lpos; + unsigned char const rbyte = *rpos; + sus_likely (lbyte != rbyte) {return lbyte < rbyte ? (int_least8_t)INT8_MIN : (int_least8_t)INT8_MAX;} + } + return zap_typlit_s8(0x0); +} diff --git a/zap/src/memcpy.c b/zap/src/memcpy.c new file mode 100644 index 0000000..1b40832 --- /dev/null +++ b/zap/src/memcpy.c @@ -0,0 +1,141 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stddef.h> +#include <stdint.h> + +#if defined(zap_priv_fastimpl) +__asm__ ( + ".global zap_memcpy\n" + + "zap_memcpy:\n" + /* + void const * in + size_t num + void * out + */ +#if defined(sus_arch_amd64) + /* rdi: Address of the current input element. */ + /* rsi: Number of remaining elements. */ + /* rdx: Address of the current output element. */ + /* rcx: Current element. */ + /* xmm0: Current element. */ + /* ymm0: Current element. */ +#if defined(sus_archfeat_avx) + ".big256cpy:\n" + "cmpq $0x20,%rsi\n" + "jl .big128cpy\n" + "vmovups (%rdi),%ymm0\n" + "vmovups %ymm0,(%rdx)\n" + "addq $0x20,%rdi\n" + "addq $0x20,%rdx\n" + "subq $0x20,%rsi\n" + "jmp .big256cpy\n" +#endif + ".big128cpy:\n" + "cmpq $0x10,%rsi\n" + "jl .wrdcpy\n" + "movdqu (%rdi),%xmm0\n" + "movdqu %xmm0,(%rdx)\n" + "addq $0x10,%rdi\n" + "addq $0x10,%rdx\n" + "subq $0x10,%rsi\n" + "jmp .big128cpy\n" + ".wrdcpy:\n" + "cmpq $0x8,%rsi\n" + "jl .bytecpy\n" + "movq (%rdi),%rcx\n" + "movq %rcx,(%rdx)\n" + "addq $0x8,%rdi\n" + "addq $0x8,%rdx\n" + "subq $0x8,%rsi\n" + "jmp .wrdcpy\n" + ".bytecpy:\n" + "testq %rsi,%rsi\n" + "jz .done\n" + "movb (%rdi),%cl\n" + "movb %cl,(%rdx)\n" + "incq %rdi\n" + "incq %rdx\n" + "decq %rsi\n" + "jmp .bytecpy\n" + ".done:\n" + "ret\n" +#elif defined(sus_arch_ia32) + /* eax: Address of the current input element. */ + "movl 0x4(%esp),%eax\n" + /* ecx: Number of remaining elements. */ + "movl 0x8(%esp),%ecx\n" + /* edx: Address of the current output element. */ + "movl 0xC(%esp),%edx\n" + /* ebx: Current element. */ + "pushl %ebx\n" /* ebx must be restored. */ + /* xmm0: Current element. */ + /* ymm0: Current element. */ +#if defined(sus_archfeat_avx) + ".big256cpy:\n" + "cmpl $0x20,%ecx\n" +#if defined(sus_archfeat_sse) + "jl .big128cpy\n" +#else + "jl .wrdcpy\n" +#endif + "vmovdqu (%eax),%ymm0\n" + "vmovdqu %ymm0,(%edx)\n" + "addl $0x20,%eax\n" + "addl $0x20,%edx\n" + "subl $0x20,%ecx\n" + "jmp .big256cpy\n" +#endif +#if defined(sus_archfeat_sse) + ".big128cpy:\n" + "cmpl $0x10,%ecx\n" + "jl .wrdcpy\n" +#if defined(sus_archfeat_sse2) + "movdqu (%eax),%xmm0\n" + "movdqu %xmm0,(%edx)\n" +#else + "movups (%eax),%xmm0\n" + "movups %xmm0,(%edx)\n" +#endif + "addl $0x10,%eax\n" + "addl $0x10,%edx\n" + "subl $0x10,%ecx\n" + "jmp .big128cpy\n" +#endif + ".wrdcpy:\n" + "cmpl $0x4,%ecx\n" + "jl .bytecpy\n" + "movl (%eax),%ebx\n" + "movl %ebx,(%edx)\n" + "addl $0x4,%eax\n" + "addl $0x4,%edx\n" + "subl $0x4,%ecx\n" + "jmp .wrdcpy\n" + ".bytecpy:\n" + "testl %ecx,%ecx\n" + "jz .done\n" + "movb (%eax),%bl\n" + "movb %bl,(%edx)\n" + "incl %eax\n" + "incl %edx\n" + "decl %ecx\n" + "jmp .bytecpy\n" + ".done:\n" + "popl %ebx\n" + "ret\n" +#endif +); +#else +void zap_memcpy(void const * const _in,size_t const _num,void * const _out) { + uint_least8_t const * in = (uint_least8_t const *)_in; + uint_least8_t * out = (uint_least8_t *)_out; + uint_least8_t const * const afterbuf = in + _num; + for (;in != afterbuf;++in,++out) {*out = *in;} +} +#endif diff --git a/zap/src/memdup.c b/zap/src/memdup.c new file mode 100644 index 0000000..3670eb3 --- /dev/null +++ b/zap/src/memdup.c @@ -0,0 +1,22 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stdlib.h> + +void * zap_memdup(sus_attr_unused void const * const _ptr,sus_attr_unused size_t const _num) { +#if !defined(zap_priv_nostdlib) + void * const dup = malloc(_num); + sus_unlikely (dup == NULL) {return NULL;} + zap_memcpy(_ptr,_num,dup); + return dup; +#else + return NULL; +#endif +} + + diff --git a/zap/src/memeq.c b/zap/src/memeq.c new file mode 100644 index 0000000..f9717ad --- /dev/null +++ b/zap/src/memeq.c @@ -0,0 +1,110 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +#if defined(zap_priv_fastimpl) +__asm__ ( + ".global zap_memeq\n" + + "zap_memeq:\n" + /* + void const * lptr + size_t num + void const * rptr + */ +#if defined(sus_arch_amd64) + /* rdi: Address of the current left element. */ + /* rsi: Number of remaining elements. */ + /* rdx: Address of the current right element. */ + /* rax: Current left element. */ + /* rcx: Current right element. */ + ".wrdcmp:\n" + "cmpq $0x8,%rsi\n" + "jl .bytecmp\n" + "movq (%rdi),%rax\n" + "movq (%rdx),%rcx\n" + "cmpq %rax,%rcx\n" + "jne .neq\n" + "addq $0x8,%rdi\n" + "addq $0x8,%rdx\n" + "subq $0x8,%rsi\n" + "jmp .wrdcmp\n" + ".bytecmp:\n" + "testq %rsi,%rsi\n" + "jne .eq\n" /* If we have reached the final element, all previous elements have compared equal, and the memory sequences are equal. */ + "movb (%rdi),%al\n" + "movb (%rdx),%cl\n" + "cmpb %al,%cl\n" + "jne .neq\n" + "incq %rdi\n" + "incq %rdx\n" + "decq %rsi\n" + "jmp .bytecmp\n" + ".eq:\n" + "movb $0x1,%al\n" + "ret\n" + ".neq:\n" + "movb $0x0,%al\n" + "ret\n" +#elif defined(sus_arch_ia32) + /* eax: Address of the current left element. */ + "movl 0x4(%esp),%eax\n" + /* ecx: Number of remaining elements. */ + "movl 0x8(%esp),%ecx\n" + /* edx: Address of the current right element. */ + "movl 0xC(%esp),%edx\n" + /* ebx: Current left element. */ + "pushl %ebx\n" + /* ebx/esi: Current right element. */ + "pushl %esi\n" + ".wrdcmp:\n" + "cmpl $0x4,%ecx\n" + "jl .bytecmp\n" + "movl (%eax),%ebx\n" + "movl (%edx),%esi\n" + "cmpl %ebx,%esi\n" + "jne .neq\n" + "addl $0x4,%eax\n" + "addl $0x4,%edx\n" + "subl $0x4,%ecx\n" + "jmp .wrdcmp\n" + ".bytecmp:\n" + "testl %ecx,%ecx\n" + "jne .eq\n" /* If we have reached the final element, all previous elements have compared equal, and the memory sequences are equal. */ + "movb (%eax),%bl\n" + "movb (%edx),%bh\n" + "cmpb %bl,%bh\n" + "jne .neq\n" + "incl %eax\n" + "incl %edx\n" + "decl %ecx\n" + "jmp .bytecmp\n" + ".eq:\n" + "popl %ebx\n" + "popl %esi\n" + "movb $0x1,%al\n" + "ret\n" + ".neq:\n" + "popl %ebx\n" + "popl %esi\n" + "movb $0x0,%al\n" + "ret\n" +#endif +); +#else +bool zap_memeq(void const * const _lptr,size_t const _num,void const * const _rptr) { + uint_least8_t const * lpos = (uint_least8_t const *)_lptr; + uint_least8_t const * rpos = (uint_least8_t const *)_rptr; + uint_least8_t const * const afterbuf = lpos + _num; + for (;lpos != afterbuf;++lpos,++rpos) {sus_likely (*lpos != *rpos) {return false;}} + return true; +} +#endif diff --git a/zap/src/memfill.c b/zap/src/memfill.c new file mode 100644 index 0000000..70982c4 --- /dev/null +++ b/zap/src/memfill.c @@ -0,0 +1,58 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stddef.h> +#include <stdint.h> + +#if defined(zap_priv_fastimpl) +__asm__ ( + ".global zap_memfill\n" + + "zap_memfill:\n" + /* + void const * ptr + size_t num + uint_least8_t val + */ +#if defined(sus_arch_amd64) + /* rdi: Address of the current element. */ + /* rsi: Address of the element after the last element. */ + "addq %rdi,%rsi\n" + ".loop:\n" + "cmpq %rsi,%rdi\n" + "je .done\n" /* Exit loop if we have reached the final element. */ + "movb %dl,(%rdi)\n" + "incq %rdi\n" + "jmp .loop\n" /* Continue to next element. */ + ".done:\n" + "ret\n" +#elif defined(sus_arch_ia32) + /* eax: Address of the current element. */ + "movl 0x4(%esp),%eax\n" + /* ecx: Address of the element after the last element. */ + "movl 0x4(%esp),%ecx\n" + "addl 0x8(%esp),%ecx\n" + /* edx: Byte value. */ + "movb 0xC(%esp),%dl\n" + ".loop:\n" + "cmpl %eax,%ecx\n" + "je .done\n" /* Exit loop if we have reached the final element. */ + "movb %dl,(%eax)\n" + "incl %eax\n" + "jmp .loop\n" /* Continue to next element. */ + ".done:\n" + "ret\n" +#endif +); +#else +void zap_memfill(void * const _ptr,size_t const _num,uint_least8_t const _byte) { + uint_least8_t * pos = (uint_least8_t *)_ptr; + uint_least8_t * const afterbuf = pos + _num; + for (;pos != afterbuf;++pos) {*pos = _byte;} +} +#endif diff --git a/zap/src/strcmp.c b/zap/src/strcmp.c new file mode 100644 index 0000000..9e11601 --- /dev/null +++ b/zap/src/strcmp.c @@ -0,0 +1,21 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stdint.h> + +int_least8_t zap_strcmp(char const * const _lstr,char const * const _rstr) { + unsigned char const * lpos = (unsigned char const *)_lstr; + unsigned char const * rpos = (unsigned char const *)_rstr; + for (;;++lpos,++rpos) { + unsigned char const lchr = *lpos; + unsigned char const rchr = *rpos; + sus_likely (lchr != rchr) {return lchr < rchr ? (int_least8_t)INT8_MIN : (int_least8_t)INT8_MAX;} + sus_unlikely (lchr == (unsigned char)0x0) {return zap_typlit_s8(0x0);} + } + sus_unreach(); +} diff --git a/zap/src/strcpy.c b/zap/src/strcpy.c new file mode 100644 index 0000000..3dc3e0f --- /dev/null +++ b/zap/src/strcpy.c @@ -0,0 +1,69 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stddef.h> + +#if defined(zap_priv_fastimpl) +__asm__ ( + ".global zap_strcpy\n" + + "zap_strcpy:\n" + /* + char const * in + char const * out + */ +#if defined(sus_arch_amd64) + /* rax: Address of the current input character. */ + "movq %rdi,%rax\n" + /* rsi: Address of the current output character. */ + "movq %rsi,%rsi\n" + /* rdx: Current character. */ + ".loop:\n" + "movb (%rax),%dl\n" /* Move current the character into a register... */ + "movb %dl,(%rsi)\n" /* ... and then back into memory. */ + "testb %dl,%dl\n" /* Check if we have reached the null-terminator... */ + "jz .done\n" /* ... and if so, we are finished copying. */ + "incq %rax\n" /* Increment the positions. */ + "incq %rsi\n" + "jmp .loop\n" /* Restart the loop. */ + ".done:\n" + "subq %rdi,%rax\n" /* Get the length of the string we copyied. */ + "decq %rdi\n" /* We do not count the null-terminator in the string length. */ + "ret\n" +#elif defined(sus_arch_ia32) + /* eax: Address of the current input character. */ + "movl 0x4(%esp),%eax\n" + /* ecx: Address of the current output character. */ + "movl 0x8(%esp),%ecx\n" + /* edx: Current character. */ + ".loop:\n" + "movb (%eax),%dl\n" /* Move current the character into a register... */ + "movb %dl,(%ecx)\n" /* ... and then back into memory. */ + "testb %dl,%dl\n" /* Check if we have reached the null-terminator... */ + "jz .done\n" /* ... and if so, we are finished copying. */ + "incl %eax\n" /* Increment the positions. */ + "incl %ecx\n" + "jmp .loop\n" /* Restart the loop. */ + ".done:\n" + "subl 0x4(%esp),%eax\n" /* Get the length of the string we copyied. */ + "decl %ecx \n" /* We do not count the null-terminator in the string length. */ + "ret\n" +#endif +); +#else +size_t zap_strcpy(char const * const _in,char * const _out) { + char const * inpos = _in; + char * outpos = _out; + for (;;++inpos,++outpos) { + char const chr = *inpos; + *outpos = chr; + if (chr == '\x0') {return (size_t)(inpos - _in);} + } + sus_unreach(); +} +#endif diff --git a/zap/src/strdup.c b/zap/src/strdup.c new file mode 100644 index 0000000..785a93b --- /dev/null +++ b/zap/src/strdup.c @@ -0,0 +1,17 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stdlib.h> + +char * zap_strdup(sus_attr_unused char const * const _str) { +#if !defined(zap_priv_nostdlib) + return zap_memdup(_str,zap_strlen(_str) + zap_typlit_usz(0x1)); +#else + return NULL; +#endif +} diff --git a/zap/src/streq.c b/zap/src/streq.c new file mode 100644 index 0000000..6425ef7 --- /dev/null +++ b/zap/src/streq.c @@ -0,0 +1,81 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stdbool.h> +#include <stdint.h> + +#if defined(zap_priv_fastimpl) +__asm__ ( + ".global zap_streq\n" + + "zap_streq:\n" + /* + char const * lstr + char const * rstr + */ +#if defined(sus_arch_amd64) + /* rax: Address of the current input character. */ + "movq %rdi,%rax\n" + /* rsi: Address of the current output character. */ + "movq %rsi,%rsi\n" + /* rdx: Current input character. */ + /* rcx: Current output character. */ + ".loop:\n" + "movb (%rax),%dl\n" /* Move the characters into registers. */ + "movb (%rsi),%cl\n" + "cmpb %dl,%cl\n" /* Check if the characters are equal... */ + "jne .neq\n" /* ... indicate inequality if they are not. */ + "testb %dl,%dl\n" /* Check if we have reached the null-terminator... */ + "jz .eq\n" /* ... indicate equality if we have. */ + "incq %rax\n" /* Increment positions. */ + "incq %rsi\n" + "jmp .loop\n" /* Restart loop. */ + ".eq:\n" /* Indicate equality. */ + "movb $0x1,%al\n" + "ret\n" + ".neq:\n" /* Indicate inequality. */ + "movb $0x0,%al\n" + "ret\n" +#elif defined(sus_arch_ia32) + /* eax: Address of the current input character. */ + "movl 0x4(%esp),%eax\n" + /* ecx: Address of the current output character. */ + "movl 0x8(%esp),%ecx\n" + /* edx: Current input character. */ + /* edx: Current output character. */ + ".loop:\n" + "movb (%eax),%dl\n" /* Move the characters into registers. */ + "movb (%ecx),%dh\n" + "cmpb %dl,%dh\n" /* Check if the characters are equal... */ + "jne .neq\n" /* ... indicate inequality if they are not. */ + "testb %dl,%dl\n" /* Check if we have reached the null-terminator... */ + "jz .eq\n" /* ... indicate equality if we have. */ + "incl %eax\n" /* Increment positions. */ + "incl %ecx\n" + "jmp .loop\n" /* Restart loop. */ + ".eq:\n" /* Indicate equality. */ + "movb $0x1,%al\n" + "ret\n" + ".neq:\n" /* Indicate inequality. */ + "movb $0x0,%al\n" + "ret\n" +#endif +); +#else +bool zap_streq(char const * const _lstr,char const * const _rstr) { + char const * lpos = _lstr; + char const * rpos = _rstr; + for (;;++lpos,++rpos) { + char const lchr = *lpos; + char const rchr = *rpos; + sus_likely (lchr != rchr) {return false;} + if (lchr == '\x0') {return true;} + } + sus_unreach(); +} +#endif diff --git a/zap/src/strfill.c b/zap/src/strfill.c new file mode 100644 index 0000000..a113094 --- /dev/null +++ b/zap/src/strfill.c @@ -0,0 +1,11 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stdint.h> + +void zap_strfill(char * const _str,char const _chr) {zap_memfill(_str,zap_strlen(_str),(uint_least8_t)_chr);} diff --git a/zap/src/strlen.c b/zap/src/strlen.c new file mode 100644 index 0000000..c1e8959 --- /dev/null +++ b/zap/src/strlen.c @@ -0,0 +1,56 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <stddef.h> + +#if defined(zap_priv_fastimpl) +__asm__ ( + ".global zap_strlen\n" + + "zap_strlen:\n" + /* + char const * str + */ +#if defined(sus_arch_amd64) + /* rax: Address of the current character. */ + "movq %rdi,%rax\n" + /* rdx: Current character. */ + ".loop:\n" + "movb (%rax),%dl\n" + "testb %dl,%dl\n" + "jz .done\n" /* Exit loop if we have reached the null-terminator. */ + "incq %rax\n" /* Continue to the next character. */ + "jmp .loop\n" + ".done:\n" + "subq %rdi,%rax\n" + "ret\n" +#elif defined(sus_arch_ia32) + /* eax: Address of the current character. */ + "movl 0x4(%esp),%eax\n" + /* ecx: Current character. */ + ".loop:\n" + "movb (%eax),%cl\n" + "testb %cl,%cl\n" + "jz .done\n" /* Exit loop if we have reached the null-terminator. */ + "incl %eax\n" /* Continue to the next character. */ + "jmp .loop\n" + ".done:\n" + "subl 0x4(%esp),%eax\n" + "ret\n" +#endif +); +#else +size_t zap_strlen(char const * const _str) { + char const * pos = _str; + for (;;++pos) { + char const chr = *pos; + sus_unlikely (chr == '\x0') {return (size_t)(pos - _str);} + } + sus_unreach(); +} +#endif |