diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | CHANGELOG.txt | 15 | ||||
-rw-r--r-- | Makefile | 73 | ||||
-rw-r--r-- | README.html | 64 | ||||
-rw-r--r-- | test.cc | 151 | ||||
-rw-r--r-- | zap/Makefile | 64 | ||||
-rw-r--r-- | zap/include-priv/zap/priv.h | 11 | ||||
-rw-r--r-- | zap/include/zap/base.h | 42 | ||||
-rw-r--r-- | zap/include/zap/math.h | 94 | ||||
-rw-r--r-- | zap/include/zap/mem.h | 59 | ||||
-rw-r--r-- | zap/src/abs.c | 96 | ||||
-rw-r--r-- | zap/src/fastimpl.c | 6 | ||||
-rw-r--r-- | zap/src/fma.c | 171 | ||||
-rw-r--r-- | zap/src/fndbyte.c | 19 | ||||
-rw-r--r-- | zap/src/fndchr.c | 4 | ||||
-rw-r--r-- | zap/src/foreach.c | 10 | ||||
-rw-r--r-- | zap/src/memcmp.c | 8 | ||||
-rw-r--r-- | zap/src/memcpy.c | 10 | ||||
-rw-r--r-- | zap/src/memdup.c | 2 | ||||
-rw-r--r-- | zap/src/memeq.c | 10 | ||||
-rw-r--r-- | zap/src/memfill.c | 16 | ||||
-rw-r--r-- | zap/src/strcmp.c | 4 | ||||
-rw-r--r-- | zap/src/strcpy.c | 6 | ||||
-rw-r--r-- | zap/src/strdup.c | 2 | ||||
-rw-r--r-- | zap/src/streq.c | 4 | ||||
-rw-r--r-- | zap/src/strfill.c | 4 | ||||
-rw-r--r-- | zap/src/strlen.c | 4 |
27 files changed, 756 insertions, 194 deletions
@@ -1,4 +1,3 @@ *.a *.o -/build /test diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 96d5b7c..6c1910f 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,18 @@ +| F + +- Remove type specifier from version macro; +- Add mathematical functions abs and fma; +- Update documentation; +- Remove nothrw attribute from foreach; +- Remove UB from foreach test; +- Fix parameter mismatch in foreach test; +- Use unsigned char instead of uint_least8_t; +- Remove unnecessary casts; +- Add new headers: 'zap/math.h' (for mathematical functions), 'zap/mem.h' (for memory sequence functions); +- Restructure makefile; +- Fix not using INT_LEAST8_MAX and INT_LEAST8_MIN instead of INT8_MAX and INT8_MIN; +- Remove '/build' from gitignore; + | E - Fix incorrect version number; @@ -1,71 +1,20 @@ -# TOOLS +LIBZAP = zap/libzap.a -#CC = clang +.PHONY: clean install purge zap -# TOOL FLAGS +zap: + $(MAKE) -Czap -CFLAGS = \ - -Izap/include \ - -Izap/include-priv \ - -O3 \ - -fPIC \ - -g \ - -march=native \ - -std=c99 \ - -Wall \ - -Wextra \ - -Wpedantic - -# Uncomment to enable freestanding mode: -#CFLAGS += \ - -Dzap_priv_nostdlib \ - -ffreestanding - -# Uncomment to disable assembly algorithms: -#CFLAGS += -Dzap_priv_noasm - -# HEADERS - -HDRS = \ - zap/include-priv/zap/priv.h \ - zap/include/zap.h \ - -# BINARIES - -OBJS = \ - zap/src/fastimpl.o \ - zap/src/fndbyte.o \ - zap/src/fndchr.o \ - zap/src/foreach.o \ - zap/src/memcmp.o \ - zap/src/memcpy.o \ - zap/src/memdup.o \ - zap/src/memeq.o \ - zap/src/memfill.o \ - zap/src/strcmp.o \ - zap/src/strdup.o \ - zap/src/streq.o \ - zap/src/strfill.o \ - zap/src/strcpy.o \ - zap/src/strlen.o - -LIB = libzap.a - -# TARGETS - -.PHONY: clean install purge - -$(LIB): $(OBJS) - ar r $@ $(OBJS) - -install: $(LIB) +install: zap mkdir -pm755 $(HDRDIR)/zap mkdir -pm755 $(LIBDIR) install -Dm644 zap/include/zap/base.h $(HDRDIR)/zap - install -Dm755 $(LIB) $(LIBDIR)/$(LIB) + install -Dm644 zap/include/zap/math.h $(HDRDIR)/zap + install -Dm644 zap/include/zap/mem.h $(HDRDIR)/zap + install -Dm755 $(LIBZAP) $(LIBDIR) clean: - rm -fr $(OBJS) + $(MAKE) -Czap clean -purge: clean - rm -fr $(LIB) +purge: + $(MAKE) -Czap purge diff --git a/README.html b/README.html index d924e6d..1a08610 100644 --- a/README.html +++ b/README.html @@ -11,50 +11,90 @@ <p>The <i>install</i> target installs the headers to <i>$(HDRDIR)</i> and the library file to <i>$(LIBDIR)</i>.</p> <p>Instructions for building the test program may be found on the first line of <i>test.c</i>.</p> <h2>Documentation</h2> + <h3>abs</h3> + <h4>Synopsis</h4> + <code>#include <zap/math.h><br />signed char zap_abs_c(signed char val);<br />int zap_abs_i(int val);<br />long zap_abs_l(long val);<br />long long zap_abs_ll(long long val);<br />short zap_abs_s(short val);</code> + <h4>Description</h4> + <p>Returns the absolute value of <i>val</i>.</p> + <br /> + <h3>fma</h3> + <h4>Synopsis</h4> + <code>#include <zap/math.h><br />signed char zap_fma_c(signed char a,signed char b,signed char c);<br/>int zap_fma_i(int a,int b,int c);<br/>long zap_fma_l(long a,long b,long c);<br/>long long zap_fma_ll(long long a,long long b,long long c);<br/>short zap_fma_s(short a,short b,short c);<br/>unsigned char zap_fma_uc(unsigned char a,unsigned char b,unsigned char c);<br/>unsigned int zap_fma_ui(unsigned int a,unsigned int b,unsigned int c);<br/>unsigned long zap_fma_ul( unsigned long a,unsigned long b,unsigned long c);<br/>unsigned long long zap_fma_ull(unsigned long long a,unsigned long long b,unsigned long long c);<br/>unsigned short zap_fma_us( unsigned short a,unsigned short b,unsigned short c);</code> + <h4>Description</h4> + <p>Returns the the fused multiply-add of <i>a</i>, <i>b</i>, and <i>c</i>.</p> + <br /> <h3>fndbyte</h3> <h4>Synopsis</h4> - <code>#include <zap/base.h><br />size_t zap_fndbtyte(void const * ptr,size_t num,unsigned char byte);</code> + <code>#include <zap/mem.h><br />size_t zap_fndbtyte(void const * ptr,size_t num,unsigned char byte);</code> <h4>Description</h4> <p>Searches for the byte-value <i>byte</i> in the array pointed to by <i>ptr</i> within the bounds of <i>num</i>.</p> + <p>If <i>ptr</i> is not a valid pointer to a null-terminated string, the behaviour is undefined.</p> <p>If <i>num</i> is larger (but not smaller) than the number of bytes in the array, the behaviour is undefined.</p> - <p>If the byte-value is found within the domain, the position of it's first occurrence (starting at zero) is returned. Otherwise <i>SIZE_MAX</i> is returned.</p> + <p>If the byte-value is found within the domain, the position of it's first occurrence (starting at zero) is returned. Otherwise, <i>SIZE_MAX</i> is returned.</p> <br /> <h3>fndchr</h3> <h4>Synopsis</h4> - <code>#include <zap/base.h><br />size_t zap_fndchr(char const * str,char chr);</code> + <code>#include <zap/mem.h><br />size_t zap_fndchr(char const * str,char chr);</code> <h4>Description</h4> <p>Searches for the character <i>chr</i> in the string <i>str</i>.</p> - <p>If the character is found in the string, the position of it's first occurrence (starting at zero) is returned. Otherwise <i>SIZE_MAX</i> is returned.</p> + <p>If the character is found in the string, the position of it's first occurrence (starting at zero) is returned. Otherwise, <i>SIZE_MAX</i> is returned.</p> <p>If <i>str</i> is not a valid pointer to a null-terminated string, the behaviour is undefined.</p> <br /> <h3>foreach</h3> <h4>Synopsis</h4> - <code>#include <zap/base.h><br />void zap_foreach(void * ptr,size_t sz,size_t num,void (* fn)(void *));</code> + <code>#include <zap/mem.h><br />void zap_foreach(void * ptr,size_t sz,size_t num,void (* fn)(void *),void * * rem);</code> <h4>Description</h4> - <p>Iterates through the array pointed to by <i>ptr</i>, invoking the function <i>fn</i> with a pointer to the current element. Each pointer is equal to the laster pointer plus <i>sz</i>.</p> + <p>Iterates through the array pointed to by <i>ptr</i>, invoking the function <i>fn</i> with a pointer to the current element. Each pointer value after the first is equal to the previous plus <i>sz</i>.</p> + <p>If the pointed-to object of <i>rem</i> is not a null pointer, the iterations are started from that address. If <i>fn</i> throws an exception, the current position is written to the pointed-to object of <i>rem</i> (unless <i>rem</i> is a null pointer) and <i>foreach</i> returns the control-flow to the caller via this exception.</p> <p>If the expression <code>(sz * num)</code> is not a valid object size, the behaviour is undefined.</p> - <p>If <i>fn</i> is not a valid function pointer, the behaviour is undefined.</p> + <p>If <i>fn</i> is not a valid pointer to a function with C language linkage, the behaviour is undefined.</p> + <p>If <i>rem</i> is not a null pointer and the pointed-to object is not initialised to <i>NULL</i> before the call to <i>foreach</i>, the behaviour is undefined.</p> <br /> <h3>memcmp</h3> <h4>Synopsis</h4> - <code>#include <zap/base.h><br />int_least8_t zap_memcmp(void const * lptr,size_t num,void const * rptr);</code> + <code>#include <zap/mem.h><br />int_least8_t zap_memcmp(void const * lptr,size_t num,void const * rptr);</code> <h4>Description</h4> <p>Compares <i>num</i>-bytes of the arrays pointed to by <i>lptr</i> and <i>rptr</i>.</p> <p>The returned value is determined by the first byte found to be different in the two arrays. If the byte has a larger value in <i>lptr</i>, a negative (less than zero) value is returned. If it's the other way, a positive (greater than zero) value is returned. Otherwise (the arrays where represented the same), zero is returned.</p> <p>If <i>lptr</i> or <i>rptr</i> (or both) are not valid pointers to arrays, the behaviour is undefined.</p> <p>If <i>num</i> is larger (but not smaller) than the number of bytes of the smallest array, the behaviour is undefined.</p> <br /> + <h3>memcpy</h3> + <h4>Synopsis</h4> + <code>#include <zap/mem.h><br />void zap_memcpy(void const * in,size_t num,void * out);</code> + <h4>Description</h4> + <p>Copies <i>num</i>-bytes from the buffer pointed to by <i>in</i> into the same relative position in the buffer pointer to by <i>out</i>.</p> + <p>If <i>in</i> or <i>out</i> (or both) are not valid pointers to arrays, the behaviour is undefined.</p> + <p>If <i>num</i> is larger (but not smaller) than the number of bytes of the smallest array, the behaviour is undefined.</p> + <br /> <h3>memdup</h3> <h4>Synopsis</h4> - <code>#include <zap/base.h><br />void * zap_memdup(void const * ptr,size_t num);</code> + <code>#include <zap/mem.h><br />void * zap_memdup(void const * ptr,size_t num);</code> <h4>Description</h4> <p>Copies <i>num</i>-bytes from the array pointed to by <i>ptr</i> into a newly-allocated array. The new array is allocated by <i>malloc</i>.</p> <p>The returned value is a pointer to the new array.</p> <p>If <i>num</i> is larger (but not smaller) than the number of bytes in the array, the behaviour is undefined.</p> <br /> + <h3>memeq</h3> + <h4>Synopsis</h4> + <code>#include <zap/mem.h><br />bool zap_memeq(void const * lptr,size_t num,void * rptr);</code> + <h4>Description</h4> + <p>Checks <i>num</i>-bytes of the buffers pointed to by <i>lptr</i> and <i>rptr</i> for equality.</p> + <p>If any two bytes are found to be different in the two buffers, false is returned. Otherwise, true is returned.</p> + <p>If <i>lptr</i> or <i>rptr</i> (or both) are not valid pointers to arrays, the behaviour is undefined.</p> + <p>If <i>num</i> is larger (but not smaller) than the number of bytes of the smallest array, the behaviour is undefined.</p> + <br /> + <h3>memfill</h3> + <h4>Synopsis</h4> + <code>#include <zap/mem.h><br />void zap_memfill(void const * ptr,size_t num,unsigned char byte);</code> + <h4>Description</h4> + <p>Fills <i>num</i>-bytes of the buffer pointed to by <i>ptr</i> with the representation of <i>byte</i>.</p> + <p>If <i>ptr</i> is not a valid pointer to an array, the behaviour is undefined.</p> + <p>If <i>num</i> is larger (but not smaller) than the number of bytes of in the array, the behaviour is undefined.</p> + <br /> <h3>streq</h3> <h4>Synopsis</h4> - <code>#include <zap/base.h><br />_Bool zap_streq(char const * lstr,char const * rstr);</code> + <code>#include <zap/mem.h><br />bool zap_streq(char const * lstr,char const * rstr);</code> <h4>Description</h4> <p>Checks the equality of the strings <i>lstr</i> and <i>rstr</i>.</p> <p>If one of the strings has a length different from the other, or if any character in the two strings is different from the other (at the same offset), true is returned. Otherwise, false is returned.</p> @@ -62,14 +102,14 @@ <br /> <h3>strfill</h3> <h4>Synopsis</h4> - <code>#include <zap/base.h><br />void zap_strfill(char * str,char chr);</code> + <code>#include <zap/mem.h><br />void zap_strfill(char * str,char chr);</code> <h4>Description</h4> <p>Writes the character <i>chr</i> to every valid position in the string <i>str</i>, excluding that of the null-terminator.</p> <p>If <i>str</i> is not a valid pointer to a null-terminated string, the behaviour is undefined.</p> <br /> <h3>strlen</h3> <h4>Synopsis</h4> - <code>#include <zap/base.h><br />size_t zap_strlen(char const * str);</code> + <code>#include <zap/mem.h><br />size_t zap_strlen(char const * str);</code> <h4>Description</h4> <p>Counts the number of characters in the string <i>str</i>.</p> <p>Returns the number of characters (excluding the null-terminator) in the string.</p> @@ -1,11 +1,21 @@ -/* c++ -Izap/include -L. -otest test.cc -lzap */ +/* c++ -Izap/include -Lzap -otest test.cc -lzap */ #include <cassert> #include <cinttypes> #include <cstddef> #include <cstdint> #include <cstdio> -#include <zap/base.h> +#include <stdexcept> +#include <zap/math.h> +#include <zap/mem.h> + +extern "C" auto zap_test_foreachfn(void * const _ptr) -> void { /* This function is passed to foreach, which requires C-linkage function pointers. I tried to overload the function to also accept C++-linkage function pointers, but that only made GCC moan. */ + auto const ptr {static_cast<int *>(_ptr)}; + auto val {*ptr}; + if (val == 0x45) {throw ::std::domain_error {"Damn!"};} + val %= 0x2; + *ptr = val; +} int main(void) { ::std::fprintf(stderr,"zap test\n"); @@ -13,16 +23,97 @@ int main(void) { ::std::fprintf(stderr,"fast: %s\n",::zap_fastimpl ? "yes" : "no"); ::std::fprintf(stderr,"\n"); { + { + auto val {::zap_abs_c(-0x5D)}; + ::std::fprintf(stderr,"val: %hhi\n",val); + assert(val == 0x5D); + } + { + auto val {::zap_abs_i(-0xEF4)}; + ::std::fprintf(stderr,"val: %i\n",val); + assert(val == 0xEF4); + } + { + auto val {::zap_abs_l(-0x6666E67B)}; + ::std::fprintf(stderr,"val: %li\n",val); + assert(val == 0x6666E67B); + } + { + auto val {::zap_abs_ll(-0x7C91A4B244F0DC99)}; + ::std::fprintf(stderr,"val: %lli\n",val); + assert(val == 0x7C91A4B244F0DC99); + } + { + auto val {::zap_abs_s(-0xDC9)}; + ::std::fprintf(stderr,"val: %i\n",val); + assert(val == 0xDC9); + } + } + ::std::fprintf(stderr,"\n"); + { + { /* Largest number for each signed parameter: (floor(cbrt(2^(x-1)-1))) */ + auto val {::zap_fma_c(0x5,0x2,0x2)}; + ::std::fprintf(stderr,"val: %hhi\n",val); + assert(val == 0x9); + } + { + auto val {::zap_fma_i(0x29,0x4AD,0x453)}; + ::std::fprintf(stderr,"val: %i\n",val); + assert(val == 0x143840); + } + { + auto val {::zap_fma_l(0x1BAA11,0x361DA,0x17462F)}; + ::std::fprintf(stderr,"val: %li\n",val); + assert(val == 0x4EB8123D17); + } + { + auto val {::zap_fma_ll(0x45,0x60,0x1A4)}; + ::std::fprintf(stderr,"val: %lli\n",val); + assert(val == 0x9DC5); + } + { + auto val {::zap_fma_s(0x7,0xE,0x1D)}; + ::std::fprintf(stderr,"val: %i\n",val); + assert(val == 0x19D); + } + { /* Largest number for each unsigned parameter: (floor(cbrt(2^x-1))) */ + auto val {::zap_fma_uc(0x6u,0x6u,0x3u)}; + ::std::fprintf(stderr,"val: %hhu\n",val); + assert(val == 0x18u); + } + { + auto val {::zap_fma_ui(0x14u,0x17u,0x3u)}; + ::std::fprintf(stderr,"val: %u\n",val); + assert(val == 0x59); + } + { + auto val {::zap_fma_ul(0x5AAu,0x412u,0x16Du)}; + ::std::fprintf(stderr,"val: %lu\n",val); + assert(val == 0x5D354u); + } + { + auto val {::zap_fma_ull(0x10EFC7u,0x19FB63u,0x1133259u)}; + ::std::fprintf(stderr,"val: %llu\n",val); + assert(val == 0x1BEE278BAB32u); + } + { + auto val {::zap_fma_us(0x23u,0x19u,0x1Cu)}; + ::std::fprintf(stderr,"val: %u\n",val); + assert(val == 0x2DF); + } + } + ::std::fprintf(stderr,"\n"); + { constexpr ::std::size_t arrsz {0x8u}; ::std::uint_least64_t arr0[arrsz] {0x0u}; ::zap_memfill(arr0,arrsz * sizeof (::std::uint_least64_t),0x0u); - ::std::fprintf(stderr,"arr0[0]: %" PRIX64 "\n",arr0[0x0u]); - ::std::fprintf(stderr,"arr0[1]: %" PRIX64 "\n",arr0[0x1u]); - ::std::fprintf(stderr,"arr0[2]: %" PRIX64 "\n",arr0[0x2u]); - ::std::fprintf(stderr,"arr0[3]: %" PRIX64 "\n",arr0[0x3u]); - ::std::fprintf(stderr,"arr0[4]: %" PRIX64 "\n",arr0[0x4u]); - ::std::fprintf(stderr,"arr0[5]: %" PRIX64 "\n",arr0[0x5u]); - ::std::fprintf(stderr,"arr0[6]: %" PRIX64 "\n",arr0[0x6u]); + ::std::fprintf(stderr,"arr0[0]: %" PRIXLEAST64 "\n",arr0[0x0u]); + ::std::fprintf(stderr,"arr0[1]: %" PRIXLEAST64 "\n",arr0[0x1u]); + ::std::fprintf(stderr,"arr0[2]: %" PRIXLEAST64 "\n",arr0[0x2u]); + ::std::fprintf(stderr,"arr0[3]: %" PRIXLEAST64 "\n",arr0[0x3u]); + ::std::fprintf(stderr,"arr0[4]: %" PRIXLEAST64 "\n",arr0[0x4u]); + ::std::fprintf(stderr,"arr0[5]: %" PRIXLEAST64 "\n",arr0[0x5u]); + ::std::fprintf(stderr,"arr0[6]: %" PRIXLEAST64 "\n",arr0[0x6u]); assert(arr0[0x0u] == 0x0u); assert(arr0[0x1u] == 0x0u); assert(arr0[0x2u] == 0x0u); @@ -31,13 +122,13 @@ int main(void) { assert(arr0[0x5u] == 0x0u); assert(arr0[0x6u] == 0x0u); ::zap_memfill(arr0,arrsz * sizeof (::std::uint_least64_t),0x7Fu); - ::std::fprintf(stderr,"arr0[0]: %" PRIX64 "\n",arr0[0x0u]); - ::std::fprintf(stderr,"arr0[1]: %" PRIX64 "\n",arr0[0x1u]); - ::std::fprintf(stderr,"arr0[2]: %" PRIX64 "\n",arr0[0x2u]); - ::std::fprintf(stderr,"arr0[3]: %" PRIX64 "\n",arr0[0x3u]); - ::std::fprintf(stderr,"arr0[4]: %" PRIX64 "\n",arr0[0x4u]); - ::std::fprintf(stderr,"arr0[5]: %" PRIX64 "\n",arr0[0x5u]); - ::std::fprintf(stderr,"arr0[6]: %" PRIX64 "\n",arr0[0x6u]); + ::std::fprintf(stderr,"arr0[0]: %" PRIXLEAST64 "\n",arr0[0x0u]); + ::std::fprintf(stderr,"arr0[1]: %" PRIXLEAST64 "\n",arr0[0x1u]); + ::std::fprintf(stderr,"arr0[2]: %" PRIXLEAST64 "\n",arr0[0x2u]); + ::std::fprintf(stderr,"arr0[3]: %" PRIXLEAST64 "\n",arr0[0x3u]); + ::std::fprintf(stderr,"arr0[4]: %" PRIXLEAST64 "\n",arr0[0x4u]); + ::std::fprintf(stderr,"arr0[5]: %" PRIXLEAST64 "\n",arr0[0x5u]); + ::std::fprintf(stderr,"arr0[6]: %" PRIXLEAST64 "\n",arr0[0x6u]); assert(arr0[0x0u] == 0x7F7F7F7F7F7F7F7Fu); assert(arr0[0x1u] == 0x7F7F7F7F7F7F7F7Fu); assert(arr0[0x2u] == 0x7F7F7F7F7F7F7F7Fu); @@ -47,13 +138,13 @@ int main(void) { assert(arr0[0x6u] == 0x7F7F7F7F7F7F7F7Fu); ::std::uint_least64_t arr1[arrsz] {0x0u}; ::zap_memcpy(arr0,arrsz * sizeof (::std::uint_least64_t),arr1); - ::std::fprintf(stderr,"arr1[0]: %" PRIX64 "\n",arr1[0x0u]); - ::std::fprintf(stderr,"arr1[1]: %" PRIX64 "\n",arr1[0x1u]); - ::std::fprintf(stderr,"arr1[2]: %" PRIX64 "\n",arr1[0x2u]); - ::std::fprintf(stderr,"arr1[3]: %" PRIX64 "\n",arr1[0x3u]); - ::std::fprintf(stderr,"arr1[4]: %" PRIX64 "\n",arr1[0x4u]); - ::std::fprintf(stderr,"arr1[5]: %" PRIX64 "\n",arr1[0x5u]); - ::std::fprintf(stderr,"arr1[6]: %" PRIX64 "\n",arr1[0x6u]); + ::std::fprintf(stderr,"arr1[0]: %" PRIXLEAST64 "\n",arr1[0x0u]); + ::std::fprintf(stderr,"arr1[1]: %" PRIXLEAST64 "\n",arr1[0x1u]); + ::std::fprintf(stderr,"arr1[2]: %" PRIXLEAST64 "\n",arr1[0x2u]); + ::std::fprintf(stderr,"arr1[3]: %" PRIXLEAST64 "\n",arr1[0x3u]); + ::std::fprintf(stderr,"arr1[4]: %" PRIXLEAST64 "\n",arr1[0x4u]); + ::std::fprintf(stderr,"arr1[5]: %" PRIXLEAST64 "\n",arr1[0x5u]); + ::std::fprintf(stderr,"arr1[6]: %" PRIXLEAST64 "\n",arr1[0x6u]); assert(arr1[0x0u] == arr0[0x0u]); assert(arr1[0x1u] == arr0[0x1u]); assert(arr1[0x2u] == arr0[0x2u]); @@ -80,7 +171,7 @@ int main(void) { auto len {::zap_strlen(str)}; ::std::fprintf(stderr,"len: %zX\n",len); ::std::size_t pos0 = ::zap_fndchr(str,' '); - ::std::size_t pos1 = ::zap_fndbyte(str,len,(::std::uint_least8_t)' '); + ::std::size_t pos1 = ::zap_fndbyte(str,len,(unsigned char)' '); ::std::fprintf(stderr,"pos0: %zX\n",pos0); ::std::fprintf(stderr,"pos1: %zX\n",pos1); assert(pos0 == 0x2u); @@ -88,7 +179,7 @@ int main(void) { str += pos0 + 0x1u; len = ::zap_strlen(str); pos0 = ::zap_fndchr(str,' '); - pos1 = ::zap_fndbyte(str,len,(::std::uint_least8_t)' '); + pos1 = ::zap_fndbyte(str,len,(unsigned char)' '); ::std::fprintf(stderr,"pos0: %zX\n",pos0); ::std::fprintf(stderr,"pos1: %zX\n",pos1); assert(pos0 == 0x2u); @@ -96,7 +187,7 @@ int main(void) { str += pos0 + 0x1u; len = ::zap_strlen(str); pos0 = ::zap_fndchr(str,' '); - pos1 = ::zap_fndbyte(str,len,(::std::uint_least8_t)' '); + pos1 = ::zap_fndbyte(str,len,(unsigned char)' '); ::std::fprintf(stderr,"pos0: %zX\n",pos0); ::std::fprintf(stderr,"pos1: %zX\n",pos1); assert(pos0 == SIZE_MAX); @@ -163,12 +254,8 @@ int main(void) { 0x2, 0x3, }; - ::zap_foreach(arr,sizeof (arr) / sizeof (int),sizeof (int),[](void * const _ptr) { - auto const ptr {static_cast<int *>(_ptr)}; - auto val {*ptr}; - val %= 0x2; - *ptr = val; - }); + void * rem {nullptr}; + ::zap_foreach(arr,sizeof (int),sizeof (arr) / sizeof (int),::zap_test_foreachfn); ::std::fprintf(stderr,"arr[0]: %i\n",arr[0x0u]); ::std::fprintf(stderr,"arr[1]: %i\n",arr[0x1u]); ::std::fprintf(stderr,"arr[2]: %i\n",arr[0x2u]); diff --git a/zap/Makefile b/zap/Makefile new file mode 100644 index 0000000..b7db3dc --- /dev/null +++ b/zap/Makefile @@ -0,0 +1,64 @@ +# 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-priv/zap/priv.h index 24718bb..8ebbd39 100644 --- a/zap/include-priv/zap/priv.h +++ b/zap/include-priv/zap/priv.h @@ -4,16 +4,15 @@ 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 +#if !defined(zap_priv_hdr_priv) +#define zap_priv_hdr_priv #include <zap/base.h> -#include <stddef.h> -#include <stdint.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 +#define zap_priv_fastimpl (0x1u) +#else +#define zap_priv_fastimpl (0x0u) #endif #endif diff --git a/zap/include/zap/base.h b/zap/include/zap/base.h index 4866051..a52414b 100644 --- a/zap/include/zap/base.h +++ b/zap/include/zap/base.h @@ -5,31 +5,12 @@ */ #include <stdbool.h> -#include <stddef.h> -#include <stdint.h> #include <susinfo.h> -#if !defined(zap_hdr_base) -#define zap_hdr_base +#if !defined(zap_priv_hdr_base) +#define zap_priv_hdr_base -#define zap_ver ((uint_Least64_t)0xEu) - -#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_strcmp -.extern zap_strcpy -.extern zap_streq -.extern zap_strfill -.extern zap_strlen - -#else +#define zap_ver (0xFu) #if defined(sus_lang_cxx) extern "C" { @@ -37,23 +18,6 @@ extern "C" { extern bool const zap_fastimpl; -/* Memory sequence functions: */ -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 sus_attr_nothrw 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); - -#endif #if defined(sus_lang_cxx) } #endif diff --git a/zap/include/zap/math.h b/zap/include/zap/math.h new file mode 100644 index 0000000..97afb66 --- /dev/null +++ b/zap/include/zap/math.h @@ -0,0 +1,94 @@ +/* + 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 new file mode 100644 index 0000000..20d7326 --- /dev/null +++ b/zap/include/zap/mem.h @@ -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/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 + +#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); + +#endif +#if defined(sus_lang_cxx) +} +#endif + +#endif diff --git a/zap/src/abs.c b/zap/src/abs.c new file mode 100644 index 0000000..8fe97e6 --- /dev/null +++ b/zap/src/abs.c @@ -0,0 +1,96 @@ +/* + 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 index 71ded00..2541a41 100644 --- a/zap/src/fastimpl.c +++ b/zap/src/fastimpl.c @@ -9,8 +9,4 @@ #include <stdbool.h> #include <stdint.h> -#if defined(zap_priv_fastimpl) -bool const zap_fastimpl = true; -#else -bool const zap_fastimpl = false; -#endif +bool const zap_fastimpl = zap_priv_fastimpl; diff --git a/zap/src/fma.c b/zap/src/fma.c new file mode 100644 index 0000000..b2f45ad --- /dev/null +++ b/zap/src/fma.c @@ -0,0 +1,171 @@ +/* + 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 index 3283eec..e6e6070 100644 --- a/zap/src/fndbyte.c +++ b/zap/src/fndbyte.c @@ -6,18 +6,20 @@ #include <zap/priv.h> +#include <zap/mem.h> + #include <stddef.h> #include <stdint.h> -#if defined(zap_priv_fastimpl) +#if zap_priv_fastimpl __asm__ ( ".globl zap_fndbyte\n" "zap_fndbyte:\n" /* - void const * ptr - size_t num - uint_least8_t byte + void const * pos + size_t num + unsigned char byte */ #if defined(sus_arch_amd64) /* rax: Address of the current element. */ @@ -68,10 +70,11 @@ __asm__ ( #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;}} +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 index 5cf78f8..fc4eb2b 100644 --- a/zap/src/fndchr.c +++ b/zap/src/fndchr.c @@ -6,10 +6,12 @@ #include <zap/priv.h> +#include <zap/mem.h> + #include <stddef.h> #include <stdint.h> -#if defined(zap_priv_fastimpl) +#if zap_priv_fastimpl __asm__ ( ".globl zap_fndchr\n" diff --git a/zap/src/foreach.c b/zap/src/foreach.c index 54911e9..5e281d4 100644 --- a/zap/src/foreach.c +++ b/zap/src/foreach.c @@ -6,11 +6,13 @@ #include <zap/priv.h> +#include <zap/mem.h> + #include <stddef.h> void zap_foreach(void * const _ptr,size_t const _sz,size_t const _num,void (* const _fn)(void *)) { - unsigned char * ptr = _ptr; - size_t const numbyte = _sz * _num; - void * const afterbuf = ptr + numbyte; - for (;ptr != afterbuf;ptr += _sz) {_fn(ptr);} + unsigned char * pos = _ptr; + size_t const numbyte = _sz * _num; + unsigned char * const afterbuf = pos + numbyte; + for (;pos != afterbuf;pos += _sz) {_fn(pos);} } diff --git a/zap/src/memcmp.c b/zap/src/memcmp.c index 31e5161..0fdf13a 100644 --- a/zap/src/memcmp.c +++ b/zap/src/memcmp.c @@ -6,16 +6,18 @@ #include <zap/priv.h> +#include <zap/mem.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 * 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 ? INT8_MIN : INT8_MAX;} + sus_likely (lbyte != rbyte) {return lbyte < rbyte ? INT_LEAST8_MIN : INT_LEAST8_MAX;} } return 0x0; } diff --git a/zap/src/memcpy.c b/zap/src/memcpy.c index 8fa98ae..ae923c3 100644 --- a/zap/src/memcpy.c +++ b/zap/src/memcpy.c @@ -6,10 +6,12 @@ #include <zap/priv.h> +#include <zap/mem.h> + #include <stddef.h> #include <stdint.h> -#if defined(zap_priv_fastimpl) +#if zap_priv_fastimpl __asm__ ( ".globl zap_memcpy\n" @@ -133,9 +135,9 @@ __asm__ ( ); #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; + 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 index 3670eb3..9b56314 100644 --- a/zap/src/memdup.c +++ b/zap/src/memdup.c @@ -6,6 +6,8 @@ #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) { diff --git a/zap/src/memeq.c b/zap/src/memeq.c index 75ecc12..7dce213 100644 --- a/zap/src/memeq.c +++ b/zap/src/memeq.c @@ -6,11 +6,13 @@ #include <zap/priv.h> +#include <zap/mem.h> + #include <stdbool.h> #include <stddef.h> #include <stdint.h> -#if defined(zap_priv_fastimpl) +#if zap_priv_fastimpl __asm__ ( ".globl zap_memeq\n" @@ -101,9 +103,9 @@ __asm__ ( ); #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; + 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; } diff --git a/zap/src/memfill.c b/zap/src/memfill.c index c9a9797..1aebd29 100644 --- a/zap/src/memfill.c +++ b/zap/src/memfill.c @@ -6,18 +6,20 @@ #include <zap/priv.h> +#include <zap/mem.h> + #include <stddef.h> #include <stdint.h> -#if defined(zap_priv_fastimpl) +#if zap_priv_fastimpl __asm__ ( ".globl zap_memfill\n" "zap_memfill:\n" /* - void const * ptr - size_t num - uint_least8_t val + void const * ptr + size_t num + unsigned char val */ #if defined(sus_arch_amd64) /* rdi: Address of the current element. */ @@ -50,9 +52,9 @@ __asm__ ( #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; +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/strcmp.c b/zap/src/strcmp.c index 101f7dc..0ed0a59 100644 --- a/zap/src/strcmp.c +++ b/zap/src/strcmp.c @@ -6,6 +6,8 @@ #include <zap/priv.h> +#include <zap/mem.h> + #include <stdint.h> int_least8_t zap_strcmp(char const * const _lstr,char const * const _rstr) { @@ -14,7 +16,7 @@ int_least8_t zap_strcmp(char const * const _lstr,char const * const _rstr) { for (;;++lpos,++rpos) { unsigned char const lchr = *lpos; unsigned char const rchr = *rpos; - sus_likely (lchr != rchr) {return lchr < rchr ? INT8_MIN : INT8_MAX;} + sus_likely (lchr != rchr) {return lchr < rchr ? INT_LEAST8_MIN : INT_LEAST8_MAX;} sus_unlikely (lchr == (unsigned char)0x0) {return 0x0;} } sus_unreach(); diff --git a/zap/src/strcpy.c b/zap/src/strcpy.c index 943cb2c..616af7f 100644 --- a/zap/src/strcpy.c +++ b/zap/src/strcpy.c @@ -6,9 +6,11 @@ #include <zap/priv.h> +#include <zap/mem.h> + #include <stddef.h> -#if defined(zap_priv_fastimpl) +#if zap_priv_fastimpl __asm__ ( ".globl zap_strcpy\n" @@ -62,7 +64,7 @@ size_t zap_strcpy(char const * const _in,char * const _out) { for (;;++inpos,++outpos) { char const chr = *inpos; *outpos = chr; - if (chr == '\x0') {return (size_t)(inpos - _in);} + if (chr == '\x0') {return inpos - _in;} } sus_unreach(); } diff --git a/zap/src/strdup.c b/zap/src/strdup.c index a7ab6e6..183a909 100644 --- a/zap/src/strdup.c +++ b/zap/src/strdup.c @@ -6,6 +6,8 @@ #include <zap/priv.h> +#include <zap/mem.h> + #include <stdlib.h> char * zap_strdup(sus_attr_unused char const * const _str) { diff --git a/zap/src/streq.c b/zap/src/streq.c index 9221cec..1ff4420 100644 --- a/zap/src/streq.c +++ b/zap/src/streq.c @@ -6,10 +6,12 @@ #include <zap/priv.h> +#include <zap/mem.h> + #include <stdbool.h> #include <stdint.h> -#if defined(zap_priv_fastimpl) +#if zap_priv_fastimpl __asm__ ( ".globl zap_streq\n" diff --git a/zap/src/strfill.c b/zap/src/strfill.c index a113094..bd0af33 100644 --- a/zap/src/strfill.c +++ b/zap/src/strfill.c @@ -6,6 +6,8 @@ #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),(uint_least8_t)_chr);} +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 index eab12e6..84b7d28 100644 --- a/zap/src/strlen.c +++ b/zap/src/strlen.c @@ -6,9 +6,11 @@ #include <zap/priv.h> +#include <zap/mem.h> + #include <stddef.h> -#if defined(zap_priv_fastimpl) +#if zap_priv_fastimpl __asm__ ( ".globl zap_strlen\n" |