diff options
Diffstat (limited to 'zap')
41 files changed, 1351 insertions, 1243 deletions
diff --git a/zap/GNUmakefile b/zap/GNUmakefile new file mode 100644 index 0000000..58a85ce --- /dev/null +++ b/zap/GNUmakefile @@ -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/. + +# TOOLS + +#CC = clang +#CC = gcc + +# TOOL FLAGS + +ASFLAGS += \ + -g \ + -march=native + +CFLAGS += \ + -Ofast \ + -fPIC \ + -ffreestanding \ + -g \ + -march=native \ + -std=c90 \ + -Wall \ + -Wextra \ + -Wpedantic + +CPPFLAGS += \ + -Iinclude \ + -Iinclude-private + +# ARTEFACTS + +OBJS = \ + src/mem/fndbyte.o \ + src/mem/fndchr.o \ + src/mem/foreach.o \ + src/mem/memcat.o \ + src/mem/memcmp.o \ + src/mem/memcp.o \ + src/mem/memeq.o \ + src/mem/memfill.o \ + src/mem/memgen.o \ + src/mem/strcat.o \ + src/mem/strcmp.o \ + src/mem/streq.o \ + src/mem/strfill.o \ + src/mem/strcp.o \ + src/mem/strlen.o \ + src/mem/utf8dec.o \ + src/mem/utf8declen.o \ + src/mem/utf8enc.o \ + src/mem/utf8enclen.o \ + src/mem/win1252dec.o \ + src/mem/win1252enc.o + +LIB = libzap.a + +# OPTIONS + +# TARGETS + +.PHONY: clean purge + +$(LIB): $(OBJS) + $(AR) r $@ $^ + +clean: + $(RM) $(OBJS) + +purge: clean + $(RM) $(LIB) diff --git a/zap/Makefile b/zap/Makefile deleted file mode 100644 index b7db3dc..0000000 --- a/zap/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# TOOLS - -#CC = clang -#CC = gcc - -# TOOL FLAGS - -CFLAGS = \ - -Iinclude \ - -Iinclude-priv \ - -O3 \ - -fPIC \ - -g \ - -march=native \ - -std=c99 \ - -Wall \ - -Wextra \ - -Wpedantic - -# ARTIFACTS - -OBJS = \ - src/abs.o \ - src/fastimpl.o \ - src/fma.o \ - src/fndbyte.o \ - src/fndchr.o \ - src/foreach.o \ - src/memcmp.o \ - src/memcpy.o \ - src/memdup.o \ - src/memeq.o \ - src/memfill.o \ - src/strcmp.o \ - src/strdup.o \ - src/streq.o \ - src/strfill.o \ - src/strcpy.o \ - src/strlen.o - -LIB = libzap.a - -# OPTIONS - -# Uncomment to disable assembly algorithms: -#CFLAGS += -Dzap_priv_noasm - -# Uncomment to enable freestanding mode (requries no runtime): -#CFLAGS += \ - -Dzap_priv_nostdlib \ - -ffreestanding - -# TARGETS - -.PHONY: clean purge - -$(LIB): $(OBJS) - ar r $@ $(OBJS) - -clean: - rm -fr $(OBJS) - -purge: clean - rm -fr $(LIB) diff --git a/zap/include-priv/zap/priv.h b/zap/include-private/zap/priv.h index 8ebbd39..c47d802 100644 --- a/zap/include-priv/zap/priv.h +++ b/zap/include-private/zap/priv.h @@ -7,12 +7,14 @@ #if !defined(zap_priv_hdr_priv) #define zap_priv_hdr_priv -#include <zap/base.h> +#if !defined(__amd64__) +#error zapq only supports AMD64! +#endif + +#if !defined(__ASSEMBLER__) +#include <zap/bs.h> -#if (defined(sus_comp_gnu) || defined(sus_comp_llvm)) && defined(sus_os_unix) && !defined(zap_priv_noasm) && (defined(sus_arch_amd64) || defined(sus_arch_ia32)) -#define zap_priv_fastimpl (0x1u) -#else -#define zap_priv_fastimpl (0x0u) +#include <sus/extra.h> #endif #endif diff --git a/zap/include/zap/base.h b/zap/include/zap/base.h deleted file mode 100644 index a52414b..0000000 --- a/zap/include/zap/base.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - 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 <susinfo.h> - -#if !defined(zap_priv_hdr_base) -#define zap_priv_hdr_base - -#define zap_ver (0xFu) - -#if defined(sus_lang_cxx) -extern "C" { -#endif - -extern bool const zap_fastimpl; - -#if defined(sus_lang_cxx) -} -#endif - -#endif diff --git a/zap/include/zap/bs.h b/zap/include/zap/bs.h new file mode 100644 index 0000000..930b1a8 --- /dev/null +++ b/zap/include/zap/bs.h @@ -0,0 +1,43 @@ +/* + 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_priv_hdr_bs) +#define zap_priv_hdr_bs + +#if defined(sus_lang_cxx) +extern "C" { +#endif + +typedef unsigned char zap_bool; +#define zap_false ((zap_bool)+0x0u) +#define zap_true ((zap_bool)+0xFFu) + +typedef unsigned short zap_chr10; +typedef unsigned int zap_chr20; +typedef unsigned char zap_chr8; + +typedef signed char zap_cmp; +#define zap_eq ((zap_cmp)+0x0) +#define zap_gt ((zap_cmp)+0x7F) +#define zap_lt ((zap_cmp)-0x80) + +#define zap_nopos (~((zap_sz)+0u)) + +#if defined(__cplusplus) +#define zap_nullptr ((unsigned long)0x0u) +#else +#define zap_nullptr ((void *)0x0u) +#endif + +typedef unsigned long zap_sz; + +#define zap_ver ((unsigned long)+0x10u) + +#if defined(sus_lang_cxx) +} +#endif + +#endif diff --git a/zap/include/zap/math.h b/zap/include/zap/math.h deleted file mode 100644 index 97afb66..0000000 --- a/zap/include/zap/math.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - 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/base.h> - -#include <susinfo.h> - -#if !defined(zap_priv_hdr_math) -#define zap_priv_hdr_math - -#if !defined(sus_langfeat_c_llng) && !defined(sus_langfeat_cxx_llng) -#error The (long long) type is required but unsupported by the implementation ! -#endif - -#if defined(sus_lang_cxx) -extern "C" { -#endif - -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret signed char zap_abs_c( signed char val); -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret int zap_abs_i( int val); -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret long zap_abs_l( long val); -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret long long zap_abs_ll( long long val); -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret short zap_abs_s( short val); - -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret signed char zap_fma_c( signed char a,signed char b,signed char c); -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret int zap_fma_i( int a,int b,int c); -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret long zap_fma_l( long a,long b,long c); -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret long long zap_fma_ll( long long a,long long b,long long c); -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret short zap_fma_s( short a,short b,short c); -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret unsigned char zap_fma_uc( unsigned char a,unsigned char b,unsigned char c); -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret unsigned int zap_fma_ui( unsigned int a,unsigned int b,unsigned int c); -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret unsigned long zap_fma_ul( unsigned long a,unsigned long b,unsigned long c); -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret unsigned long long zap_fma_ull(unsigned long long a,unsigned long long b,unsigned long long c); -sus_attr_const sus_attr_hot sus_attr_nothrw sus_attr_useret unsigned short zap_fma_us( unsigned short a,unsigned short b,unsigned short c); - -#if defined(sus_langfeat_c_generic) - -#define zap_abs_tg(_val) \ - (_Generic((_val), \ - signed char:zap_abs_c, \ - int: zap_abs_i, \ - long: zap_abs_l, \ - long long: zap_abs_ll,\ - short: zap_abs_s, \ - )((_val))) - -#define zap_fma_tg(_a,_b,_c) \ - (_Generic((_a), \ - signed char: zap_fma_c, \ - int: zap_fma_i, \ - long: zap_fma_l, \ - long long: zap_fma_ll, \ - short: zap_fma_s, \ - unsigned char: zap_fma_uc, \ - unsigned int: zap_fma_ui, \ - unsigned long: zap_fma_ul, \ - unsigned long long:zap_fma_ull,\ - unsigned short: zap_fma_us, \ - )((_a),(_b),(_c))) - -#elif defined(sus_lang_cxx) - -extern "C++" { - sus_attr_const sus_attr_inline sus_attr_useret sus_inline signed char zap_priv_cxxtg_abs(signed char const _val) {return ::zap_abs_c( _val);}; - sus_attr_const sus_attr_inline sus_attr_useret sus_inline int zap_priv_cxxtg_abs(int const _val) {return ::zap_abs_i( _val);}; - sus_attr_const sus_attr_inline sus_attr_useret sus_inline long zap_priv_cxxtg_abs(long const _val) {return ::zap_abs_l( _val);}; - sus_attr_const sus_attr_inline sus_attr_useret sus_inline long long zap_priv_cxxtg_abs(long long const _val) {return ::zap_abs_ll(_val);}; - sus_attr_const sus_attr_inline sus_attr_useret sus_inline short zap_priv_cxxtg_abs(short const _val) {return ::zap_abs_s( _val);}; - - sus_attr_const sus_attr_inline sus_attr_useret sus_inline signed char zap_priv_cxxtg_fma(signed char const _a,signed char const _b,signed char const _c) {return ::zap_fma_c( _a,_b,_c);}; - sus_attr_const sus_attr_inline sus_attr_useret sus_inline int zap_priv_cxxtg_fma(int const _a,int const _b,int const _c) {return ::zap_fma_i( _a,_b,_c);}; - sus_attr_const sus_attr_inline sus_attr_useret sus_inline long zap_priv_cxxtg_fma(long const _a,long const _b,long const _c) {return ::zap_fma_l( _a,_b,_c);}; - sus_attr_const sus_attr_inline sus_attr_useret sus_inline long long zap_priv_cxxtg_fma(long long const _a,long long const _b,long long const _c) {return ::zap_fma_ll( _a,_b,_c);}; - sus_attr_const sus_attr_inline sus_attr_useret sus_inline short zap_priv_cxxtg_fma(short const _a,short const _b,short const _c) {return ::zap_fma_s( _a,_b,_c);}; - sus_attr_const sus_attr_inline sus_attr_useret sus_inline unsigned char zap_priv_cxxtg_fma(unsigned char const _a,unsigned char const _b,unsigned char const _c) {return ::zap_fma_uc( _a,_b,_c);}; - sus_attr_const sus_attr_inline sus_attr_useret sus_inline unsigned int zap_priv_cxxtg_fma(unsigned int const _a,unsigned int const _b,unsigned int const _c) {return ::zap_fma_ui( _a,_b,_c);}; - sus_attr_const sus_attr_inline sus_attr_useret sus_inline unsigned long zap_priv_cxxtg_fma(unsigned long const _a,unsigned long const _b,unsigned long const _c) {return ::zap_fma_ul( _a,_b,_c);}; - sus_attr_const sus_attr_inline sus_attr_useret sus_inline unsigned long long zap_priv_cxxtg_fma(unsigned long long const _a,unsigned long long const _b,unsigned long long const _c) {return ::zap_fma_ull(_a,_b,_c);}; - sus_attr_const sus_attr_inline sus_attr_useret sus_inline unsigned short zap_priv_cxxtg_fma(unsigned short const _a,unsigned short const _b,unsigned short const _c) {return ::zap_fma_us( _a,_b,_c);}; -} - -#define zap_abs_tg(_val) (::zap_priv_cxxtg_abs( _val)) -#define zap_fma_tg(_a, _b,_c) (::zap_priv_cxxtg_fma(_a, _b,_c)) - -#endif - -#if defined(sus_lang_cxx) -} -#endif - -#endif diff --git a/zap/include/zap/mem.h b/zap/include/zap/mem.h index 20d7326..0580019 100644 --- a/zap/include/zap/mem.h +++ b/zap/include/zap/mem.h @@ -4,54 +4,37 @@ 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/base.h> - -#include <stdbool.h> -#include <stddef.h> -#include <stdint.h> -#include <susinfo.h> - #if !defined(zap_priv_hdr_mem) #define zap_priv_hdr_mem -#if defined(sus_lang_asm) - -.extern zap_fndbyte -.extern zap_fndchr -.extern zap_foreach -.extern zap_memcmp -.extern zap_memcpy -.extern zap_memeq -.extern zap_memfill -.extern zap_memfill -.extern zap_strcmp -.extern zap_strcpy -.extern zap_streq -.extern zap_strfill -.extern zap_strlen - -#else +#include <zap/bs.h> #if defined(sus_lang_cxx) extern "C" { #endif -sus_attr_hot sus_attr_nothrw sus_attr_useret size_t zap_fndbyte( void const * ptr, size_t num, unsigned char byte); -sus_attr_hot sus_attr_nothrw sus_attr_useret size_t zap_fndchr( char const * str, char chr); -sus_attr_hot void zap_foreach( void * ptr, size_t sz, size_t num, void (* fn)(void *)); -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_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 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, unsigned char 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); +__attribute__ ((hot,nothrow,warn_unused_result)) zap_sz zap_fndbyte( void const * ptr, zap_sz num, unsigned char byte); +__attribute__ ((hot,nothrow,warn_unused_result)) zap_sz zap_fndchr( char const * str, char chr); +__attribute__ ((hot)) void zap_foreach( void * ptr, zap_sz sz, zap_sz num, void (* fn)(void *)); +__attribute__ ((hot,nothrow)) void zap_memcat( void const * lptr, zap_sz llen,void const * rptr, zap_sz rlen, void * buf); +__attribute__ ((hot,nothrow,warn_unused_result)) zap_cmp zap_memcmp( void const * lstr, zap_sz num, void const * rstr); +__attribute__ ((hot,nothrow)) void zap_memcp( void const * in, zap_sz num, void * out); +__attribute__ ((hot,nothrow,warn_unused_result)) zap_bool zap_memeq( void const * lptr, zap_sz num, void const * rptr); +__attribute__ ((hot,nothrow)) void zap_memfill( void * ptr, zap_sz num, unsigned char val); +__attribute__ ((hot)) void zap_memgen( void * ptr, zap_sz sz, zap_sz num, void (* fn)(zap_sz,void *)); +__attribute__ ((hot,nothrow)) void zap_strcat( char const * lstr, char const * rstr,char * buf); +__attribute__ ((hot,nothrow,warn_unused_result)) zap_cmp zap_strcmp( char const * lstr, char const * rstr); +__attribute__ ((hot,nothrow)) zap_sz zap_strcp( char const * in, char * out); +__attribute__ ((hot,nothrow,warn_unused_result)) zap_bool zap_streq( char const * lstr, char const * rstr); +__attribute__ ((hot,nothrow)) zap_sz zap_strfill( char * lstr, char chr); +__attribute__ ((hot,nothrow,warn_unused_result)) zap_sz zap_strlen( char const * str); +__attribute__ ((hot,nothrow)) void zap_utf8dec( zap_chr8 const * in, zap_chr20 * out); +__attribute__ ((hot,nothrow)) zap_sz zap_utf8declen(zap_chr8 const * utf8); +__attribute__ ((hot,nothrow)) void zap_utf8enc( zap_chr20 const * in, zap_chr8 * out); +__attribute__ ((hot,nothrow)) zap_sz zap_utf8enclen(zap_chr20 const * utf20); +__attribute__ ((hot,nothrow)) void zap_win1252dec(zap_chr8 const * in, zap_chr20 * out); +__attribute__ ((hot,nothrow)) void zap_win1252enc(zap_chr20 const * in, zap_chr8 * out); -#endif #if defined(sus_lang_cxx) } #endif diff --git a/zap/src/abs.c b/zap/src/abs.c deleted file mode 100644 index 8fe97e6..0000000 --- a/zap/src/abs.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - 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 <zap/math.h> - -#include <stdint.h> - -#if zap_priv_fastimpl -__asm__ ( - ".globl zap_abs_c\n" - ".globl zap_abs_i\n" - ".globl zap_abs_l\n" - ".globl zap_abs_ll\n" - ".globl zap_abs_s\n" - - "zap_abs_c:\n" - /* - signed char val - */ -#if defined(sus_arch_amd64) || defined(sus_arch_ia32) - "movb %dil,%al\n" - "sarb $0x3F,%al\n" - "xorb %al,%dil\n" - "subb %al,%dil\n" - "movb %dil,%al\n" - "ret\n" -#endif - - "zap_abs_i:\n" - /* - int val - */ -#if defined(sus_arch_amd64) || defined(sus_arch_ia32) - "movl %edi,%eax\n" - "sarl $0x3F,%eax\n" - "xorl %eax,%edi\n" - "subl %eax,%edi\n" - "movl %edi,%eax\n" - "ret\n" -#endif - - "zap_abs_l:\n" - /* - long val - */ -#if defined(sus_arch_amd64) - "movq %rdi,%rax\n" - "sarq $0x3F,%rax\n" - "xorq %rax,%rdi\n" - "subq %rax,%rdi\n" - "movq %rdi,%rax\n" - "ret\n" -#endif - - "zap_abs_ll:\n" - /* - long long val - */ -#if defined(sus_arch_amd64) - "movq %rdi,%rax\n" - "sarq $0x3F,%rax\n" - "xorq %rax,%rdi\n" - "subq %rax,%rdi\n" - "movq %rdi,%rax\n" - "ret\n" -#endif - - "zap_abs_s:\n" - /* - short val - */ -#if defined(sus_arch_amd64) || defined(sus_arch_ia32) - "movw %di,%ax\n" - "sarw $0x3F,%ax\n" - "xorw %ax,%di\n" - "subw %ax,%di\n" - "movw %di,%ax\n" - "ret\n" -#endif -); -#else -#define zap_local_abs(_typ,_sufx) \ - _typ zap_abs_ ## _sufx (_typ const _val) {return _val > (_typ)0x0 ? _val : -_val;} - -zap_local_abs(signed char,c) -zap_local_abs(int,i) -zap_local_abs(long,l) -zap_local_abs(long long,ll) -zap_local_abs(short,s) - -#endif diff --git a/zap/src/fastimpl.c b/zap/src/fastimpl.c deleted file mode 100644 index 2541a41..0000000 --- a/zap/src/fastimpl.c +++ /dev/null @@ -1,12 +0,0 @@ -/* - 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> - -bool const zap_fastimpl = zap_priv_fastimpl; diff --git a/zap/src/fma.c b/zap/src/fma.c deleted file mode 100644 index b2f45ad..0000000 --- a/zap/src/fma.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - 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 <zap/math.h> - -#include <stdint.h> - -#if zap_priv_fastimpl -__asm__ ( - ".globl zap_fma_c\n" - ".globl zap_fma_i\n" - ".globl zap_fma_l\n" - ".globl zap_fma_ll\n" - ".globl zap_fma_s\n" - ".globl zap_fma_uc\n" - ".globl zap_fma_ui\n" - ".globl zap_fma_ul\n" - ".globl zap_fma_ull\n" - ".globl zap_fma_us\n" - - "zap_fma_c:\n" - /* - signed char a - signed char b - signed char c - */ -#if defined(sus_arch_amd64) - "movb %sil,%al\n" - "imulb %dl\n" - "addb %dil,%al\n" - "ret\n" -#endif - - "zap_fma_i:\n" - /* - int a - int b - int c - */ -#if defined(sus_arch_amd64) - "movl %edx,%eax\n" - "imull %esi\n" - "addl %edi,%eax\n" - "ret\n" -#endif - - "zap_fma_l:\n" - /* - long a - long b - long c - */ -#if defined(sus_arch_amd64) - "movq %rdx,%rax\n" - "imulq %rsi\n" - "addq %rdi,%rax\n" - "ret\n" -#endif - - "zap_fma_ll:\n" - /* - long long a - long long b - long long c - */ -#if defined(sus_arch_amd64) - "movq %rdx,%rax\n" - "imulq %rsi\n" - "addq %rdi,%rax\n" - "ret\n" -#endif - - "zap_fma_s:\n" - /* - short a - short b - short c - */ -#if defined(sus_arch_amd64) - "movw %dx,%ax\n" - "imulw %si\n" - "addw %di,%ax\n" - "ret\n" -#endif - - "zap_fma_uc:\n" - /* - unsigned char a - unsigned char b - unsigned char c - */ -#if defined(sus_arch_amd64) - "movb %sil,%al\n" /* mulb uses ax instead of al:dl (like the other variants), so we don't need to worry about it overwritting dl. */ - "mulb %dl\n" - "addb %dil,%al\n" - "ret\n" -#endif - - "zap_fma_ui:\n" - /* - unsigned int a - unsigned int b - unsigned int c - */ -#if defined(sus_arch_amd64) - "movl %edx,%eax\n" - "mull %esi\n" - "addl %edi,%eax\n" - "ret\n" -#endif - - "zap_fma_ul:\n" - /* - unsigned long a - unsigned long b - unsigned long c - */ -#if defined(sus_arch_amd64) - "movq %rdx,%rax\n" - "mulq %rsi\n" - "addq %rdi,%rax\n" - "ret\n" -#endif - - "zap_fma_ull:\n" - /* - unsigned long long a - unsigned long long b - unsigned long long c - */ -#if defined(sus_arch_amd64) - "movq %rdx,%rax\n" /* rdx get overwritten by mulq, so might as well just make it the first operand (in multiplication, the order is meaningless). */ - "mulq %rsi\n" - "addq %rdi,%rax\n" - "ret\n" -#endif - - "zap_fma_us:\n" - /* - unsigned short a - unsigned short b - unsigned short c - */ -#if defined(sus_arch_amd64) - "movw %dx,%ax\n" - "mulw %si\n" - "addw %di,%ax\n" - "ret\n" -#endif -); -#else -#define zap_local_fma(_typ,_sufx) \ - _typ zap_fma_ ## _sufx (_typ const _a,_typ const _b,_typ const _c) {return _a + _b * _c;} - -zap_local_fma(signed char,c) -zap_local_fma(int,i) -zap_local_fma(long,l) -zap_local_fma(long long,ll) -zap_local_fma(short,s) -zap_local_fma(unsigned char,uc) -zap_local_fma(unsigned int,ui) -zap_local_fma(unsigned long,ul) -zap_local_fma(unsigned long long,ull) -zap_local_fma(unsigned short,us) - -#endif diff --git a/zap/src/fndbyte.c b/zap/src/fndbyte.c deleted file mode 100644 index e6e6070..0000000 --- a/zap/src/fndbyte.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - 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 <zap/mem.h> - -#include <stddef.h> -#include <stdint.h> - -#if zap_priv_fastimpl -__asm__ ( - ".globl zap_fndbyte\n" - - "zap_fndbyte:\n" - /* - void const * pos - size_t num - unsigned char 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,unsigned char const _byte) { - unsigned char const * startpos = _ptr; - unsigned char const * pos = startpos; - unsigned char const * const afterbuf = pos + _num; - for (;pos != afterbuf;++pos) {sus_unlikely (*pos == _byte) {return pos - startpos;}} - return SIZE_MAX; -} -#endif diff --git a/zap/src/fndchr.c b/zap/src/fndchr.c deleted file mode 100644 index fc4eb2b..0000000 --- a/zap/src/fndchr.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - 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 <zap/mem.h> - -#include <stddef.h> -#include <stdint.h> - -#if zap_priv_fastimpl -__asm__ ( - ".globl 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 SIZE_MAX;} - } - sus_unreach(); -} -#endif diff --git a/zap/src/mem/fndbyte.S b/zap/src/mem/fndbyte.S new file mode 100644 index 0000000..4413b42 --- /dev/null +++ b/zap/src/mem/fndbyte.S @@ -0,0 +1,59 @@ +/* + 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> + +.globl zap_fndbyte + +zap_fndbyte: + + /* + void const * ptr + zap_sz num + unsigned char byte + */ + +#if defined(__amd64__) + + # rax: Address of the current element. + # rdi: Address of the first element. + # rsi: Address of the element after the last element. + # rdx: Byte value. + # rcx: Current byte. + + movq %rdi,%rax + + addq %rdi,%rsi + + # Iterate over the array: +.loop: + + # Check if we have reached the end of the array: + cmpq %rax,%rsi + je .nfnd + + # Check if we have found the byte value: + movb (%rax),%cl + cmpb %cl,%dl + je .fnd + + # Continue to the next byte: + incq %rax + jmp .loop + + # Found: +.fnd: + + subq %rdi,%rax + ret + + # Not found: +.nfnd: + + movq $0xFFFFFFFFFFFFFFFF,%rax + ret + +#endif diff --git a/zap/src/mem/fndchr.S b/zap/src/mem/fndchr.S new file mode 100644 index 0000000..2982e7e --- /dev/null +++ b/zap/src/mem/fndchr.S @@ -0,0 +1,57 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Pudhic 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> + +.globl zap_fndchr + +zap_fndchr: + + /* + char const * str + char chr + */ + +#if defined(__amd64__) + + # rdi: Address of the first character. + # rsi: Character to be found. + # rax: Address of the current character. + # rdx: Current character. + + movq %rdi,%rax + + # Iterate over the string: +.loop: + + # Copy the character into a register: + movb (%rax),%dl + + # Check if we have found the character: + cmpb %dl,%sil + je .fnd + + # Check if we have found the null-terminator: + testb %dl,%dl + jz .nfnd + + # Continue to the next character: + incq %rax + jmp .loop + + # Found: +.fnd: + + subq %rdi,%rax + ret + + # Not found: +.nfnd: + + movq $0xFFFFFFFFFFFFFFFF,%rax + ret + +#endif diff --git a/zap/src/mem/foreach.S b/zap/src/mem/foreach.S new file mode 100644 index 0000000..fe96538 --- /dev/null +++ b/zap/src/mem/foreach.S @@ -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> + +.globl zap_foreach + +zap_foreach: + + /* + void * ptr + zap_sz sz + zap_sz num + void (* fn)(void *) + */ + +#if defined(__amd64__) + + # rbx: Address of the current element. + # r12: Address of the element after the last input element. + # r13: Size of each input element. + # r14: Address of the function. + + # We're gonna use callee-saved registers for storing values so they don't get overwritten with each function call. + + # Push the callee-saved registers: + pushq %rbx + pushq %r12 + pushq %r13 + pushq %r14 + + # Move registers into place: + movq %rdi,%rbx + movq %rsi,%r13 + movq %rcx,%r14 + + # Get the one-past-the-end address: + movq %rdx,%r12 + imulq %r13,%r12 # Calculate the array size in bytes (sz * num). We're using signed multiply because the equivalent using the unsigned instruction would use more instructions. + addq %rbx,%r12 + + # Iterate through the array: +.loop: + + # Check if we have reached the one-past-the-end address: + cmpq %rbx,%r12 + je .done + + # Call the provided function: + movq %rbx,%rdi # Provide the current address to the function. + call *%r14 # We don't need to save any registers for this as we only use callee-saved registers. + + # Continue to the next element: + addq %r13,%rbx + jmp .loop + + # Finish: +.done: + + # Restore the callee-saved registers: + popq %r14 + popq %r13 + popq %r12 + popq %rbx + + ret + +#endif diff --git a/zap/src/strdup.c b/zap/src/mem/memcat.c index 183a909..f3e9a9b 100644 --- a/zap/src/strdup.c +++ b/zap/src/mem/memcat.c @@ -8,12 +8,9 @@ #include <zap/mem.h> -#include <stdlib.h> +#include <stddef.h> -char * zap_strdup(sus_attr_unused char const * const _str) { -#if !defined(zap_priv_nostdlib) - return zap_memdup(_str,zap_strlen(_str) + 0x1u); -#else - return NULL; -#endif +void zap_memcat(void const * const _lptr,zap_sz const _llen,void const * const _rptr,zap_sz const _rlen,void * const _buf) { + zap_memcp(_lptr,_llen,_buf); + zap_memcp(_rptr,_rlen,(unsigned char *)_buf + _llen); } diff --git a/zap/src/memcmp.c b/zap/src/mem/memcmp.c index 0fdf13a..601da99 100644 --- a/zap/src/memcmp.c +++ b/zap/src/mem/memcmp.c @@ -8,16 +8,14 @@ #include <zap/mem.h> -#include <stddef.h> - -int_least8_t zap_memcmp(void const * const _lstr,size_t const _num,void const * const _rstr) { +zap_cmp zap_memcmp(void const * const _lstr,zap_sz const _num,void const * const _rstr) { unsigned char const * lpos = _lstr; unsigned char const * rpos = _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_MIN : INT_LEAST8_MAX;} + sus_likely (lbyte != rbyte) {return lbyte < rbyte ? zap_lt : zap_gt;} } - return 0x0; + return zap_eq; } diff --git a/zap/src/mem/memcp.S b/zap/src/mem/memcp.S new file mode 100644 index 0000000..ead0718 --- /dev/null +++ b/zap/src/mem/memcp.S @@ -0,0 +1,107 @@ +/* + 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> + +.globl zap_memcp + +zap_memcp: + + /* + void const * in + zap_sz num + void * out + */ +#if defined(__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(__AVX__) + # AVX support 256-bit moves. + + # Copy 32 bytes: +.big20cp: + + # Check if there are at least 32 bytes remaining: + cmpq $0x20,%rsi + jl .big10cp # If not, skip to the 10 byte copying. + + # Copy: + vmovups (%rdi),%ymm0 # Move into a register. + vmovups %ymm0,(%rdx) # And then back into memory. + + # Continue: + addq $0x20,%rdi + addq $0x20,%rdx + subq $0x20,%rsi + jmp .big20cp + +#endif + + # AMD64 requires SSE(2). + + # Copy 16 bytes: +.big10cp: + + # Check if there are at least 16 bytes remaining: + cmpq $0x10,%rsi + jl .wrdcp + + # Copy: + movdqu (%rdi),%xmm0 + movdqu %xmm0,(%rdx) + + # Continue: + addq $0x10,%rdi + addq $0x10,%rdx + subq $0x10,%rsi + jmp .big10cp + + # Copy one word (8 bytes): +.wrdcp: + + # Check if there are at least 8 bytes remaining: + cmpq $0x8,%rsi + jl .bytecp + + # Copy: + movq (%rdi),%rcx + movq %rcx,(%rdx) + + # Continue: + addq $0x8,%rdi + addq $0x8,%rdx + subq $0x8,%rsi + jmp .wrdcp + + # Copy one byte: +.bytecp: + + # Check if we have any bytes remaining: + testq %rsi,%rsi + jz .done + + # Copy: + movb (%rdi),%cl + movb %cl,(%rdx) + + # Continue: + incq %rdi + incq %rdx + decq %rsi + jmp .bytecp + + # Finish: +.done: + + ret + +#endif diff --git a/zap/src/mem/memeq.S b/zap/src/mem/memeq.S new file mode 100644 index 0000000..cf554c2 --- /dev/null +++ b/zap/src/mem/memeq.S @@ -0,0 +1,82 @@ +/* + 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> + +.globl zap_memeq + +zap_memeq: + + /* + void const * lptr + zap_sz num + void const * rptr + */ + +#if defined(__amd64__) + + /* rdi: Left pointer. */ + /* rsi: Number of remaining elements. */ + /* rdx: Right pointer. */ + /* rax: Current left element. */ + /* rcx: Current right element. */ + + /* Compare words: */ +.wrdcmp: + + /* Check if there's at least one word left: */ + cmpq $0x8,%rsi + jl .bytecmp /* If not, skip to byte checks: */ + + /* Copy the values into registers: */ + movq (%rdi),%rax + movq (%rdx),%rcx + + /* Check if the words are equal: */ + cmpq %rax,%rcx + jne .neq + + /* Mark eight more bytes as equal: */ + addq $0x8,%rdi + addq $0x8,%rdx + subq $0x8,%rsi + + /* Continue to the next word: */ + jmp .wrdcmp + + /* Compare bytes: */ +.bytecmp: + + /* Check if there are any bytes left: */ + testq %rsi,%rsi + jz .eq /* If we have reached the final element, all previous elements have compared equal, and the memory sequences are equal. */ + + /* Copy the values into registers: */ + movb (%rdi),%al + movb (%rdx),%cl + + cmpb %al,%cl + jne .neq + + /* Mark another byte as equal: */ + incq %rdi + incq %rdx + decq %rsi + + /* Continue to the next byte: */ + jmp .bytecmp + + /* The memory sequences have compared equal: */ +.eq: + movb $0xFF,%al + ret + + /* The memory sequences have compared NOT equal: */ +.neq: + movb $0x0,%al + ret + +#endif diff --git a/zap/src/mem/memfill.S b/zap/src/mem/memfill.S new file mode 100644 index 0000000..63a1aad --- /dev/null +++ b/zap/src/mem/memfill.S @@ -0,0 +1,45 @@ +/* + 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> + +.globl zap_memfill + +zap_memfill: + + /* + void const * ptr + zap_sz num + unsigned char val + */ + +#if defined(__amd64__) + + # rdi: Address of the current element. + # rsi: Address of the element after the last element. + # rdx: Byte value. + + addq %rdi,%rsi + + # Iterate over buffer: +.loop: + + # Check if we have reached the final element: + cmpq %rdi,%rsi + je .done # Exit loop if we have. + + # Set the value of the current element: + movb %dl,(%rdi) + + # Continue to next element: + incq %rdi + jmp .loop + + # Finish: +.done: + ret + +#endif diff --git a/zap/src/mem/memgen.c b/zap/src/mem/memgen.c new file mode 100644 index 0000000..a39e326 --- /dev/null +++ b/zap/src/mem/memgen.c @@ -0,0 +1,25 @@ +/* + 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> + +/*.globl zap_memgen + +zap_memgen:*/ + + /* + void * ptr + zap_sz sz + zap_sz num + void (* fn)(zap_sz,void *) + */ + +void zap_memgen(void * const _ptr,zap_sz const _sz,zap_sz const _num,void (* const _fn)(zap_sz,void *)) { + unsigned char * ptr = _ptr; + unsigned char * const afterbuf = ptr + _sz * _num; + for (;ptr != afterbuf;ptr += _sz) {_fn((ptr - (unsigned char *)_ptr) / _sz,ptr);} +} + diff --git a/zap/src/foreach.c b/zap/src/mem/strcat.c index 5e281d4..f7f66c8 100644 --- a/zap/src/foreach.c +++ b/zap/src/mem/strcat.c @@ -10,9 +10,10 @@ #include <stddef.h> -void zap_foreach(void * const _ptr,size_t const _sz,size_t const _num,void (* const _fn)(void *)) { - unsigned char * pos = _ptr; - size_t const numbyte = _sz * _num; - unsigned char * const afterbuf = pos + numbyte; - for (;pos != afterbuf;pos += _sz) {_fn(pos);} +void zap_strcat(char const * const _lstr,char const * const _rstr,char * const _buf) { + zap_sz const llen = zap_strlen (_lstr); + zap_sz const rlen = zap_strlen (_rstr); + zap_memcp(_lstr,llen,_buf); + zap_memcp(_rstr,rlen,_buf + llen); + _buf[llen + rlen] = '\x0'; } diff --git a/zap/src/strcmp.c b/zap/src/mem/strcmp.c index 0ed0a59..691717a 100644 --- a/zap/src/strcmp.c +++ b/zap/src/mem/strcmp.c @@ -10,14 +10,14 @@ #include <stdint.h> -int_least8_t zap_strcmp(char const * const _lstr,char const * const _rstr) { +zap_cmp 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_MIN : INT_LEAST8_MAX;} - sus_unlikely (lchr == (unsigned char)0x0) {return 0x0;} + sus_likely (lchr != rchr) {return lchr < rchr ? zap_lt : zap_gt;} + sus_unlikely (lchr == (unsigned char)0x0) {return zap_eq;} } sus_unreach(); } diff --git a/zap/src/mem/strcp.S b/zap/src/mem/strcp.S new file mode 100644 index 0000000..04c3198 --- /dev/null +++ b/zap/src/mem/strcp.S @@ -0,0 +1,53 @@ +/* + 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> + +.globl zap_strcp + +zap_strcp: + + /* + char const * in + char const * out + */ + +#if defined(__amd64__) + + # rax: Address of the current input character. + # rdi: Address of the first input character. + # rsi: Address of the current output character. + # rdx: Current character. + + movq %rdi,%rax + + # Iterate over the strings: +.loop: + + # Copy character: + movb (%rax),%dl # Move it into a register... + movb %dl,(%rsi) # ... and then back into memory. + + # Check if we have reached the null-terminator: + testb %dl,%dl + jz .done + + # Continue to the next character: + + incq %rax + incq %rsi + jmp .loop + + # Finish: +.done: + + # Get the length of the (input) string: + subq %rdi,%rax + decq %rax # We do not count the null-terminator in the string length. + + ret + +#endif diff --git a/zap/src/mem/streq.S b/zap/src/mem/streq.S new file mode 100644 index 0000000..d331e93 --- /dev/null +++ b/zap/src/mem/streq.S @@ -0,0 +1,57 @@ +/* + 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> + +.globl zap_streq + +zap_streq: + + /* + char const * lstr + char const * rstr + */ + +#if defined(__amd64__) + + # rdi: Address of the current left character. + # rsi: Address of the current right character. + # rax: Current left character. + # rdx: Current right character. + + # Iterate over the strings: +.loop: + + # Copy the characters into registers: + movb (%rdi),%al + movb (%rsi),%dl + + # Check if the characters are equal: + cmpb %al,%dl + jne .neq # If not, the strings also aren't equal. + + # Check if we have reached the null-terminator: + testb %al,%al + jz .eq # If so, all previous characters have compared equal, and the strings are equal. + + # Continue to the next characters: + incq %rdi + incq %rsi + jmp .loop + + # The strings have compared equal: +.eq: + + movb $0xFF,%al + ret + + /* The strings have compared unequal: */ +.neq: + + movb $0x0,%al + ret + +#endif diff --git a/zap/src/mem/strfill.S b/zap/src/mem/strfill.S new file mode 100644 index 0000000..277865e --- /dev/null +++ b/zap/src/mem/strfill.S @@ -0,0 +1,48 @@ +/* + 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> + +.globl zap_strfill + +zap_strfill: + + /* + char * str + char chr + */ + +#if defined(__amd64__) + + # rdi: Address of the first character of the string. + # rsi: Fill character. + # rax: Address of the current character. + + movq %rdi,%rax + + # Iterate over string: +.loop: + + # Check if we have reached the null-terminator: + cmpb $0x0,(%rax) + je .done # Exit loop if we have. + + # Set the value of the current element: + movb %sil,(%rax) + + # Continue to next character: + incq %rax + jmp .loop + + # Finish: +.done: + + # Get the length of the string: + subq %rdi,%rax + + ret + +#endif diff --git a/zap/src/mem/strlen.S b/zap/src/mem/strlen.S new file mode 100644 index 0000000..4cb435f --- /dev/null +++ b/zap/src/mem/strlen.S @@ -0,0 +1,46 @@ +/* + 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> + +.globl zap_strlen + +zap_strlen: + + /* + char const * str + */ + +#if defined(__amd64__) + + # rax: Address of the current character. + # rdx: Current character. + + movq %rdi,%rax + + # Iterate over the string: +.loop: + + # Move the character into a register: + movb (%rax),%dl + + # Check if we have reached the null-terminator: + testb %dl,%dl + jz .done # If so, we are done. + + # Continue to the next character: + incq %rax + jmp .loop + + # Done: +.done: + + # Get the length: + subq %rdi,%rax + + ret + +#endif diff --git a/zap/src/mem/utf8dec.c b/zap/src/mem/utf8dec.c new file mode 100644 index 0000000..32ebd00 --- /dev/null +++ b/zap/src/mem/utf8dec.c @@ -0,0 +1,51 @@ +/* + 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 <zap/mem.h> + +void zap_utf8dec(zap_chr8 const * const _in,zap_chr20 * const _out) { + zap_chr8 const * in = _in; + zap_chr20 * out = _out; + for (;;++out) { + zap_chr8 const oct = *in; + if (oct >= 0xF0u) { /* Four octets. */ + zap_chr20 chr = ((zap_chr20)oct ^ 0xF0u) << 0x12u; + ++in; + chr += ((zap_chr20)*in ^ 0x80u) << 0xCu; + ++in; + chr += ((zap_chr20)*in ^ 0x80u) << 0x6u; + ++in; + chr += (zap_chr20)*in ^ 0x80u; + ++in; + *out = chr; + continue; + } + if (oct >= 0xE0u) { /* Three octets. */ + zap_chr20 chr = ((zap_chr20)oct ^ 0xE0u) << 0xCu; + ++in; + chr += ((zap_chr20)*in ^ 0x80u) << 0x6u; + ++in; + chr += (zap_chr20)*in ^ 0x80u; + ++in; + *out = chr; + continue; + } + if (oct >= 0xC0u) { /* Two octets. */ + zap_chr20 chr = ((zap_chr20)oct ^ 0xC0u) << 0x6u; + ++in; + chr += (zap_chr20)*in ^ 0x80u; + ++in; + *out = chr; + continue; + } + /* One octet. */ + *out = oct; + ++in; + sus_unlikely (oct == 0x0u) {break;} + } +} diff --git a/zap/src/mem/utf8declen.c b/zap/src/mem/utf8declen.c new file mode 100644 index 0000000..202e995 --- /dev/null +++ b/zap/src/mem/utf8declen.c @@ -0,0 +1,35 @@ +/* + 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 <zap/mem.h> + +#include <stddef.h> + +zap_sz zap_utf8declen(zap_chr8 const * const _in) { + zap_sz len = 0x0u; + zap_chr8 const * in; + for (in = _in;;++len) { + zap_chr8 const oct = *in; + sus_unlikely (oct == 0x0u) {break;} + if (oct >= 0xF0u) { + in += 0x4u; + continue; + } + if (oct >= 0xE0u) { + in += 0x3u; + continue; + } + if (oct >= 0xC0u) { + in += 0x2u; + continue; + } + ++in; + continue; + } + return len; +} diff --git a/zap/src/mem/utf8enc.S b/zap/src/mem/utf8enc.S new file mode 100644 index 0000000..24e09d8 --- /dev/null +++ b/zap/src/mem/utf8enc.S @@ -0,0 +1,152 @@ +/* + 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> + +.globl zap_utf8enc + +zap_utf8enc: + + /* + zap_chr20 const * in + zap_chr8 * out + */ + +#if defined(__amd64__) + + # rdi: Current input codepoint. + # rsi: Current output octet. + # rax: Current codepoint. + # rdx: Temporary. + + # Iterate over the input: +.loop: + + movl (%rdi),%eax + + cmpl $0xFFFF,%eax + jg .oct4 + + cmpl $0x7FF,%eax + jg .oct3 + + cmpl $0x7F,%eax + jg .oct2 # Otherwise, only one octet is needed. + + # One octet: +.oct1: + + # Octet #0: + movb %al,(%rsi) # No conversion needed: + + incq %rsi + + # Test if we have reached the null-terminator: + testb %al,%al + jz .done + + jmp .cnt + + # Two octets: +.oct2: + + /* Octet #0: */ + movl %eax,%edx + shrl $0x6,%edx + orb $0xC0,%dl + movb %dl,(%rsi) + + incq %rsi + + # Octet #1: + movl %eax,%edx + andb $0x3F,%dl + orb $0x80,%dl + movb %dl,(%rsi) + + incq %rsi + + jmp .cnt + + # Three octets: +.oct3: + + # Octet #0: + movl %eax,%edx + shrl $0xC,%edx + orb $0xE0,%dl + movb %dl,(%rsi) + + incq %rsi + + # Octet #1: + movl %eax,%edx + shrl $0x6,%edx + andb $0x3F,%dl + orb $0x80,%dl + movb %dl,(%rsi) + + incq %rsi + + # Octet #2: + movl %eax,%edx + andb $0x3F,%dl + orb $0x80,%dl + movb %dl,(%rsi) + + incq %rsi + + jmp .cnt + + # Four octets:/ +.oct4: + + # Octet #0: + movl %eax,%edx + shrl $0x12,%edx + orb $0xF0,%dl + movb %dl,(%rsi) + + incq %rsi + + # Octet #1: + movl %eax,%edx + shrl $0xC,%edx + andb $0x3F,%dl + orb $0x80,%dl + movb %dl,(%rsi) + + incq %rsi + + # Octet #2: + movl %eax,%edx + shrl $0x6,%edx + andb $0x3F,%dl + orb $0x80,%dl + movb %dl,(%rsi) + + incq %rsi + + # Octet #3: + movl %eax,%edx + andb $0x3F,%dl + orb $0x80,%dl + movb %dl,(%rsi) + + incq %rsi + + # Continue to the next codepoint: +.cnt: + + addq $0x4,%rdi + jmp .loop + + # Done: +.done: + + ret + +#endif diff --git a/zap/src/mem/utf8enclen.S b/zap/src/mem/utf8enclen.S new file mode 100644 index 0000000..1c80e6a --- /dev/null +++ b/zap/src/mem/utf8enclen.S @@ -0,0 +1,80 @@ +/* + 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> + +.globl zap_utf8enclen + +zap_utf8enclen: + + /* + zap_chr20 const * utf20 + */ + +#if defined(__amd64__) + + # rdi: Address of the current character. + # rax: Length of the string. + # rsi: Current character. + + movq $0x0,%rax + + # Iterate over the input: +.loop: + + movl (%rdi),%esi + + # Test if we have reached the null-terminator: + testl %esi,%esi + jz .done + + cmpl $0xFFFF,%esi + jg .oct4 + + cmpl $0x7FF,%esi + jg .oct3 + + cmpl $0x7F,%esi + jg .oct2 + + # One octet: +.oct1: + + incq %rax + + jmp .cnt + + # Two octets: +.oct2: + + addq $0x2,%rax + + jmp .cnt + + # Three octets: +.oct3: + + addq $0x3,%rax + + jmp .cnt + + # Four octets: +.oct4: + + addq $0x4,%rax + + # Continue to the next codepoint: +.cnt: + + addq $0x4,%rdi + jmp .loop + + # Done: +.done: + + ret + +#endif diff --git a/zap/src/mem/win1252dec.c b/zap/src/mem/win1252dec.c new file mode 100644 index 0000000..529bbe3 --- /dev/null +++ b/zap/src/mem/win1252dec.c @@ -0,0 +1,111 @@ +/* + 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 <zap/mem.h> + +void zap_win1252dec(zap_chr8 const * const _in,zap_chr20 * const _out) { + zap_chr8 const * in = _in; + zap_chr20 * out = _out; + for (;;++in,++out) { + zap_chr8 const chr = *in; + switch (chr) { + default: + *out = *in; + break; + case 0x81: /* Bad characters. */ + case 0x8D: + case 0x8F: + case 0x90: + case 0x9D: + *out = 0xFFFDu; /* REPLACEMENT CHARACTER */ + break; + case 0x80: + *out = 0x20ACu; + break; + case 0x82: + *out = 0x201Au; + break; + case 0x83: + *out = 0x192u; + break; + case 0x84: + *out = 0x201Eu; + break; + case 0x85: + *out = 0x2026u; + break; + case 0x86: + *out = 0x2020u; + break; + case 0x87: + *out = 0x2021u; + break; + case 0x88: + *out = 0x2C6u; + break; + case 0x89: + *out = 0x2030u; + break; + case 0x8A: + *out = 0x160u; + break; + case 0x8B: + *out = 0x2039u; + break; + case 0x8C: + *out = 0x152u; + break; + case 0x8E: + *out = 0x17Du; + break; + case 0x91: + *out = 0x2018u; + break; + case 0x92: + *out = 0x2019u; + break; + case 0x93: + *out = 0x201Cu; + break; + case 0x94: + *out = 0x201Du; + break; + case 0x95: + *out = 0x2022u; + break; + case 0x96: + *out = 0x2013u; + break; + case 0x97: + *out = 0x2014u; + break; + case 0x98: + *out = 0x2DCu; + break; + case 0x99: + *out = 0x2122u; + break; + case 0x9A: + *out = 0x161u; + break; + case 0x9B: + *out = 0x203Au; + break; + case 0x9C: + *out = 0x153u; + break; + case 0x9E: + *out = 0x17Eu; + break; + case 0x9F: + *out = 0x178u; + break; + } + sus_unlikely (chr == 0x0u) {break;} + } +} diff --git a/zap/src/mem/win1252enc.c b/zap/src/mem/win1252enc.c new file mode 100644 index 0000000..147ddaf --- /dev/null +++ b/zap/src/mem/win1252enc.c @@ -0,0 +1,113 @@ +/* + 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 <zap/mem.h> + +void zap_win1252enc(zap_chr20 const * const _in,zap_chr8 * const _out) { + zap_chr20 const * in = _in; + zap_chr8 * out = _out; + for (;;++in,++out) { + zap_chr20 const chr = *in; + zap_chr8 const bad = 0x3Fu; + switch (chr) { + default: + sus_unlikely (chr > 0xFFu) { + *out = bad; + break; + } + sus_unlikely (chr >= 0x80u && chr <= 0x9Fu) { + *out = bad; + break; + } + *out = *in; + break; + case 0x20ACu: + *out = 0x80u; + break; + case 0x201Au: + *out = 0x82u; + break; + case 0x192u: + *out = 0x83u; + break; + case 0x201Eu: + *out = 0x84u; + break; + case 0x2026u: + *out = 0x85u; + break; + case 0x2020u: + *out = 0x86u; + break; + case 0x2021u: + *out = 0x87u; + break; + case 0x2C6u: + *out = 0x88u; + break; + case 0x2030u: + *out = 0x89u; + break; + case 0x160u: + *out = 0x8Au; + break; + case 0x2039u: + *out = 0x8Bu; + break; + case 0x152u: + *out = 0x8Cu; + break; + case 0x17Du: + *out = 0x8Eu; + break; + case 0x2018u: + *out = 0x91u; + break; + case 0x2019u: + *out = 0x92u; + break; + case 0x201Cu: + *out = 0x93u; + break; + case 0x201Du: + *out = 0x94u; + break; + case 0x2022u: + *out = 0x95u; + break; + case 0x2013u: + *out = 0x96u; + break; + case 0x2014u: + *out = 0x97u; + break; + case 0x2DCu: + *out = 0x98u; + break; + case 0x2122u: + *out = 0x99u; + break; + case 0x161u: + *out = 0x9Au; + break; + case 0x203Au: + *out = 0x9Bu; + break; + case 0x153u: + *out = 0x9Cu; + break; + case 0x17Eu: + *out = 0x9Eu; + break; + case 0x178u: + *out = 0x9Fu; + break; + } + sus_unlikely (chr == 0x0u) {break;} + } +} diff --git a/zap/src/memcpy.c b/zap/src/memcpy.c deleted file mode 100644 index ae923c3..0000000 --- a/zap/src/memcpy.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - 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 <zap/mem.h> - -#include <stddef.h> -#include <stdint.h> - -#if zap_priv_fastimpl -__asm__ ( - ".globl 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) { - unsigned char const * in = _in; - unsigned char * out = _out; - unsigned char 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 deleted file mode 100644 index 9b56314..0000000 --- a/zap/src/memdup.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - 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 <zap/mem.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 deleted file mode 100644 index 7dce213..0000000 --- a/zap/src/memeq.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - 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 <zap/mem.h> - -#include <stdbool.h> -#include <stddef.h> -#include <stdint.h> - -#if zap_priv_fastimpl -__asm__ ( - ".globl 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) { - unsigned char const * lpos = _lptr; - unsigned char const * rpos = _rptr; - unsigned char 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 deleted file mode 100644 index 1aebd29..0000000 --- a/zap/src/memfill.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - 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 <zap/mem.h> - -#include <stddef.h> -#include <stdint.h> - -#if zap_priv_fastimpl -__asm__ ( - ".globl zap_memfill\n" - - "zap_memfill:\n" - /* - void const * ptr - size_t num - unsigned char 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 %rdi,%rsi\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,unsigned char const _byte) { - unsigned char * pos = _ptr; - unsigned char * const afterbuf = pos + _num; - for (;pos != afterbuf;++pos) {*pos = _byte;} -} -#endif diff --git a/zap/src/strcpy.c b/zap/src/strcpy.c deleted file mode 100644 index 616af7f..0000000 --- a/zap/src/strcpy.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - 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 <zap/mem.h> - -#include <stddef.h> - -#if zap_priv_fastimpl -__asm__ ( - ".globl 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 inpos - _in;} - } - sus_unreach(); -} -#endif diff --git a/zap/src/streq.c b/zap/src/streq.c deleted file mode 100644 index 1ff4420..0000000 --- a/zap/src/streq.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - 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 <zap/mem.h> - -#include <stdbool.h> -#include <stdint.h> - -#if zap_priv_fastimpl -__asm__ ( - ".globl 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 deleted file mode 100644 index bd0af33..0000000 --- a/zap/src/strfill.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - 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 <zap/mem.h> - -#include <stdint.h> - -void zap_strfill(char * const _str,char const _chr) {zap_memfill(_str,zap_strlen(_str),(unsigned char)_chr);} diff --git a/zap/src/strlen.c b/zap/src/strlen.c deleted file mode 100644 index 84b7d28..0000000 --- a/zap/src/strlen.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - 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 <zap/mem.h> - -#include <stddef.h> - -#if zap_priv_fastimpl -__asm__ ( - ".globl 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 |