diff options
70 files changed, 2261 insertions, 1792 deletions
@@ -1,3 +1,3 @@ *.a *.o -/test +/test/test diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 6c1910f..83ace3c 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,141 +1,167 @@ -| 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; - -| D - -- Add function foreach: Run function on each element; -- Use directive globl instead of global in assembly; -- Use SIZE_MAX instead of negative one; -- Remove asflags from makefile; -- Don't require GNU Make; -- Change the type of fndbyte: (size_t (void const *,size_t,uint_least8_t)) => (size_t (void const *,size_t,unsigned char)); -- Change the type of memfill: (void (void *,size_t,uint_least8_t)) => (void (void *,size_t,unsigned char)); -- Update readme (add documentation for some functions); -- Update susinfo symbol names; - -| C - -- Fix install target; -- Remove type literals; - -| B - -- memdup: Use sus_unlikely instead of __builtin_expect; -- Rename project to zap (from rgo); -- Remove global license file (useless with MPL); -- Migrate test to C++ (for reasons which will be revealed later); -- Restructure headers; -- Add include guards to the private header; -- Add attribute useret to functions; -- Require GNU Make; -- Compile position independent code; -- Update readme; - -| A - -- Installation script: Create installation directories if they don't already exist; -- Don't use susinfo types; -- Remove declarations for getbinver; -- Add memcmp, strcmp; -- Update makefile; -- Reimplement fastimpl as a global variable; -- Change type of fastimpl (uint_least8_t => _Bool); -- Change the return types of memeq and streq (uint_least8_t => _Bool); -- Enable compilation warnings; -- Add type literals (like those from susinfo); -- Use *int_leastN_t instead of *intN_t; -- Remove restrict-qualifications; -- Remove C++ version of memdup; - -| 9 - -- Fix readme not reflecting that we now support all platforms; -- Rename the 'Building' section in the readme to 'Building & Installing'; - -| 8 - -- Use susinfo; -- Implement algorithms in C (with inline assembly on supported platforms); -- Add comments; -- Fix strcpy counting the null-terminator; -- Fix strcpy taking a pointer-to-const as the output; -- Implement strcpy, streq in IA-32; -- Optimise streq: Only use the lower eight bytes for the return value; -- Optimise strlen: Use fewer registers; -- Fix memfill taking a pointer-to-const as the output; -- Fix strfill taking a pointer-to-const as the output; -- Update readme; -- Add private header; -- Remove assembly-specific version macro; - -| 7 - -- Relicense under MPL2; -- Instead of throwing an error, define a macro when the header is included on an unsupported platform; - -| 6 - -- Remove stupid debug return from memcpy; - -| 5 - -- Fix compile flags not indicating new relative header location; - -| 4 - -- Add install target to makefile; -- Merge makefiles; - -| 3 - -- Enable compiler optimisations; -- Optimise memfill; -- Optimise memcpy: Use movdqu instead of movups (AMD64, i386 SSE2), add 256-bit copy (AMD64 AVX, i386 AVX); -- Update makefile; -- Implement fndbyte, fndchr, strlen in IA-32; -- Fix bug in test; -- Update readme; -- Add new planned architectures: Motorola 68000, Power ISA, RISC-V, Sparc; - -| 2 - -- Fix target purge in makefile not being labeled phony; -- Add machien architecture check in header; -- Implement memcpy, memeq, memfill in IA-32; -- Fix some incorrect comments; -- Use a different register order for temporaries and optimise register usage; -- Fix bug in memeq: Should jump if zero, not if equal; -- Update readme; - -| 1 - -- Fix indentation in license notices; -- Fix incorrect declaration for rgo_strcpy, rgo_streq; -- Implement fndbyte,memeq,strcpy,streq; -- Add new tests; -- Fix bug in memcpy: Should jump if zero, not if equal; -- Remove declaration for rgo_memcmp; -- Add macro rgo_ver, defined to the current version number; -- Add assembly declaration for rgo_fndchr, rgo_fndbyte; -- Fix some incorrect comments; -- Use movups instead of movdqu in memcpy; - -| 0 - -- Initial. +# 10.0 + +* Update readme; +* Fix typo in makefile; +* Include headers inside header guard; +* Remove unneeded includes; +* Rename private include directory: 'include-priv' => 'include-private'; +* Remove assembly support from (public) headers; +* Remove fastimpl (assembly algorithms are still used); +* Add copyright/license notices to makefiles; +* Seperate sources according to header; +* Require GNU Make; +* Move (most) C-implementations into a seperate project: zapx; +* Restructure assembly; +* Implement strfill in assembly; +* Use new versioning system (api.ver); +* Remove documentation; +* Add features from latest standard; +* Temporarily remove i386 implementations; +* Update readme format; +* Update changelog format; +* Remove impl; +* Remove stdver; +* Readd ver; +* Use git tagging; + +# 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; + +# D + +* Add function foreach: Run function on each element; +* Use directive globl instead of global in assembly; +* Use SIZE_MAX instead of negative one; +* Remove asflags from makefile; +* Don't require GNU Make; +* Change the type of fndbyte: (size_t (void const *,size_t,uint_least8_t)) => (size_t (void const *,size_t,unsigned char)); +* Change the type of memfill: (void (void *,size_t,uint_least8_t)) => (void (void *,size_t,unsigned char)); +* Update readme (add documentation for some functions); +* Update susinfo symbol names; + +# C + +* Fix install target; +* Remove type literals; + +# B + +* memdup: Use sus_unlikely instead of __builtin_expect; +* Rename project to zap (from rgo); +* Remove global license file (useless with MPL); +* Migrate test to C++ (for reasons which will be revealed later); +* Restructure headers; +* Add include guards to the private header; +* Add attribute useret to functions; +* Require GNU Make; +* Compile position independent code; +* Update readme; + +# A + +* Installation script: Create installation directories if they don't already exist; +* Don't use susinfo types; +* Remove declarations for getbinver; +* Add memcmp, strcmp; +* Update makefile; +* Reimplement fastimpl as a global variable; +* Change type of fastimpl (uint_least8_t => _Bool); +* Change the return types of memeq and streq (uint_least8_t => _Bool); +* Enable compilation warnings; +* Add type literals (like those from susinfo); +* Use *int_leastN_t instead of *intN_t; +* Remove restrict-qualifications; +* Remove C++ version of memdup; + +# 9 + +* Fix readme not reflecting that we now support all platforms; +* Rename the 'Building' section in the readme to 'Building & Installing'; + +# 8 + +* Use susinfo; +* Implement algorithms in C (with inline assembly on supported platforms); +* Add comments; +* Fix strcpy counting the null-terminator; +* Fix strcpy taking a pointer-to-const as the output; +* Implement strcpy, streq in IA-32; +* Optimise streq: Only use the lower eight bytes for the return value; +* Optimise strlen: Use fewer registers; +* Fix memfill taking a pointer-to-const as the output; +* Fix strfill taking a pointer-to-const as the output; +* Update readme; +* Add private header; +* Remove assembly-specific version macro; + +# 7 + +* Relicense under MPL2; +* Instead of throwing an error, define a macro when the header is included on an unsupported platform; + +# 6 + +* Remove stupid debug return from memcpy; + +# 5 + +* Fix compile flags not indicating new relative header location; + +# 4 + +* Add install target to makefile; +* Merge makefiles; + +# 3 + +* Enable compiler optimisations; +* Optimise memfill; +* Optimise memcpy: Use movdqu instead of movups (AMD64, i386 SSE2), add 256-bit copy (AMD64 AVX, i386 AVX); +* Update makefile; +* Implement fndbyte, fndchr, strlen in IA-32; +* Fix bug in test; +* Update readme; +* Add new planned architectures: Motorola 68000, Power ISA, RISC-V, Sparc; + +# 2 + +* Fix target purge in makefile not being labeled phony; +* Add machien architecture check in header; +* Implement memcpy, memeq, memfill in IA-32; +* Fix some incorrect comments; +* Use a different register order for temporaries and optimise register usage; +* Fix bug in memeq: Should jump if zero, not if equal; +* Update readme; + +# 1 + +* Fix indentation in license notices; +* Fix incorrect declaration for rgo_strcpy, rgo_streq; +* Implement fndbyte,memeq,strcpy,streq; +* Add new tests; +* Fix bug in memcpy: Should jump if zero, not if equal; +* Remove declaration for rgo_memcmp; +* Add macro rgo_ver, defined to the current version number; +* Add assembly declaration for rgo_fndchr, rgo_fndbyte; +* Fix some incorrect comments; +* Use movups instead of movdqu in memcpy; + +# 0 + +* Initial. diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 0000000..36105b5 --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,22 @@ +# Copyright 2022 Gabriel Jensen. +# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. + +LIBZAP = zap/libzap.a + +.PHONY: clean install purge + +$(LIBZAP): + $(MAKE) -Czap + +install: $(LIBZAP) + mkdir -pm755 "$(HDRDIR)/zap" + mkdir -pm755 "$(LIBDIR)" + install -m644 "zap/include/zap/"*".h" "$(HDRDIR)/zap" + install -m755 "$(LIBZAP)" "$(LIBDIR)" + +clean: + $(MAKE) -Czap clean + +purge: + $(MAKE) -Czap purge diff --git a/Makefile b/Makefile deleted file mode 100644 index f4d59b1..0000000 --- a/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -LIBZAP = zap/libzap.a - -.PHONY: clean install purge zap - -zap: - $(MAKE) -Czap - -install: zap - mkdir -pm755 $(HDRDIR)/zap - mkdir -pm755 $(LIBDIR) - install -Dm644 zap/include/zap/base.h $(HDRDIR)/zap - install -Dm644 zap/include/zap/math.h $(HDRDIR)/zap - install -Dm644 zap/include/zap/mem.h $(HDRDIR)/zap - install -Dm755 $(LIBZAP) $(LIBDIR) - -clean: - $(MAKE) -Czap clean - -purge: - $(MAKE) -Czap purge diff --git a/README.html b/README.html deleted file mode 100644 index 1a08610..0000000 --- a/README.html +++ /dev/null @@ -1,117 +0,0 @@ -<!DOCTYPE html> -<html> - <h1>zap</h1> - <p>A library for algorithmics.</p> - <p><i>Note: This library is still in it's early stages and is NOT anywhere near being fully optimised.</i></p> - <br /> - <h2>Building and installation</h2> - <p>The provided makefile has been tested to work with both GNU Make and BSD Make.</p> - <p>The default target builds the static library file (located at <i>zap/libzap.a</i>). The target <i>clean</i> removes object files, whilst <i>purge</i> removes object files and the static library file.</p> - <p>Currently, zap doesn't support being compiled as a shared library out of the box, but the makefile could be modified to allow this.</p> - <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/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> - <br /> - <h3>fndchr</h3> - <h4>Synopsis</h4> - <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 <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/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 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 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/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/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/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> - <p>If <i>lstr</i> or <i>rstr</i> (or both) are not valid pointers to null-terminated strings, the behaviour is undefined.</p> - <br /> - <h3>strfill</h3> - <h4>Synopsis</h4> - <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/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> - <p>If <i>str</i> is not a valid pointer to a null-terminated string, the behaviour is undefined.</p> -</html>
\ No newline at end of file diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..80614de --- /dev/null +++ b/README.txt @@ -0,0 +1,10 @@ +ZAP + +This repository contains the standard paper (stdzap), the official, "optimised" implementation (zap), and the official reference implementation (zapx). + +# Building and installation + +zap uses GNU Make for building: +The default target builds the static library file (located at 'zap/libzapq.a'). The target 'clean' removes object files, whilst 'purge' removes all artefacts. +Currently, zap doesn't support being compiled as a shared library out of the box, but the makefile could be modified to allow this. +The 'install' target installs the headers to '$(HDRDIR)' and the library file to '$(LIBDIR)'. Both values need to be set when invoking the makefile (like via `make HDRDIR=/usr/include LIBDIR=/usr/lib`), or by modifying the makefiles directly. diff --git a/test.cc b/test.cc deleted file mode 100644 index 521d556..0000000 --- a/test.cc +++ /dev/null @@ -1,270 +0,0 @@ -/* c++ -Izap/include -Lzap -otest test.cc -lzap */ - -#include <cassert> -#include <cinttypes> -#include <cstddef> -#include <cstdint> -#include <cstdio> -#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"); - ::std::fprintf(stderr,"arch: %s\n",sus_archstr); - ::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]: %" 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); - assert(arr0[0x3u] == 0x0u); - assert(arr0[0x4u] == 0x0u); - assert(arr0[0x5u] == 0x0u); - assert(arr0[0x6u] == 0x0u); - ::zap_memfill(arr0,arrsz * sizeof (::std::uint_least64_t),0x7Fu); - ::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); - assert(arr0[0x3u] == 0x7F7F7F7F7F7F7F7Fu); - assert(arr0[0x4u] == 0x7F7F7F7F7F7F7F7Fu); - assert(arr0[0x5u] == 0x7F7F7F7F7F7F7F7Fu); - 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]: %" 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]); - assert(arr1[0x3u] == arr0[0x3u]); - assert(arr1[0x4u] == arr0[0x4u]); - assert(arr1[0x5u] == arr0[0x5u]); - assert(arr1[0x6u] == arr0[0x6u]); - auto const eq {::zap_memeq(arr1,arrsz,arr0)}; - ::std::fprintf(stderr,"eq: %u\n",eq); - assert(eq); - } - ::std::fprintf(stderr,"\n"); - { - auto const str {"Hello there! General Kenobi?"}; - ::std::fprintf(stderr,"str: \"%s\"\n",str); - auto const strsz {::zap_strlen(str)}; - ::std::fprintf(stderr,"strsz: %zX\n",strsz); - assert(strsz == 0x1Cu); - } - ::std::fprintf(stderr,"\n"); - { - auto str {"Oh my science!"}; - ::std::fprintf(stderr,"str: \"%s\"\n",str); - 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,(unsigned char)' '); - ::std::fprintf(stderr,"pos0: %zX\n",pos0); - ::std::fprintf(stderr,"pos1: %zX\n",pos1); - assert(pos0 == 0x2u); - assert(pos1 == pos0); - str += pos0 + 0x1u; - len = ::zap_strlen(str); - pos0 = ::zap_fndchr(str,' '); - pos1 = ::zap_fndbyte(str,len,(unsigned char)' '); - ::std::fprintf(stderr,"pos0: %zX\n",pos0); - ::std::fprintf(stderr,"pos1: %zX\n",pos1); - assert(pos0 == 0x2u); - assert(pos1 == pos0); - str += pos0 + 0x1u; - len = ::zap_strlen(str); - pos0 = ::zap_fndchr(str,' '); - 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); - assert(pos1 == pos0); - } - ::std::fprintf(stderr,"\n"); - { - char const str0[] = "What's up, my guy?"; - ::std::fprintf(stderr,"str0: \"%s\"\n",str0); - char const str1[] = "What's up, my guy?"; - ::std::fprintf(stderr,"str1: \"%s\"\n",str1); - char const str2[] = "I don't know you!"; - ::std::fprintf(stderr,"str2: \"%s\"\n",str2); - bool const cmp0 = ::zap_streq(str0,str1); - bool const cmp1 = ::zap_streq(str0,str2); - bool const cmp2 = ::zap_streq(str1,str2); - ::std::fprintf(stderr,"cmp0: %u\n",cmp0); - ::std::fprintf(stderr,"cmp1: %u\n",cmp1); - ::std::fprintf(stderr,"cmp2: %u\n",cmp2); - assert(cmp0); - assert(!cmp1); - assert(!cmp2); - } - ::std::fprintf(stderr,"\n"); - { - char const str0[] = "What in the world are you doing?"; - ::std::fprintf(stderr,"str0: \"%s\"\n",str0); - char str1[sizeof (str0)]; - assert(::zap_strcpy(str0,str1) == 0x20u); - ::std::fprintf(stderr,"str1: \"%s\"\n",str1); - assert(::zap_streq(str0,str1)); - } - ::std::fprintf(stderr,"\n"); - { - char const str0[] {"Oej Moej Goejd"}; - char const str1[] {"Er jeg egentlig okay med AWP?"}; - ::std::fprintf(stderr,"str0: \"%s\"\n",str0); - ::std::fprintf(stderr,"str1: \"%s\"\n",str1); - auto const cmp0 {::zap_strcmp(str0,str1)}; - auto const cmp1 {::zap_strcmp(str0,str0)}; - auto const cmp2 {::zap_strcmp(str1,str0)}; - auto const leastsz {sizeof (str0) < sizeof (str1) ? sizeof (str0) : sizeof (str1)}; - auto const cmp3 {::zap_memcmp(str0,leastsz,str1)}; - auto const cmp4 {::zap_memcmp(str0,leastsz,str0)}; - auto const cmp5 {::zap_memcmp(str1,leastsz,str0)}; - ::std::fprintf(stderr,"cmp0: %i\n",cmp0); - ::std::fprintf(stderr,"cmp1: %i\n",cmp1); - ::std::fprintf(stderr,"cmp2: %i\n",cmp2); - ::std::fprintf(stderr,"cmp3: %i\n",cmp3); - ::std::fprintf(stderr,"cmp4: %i\n",cmp4); - ::std::fprintf(stderr,"cmp5: %i\n",cmp5); - assert(cmp0 > 0x0); - assert(cmp1 == 0x0); - assert(cmp2 < 0x0); - assert(cmp3 > 0x0); - assert(cmp4 == 0x0); - assert(cmp5 < 0x0); - } - ::std::fprintf(stderr,"\n"); - { - int arr[] { - 0x0, - 0x1, - 0x2, - 0x3, - }; - 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]); - ::std::fprintf(stderr,"arr[3]: %i\n",arr[0x3u]); - assert(arr[0x0u] == 0x0); - assert(arr[0x1u] == 0x1); - assert(arr[0x2u] == 0x0); - assert(arr[0x3u] == 0x1); - } - ::std::fprintf(stderr,"\n"); - ::std::fprintf(stderr,"All tests have passed!\n"); -} diff --git a/test/src/main.c b/test/src/main.c new file mode 100644 index 0000000..79bf0ce --- /dev/null +++ b/test/src/main.c @@ -0,0 +1,106 @@ +#include <inttypes.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <zap/mem.h> + +#define zaptest_log(_expr,_typ,_fmtspec) (fprintf(stderr,"(" #_expr "): " _fmtspec "\n\n",(_typ)(_expr))); + +#define zaptest_chk(_lexpr,_rexpr,_typ,_fmtspec) { \ + fprintf(stderr,"(" #_lexpr "): " _fmtspec "\n",(_typ)(_lexpr)); \ + fprintf(stderr,"(" #_rexpr "): " _fmtspec "\n\n",(_typ)(_rexpr)); \ + if ((_typ)(_lexpr) != (_typ)(_rexpr)) { \ + fprintf(stderr,"Mismatch!\n"); \ + return true; \ + } \ +} + +typedef bool (* zaptest_testtyp)(void); + +#include "test/bool.i" +#include "test/cmp.i" +#include "test/fndbyte.i" +#include "test/fndchr.i" +#include "test/foreach.i" +#include "test/memcat.i" +#include "test/memcmp.i" +#include "test/memcp.i" +#include "test/memeq.i" +#include "test/memfill.i" +#include "test/memgen.i" +#include "test/nullptr.i" +#include "test/strcat.i" +#include "test/strcp.i" +#include "test/streq.i" +#include "test/strfill.i" +#include "test/strlen.i" +#include "test/utf8dec.i" +#include "test/utf8enc.i" +#include "test/win1252dec.i" +#include "test/win1252enc.i" + +static zaptest_testtyp zaptest_tests[] = { + zaptest_test_bool, + zaptest_test_cmp, + zaptest_test_fndbyte, + zaptest_test_fndchr, + zaptest_test_foreach, + zaptest_test_memcat, + zaptest_test_memcmp, + zaptest_test_memcp, + zaptest_test_memeq, + zaptest_test_memfill, + zaptest_test_memgen, + zaptest_test_nullptr, + zaptest_test_strcat, + zaptest_test_strcp, + zaptest_test_streq, + zaptest_test_strfill, + zaptest_test_strlen, + zaptest_test_utf8dec, + zaptest_test_utf8enc, + zaptest_test_win1252dec, + zaptest_test_win1252enc, +}; + +static char const * zaptest_testnms[] = { + "bool", + "cmp", + "fndbyte", + "fndchr", + "foreach", + "memcat", + "memcmp", + "memcp", + "memeq", + "memfill", + "memgen", + "nullptr", + "strcat", + "strcp", + "streq", + "strfill", + "strlen", + "utf8dec", + "utf8enc", + "win1252dec", + "win1252enc", +}; + +static void zaptest_dotest(zap_sz const _n) { + fprintf(stderr,":: \x1B[94mTesting\x1B[0m %s...\n\n",zaptest_testnms[_n]); + if (zaptest_tests[_n]()) { + fprintf(stderr,":: \x1B[91mError\x1B[0m in %s! Aborting...\n\n",zaptest_testnms[_n]); + exit(EXIT_FAILURE); + } + fprintf(stderr,":: \x1B[92mSuccess\x1B[0m with %s!\n\n",zaptest_testnms[_n]); +} + +int main(void) { + fprintf(stderr,"Zap Test\n\n"); + fprintf(stderr,"Version: %lX\n",zap_ver); + fprintf(stderr,"\n"); + zaptest_log(zap_nopos,zap_sz,"%zX") + zaptest_log((void *)zap_nullptr,uintptr_t,"%" PRIXPTR) + for (zap_sz n = 0x0u;n < sizeof (zaptest_tests) / sizeof (zaptest_tests[0x0u]);++n) {zaptest_dotest(n);} +} diff --git a/test/src/test/bool.i b/test/src/test/bool.i new file mode 100644 index 0000000..adacf85 --- /dev/null +++ b/test/src/test/bool.i @@ -0,0 +1,9 @@ +#include <inttypes.h> +#include <stdbool.h> + +static bool zaptest_test_bool(void) { + zaptest_log(zap_true,uintmax_t,"%" PRIXMAX) + zaptest_chk(zap_false,0x0u,unsigned char,"%hhX") + zaptest_chk(zap_true > zap_false,0x1u,unsigned char,"%hhX") + return false; +} diff --git a/test/src/test/cmp.i b/test/src/test/cmp.i new file mode 100644 index 0000000..fbb7d5c --- /dev/null +++ b/test/src/test/cmp.i @@ -0,0 +1,11 @@ +#include <inttypes.h> +#include <stdbool.h> + +static bool zaptest_test_cmp(void) { + zaptest_log(zap_lt,intmax_t,"%" PRIiMAX) + zaptest_log(zap_gt,intmax_t,"%" PRIiMAX) + zaptest_chk(zap_eq,0x0u,signed char,"%hhi") + zaptest_chk(zap_lt < zap_eq,0x1u,unsigned char,"%hhX") + zaptest_chk(zap_gt > zap_eq,0x1u,unsigned char,"%hhX") + return false; +} diff --git a/test/src/test/fndbyte.i b/test/src/test/fndbyte.i new file mode 100644 index 0000000..56231ac --- /dev/null +++ b/test/src/test/fndbyte.i @@ -0,0 +1,33 @@ +#include <stdbool.h> + +static bool zaptest_test_fndbyte(void) { + unsigned char const arr[] = { + 0x1u, + 0x3u, + 0x7u, + 0xFu, + 0x1Fu, + 0x3Fu, + 0x7Fu, + 0xFFu, + }; + zap_sz pos = zap_fndbyte(arr,sizeof (arr),0x1u); + zaptest_chk(pos,0x0u,zap_sz,"%zX"); + pos = zap_fndbyte(arr,sizeof (arr),0x3u); + zaptest_chk(pos,0x1u,zap_sz,"%zX"); + pos = zap_fndbyte(arr,sizeof (arr),0x7u); + zaptest_chk(pos,0x2u,zap_sz,"%zX"); + pos = zap_fndbyte(arr,sizeof (arr),0xFu); + zaptest_chk(pos,0x3u,zap_sz,"%zX"); + pos = zap_fndbyte(arr,sizeof (arr),0x1Fu); + zaptest_chk(pos,0x4u,zap_sz,"%zX"); + pos = zap_fndbyte(arr,sizeof (arr),0x3Fu); + zaptest_chk(pos,0x5u,zap_sz,"%zX"); + pos = zap_fndbyte(arr,sizeof (arr),0x7Fu); + zaptest_chk(pos,0x6u,zap_sz,"%zX"); + pos = zap_fndbyte(arr,sizeof (arr),0xFFu); + zaptest_chk(pos,0x7u,zap_sz,"%zX"); + pos = zap_fndbyte(arr,sizeof (arr),0xFEu); + zaptest_chk(pos,zap_nopos,zap_sz,"%zX"); + return false; +} diff --git a/test/src/test/fndchr.i b/test/src/test/fndchr.i new file mode 100644 index 0000000..8fb670a --- /dev/null +++ b/test/src/test/fndchr.i @@ -0,0 +1,12 @@ +#include <stdbool.h> + +static bool zaptest_test_fndchr(void) { + char const str[] = "What the drake doing?"; + zap_sz pos = zap_fndchr(str,'?'); + zaptest_chk(pos,0x14u,zap_sz,"%zX"); + pos = zap_fndchr(str,'t'); + zaptest_chk(pos,0x3u,zap_sz,"%zX"); + pos = zap_fndchr(str,'!'); + zaptest_chk(pos,zap_nopos,zap_sz,"%zX"); + return false; +} diff --git a/test/src/test/foreach.i b/test/src/test/foreach.i new file mode 100644 index 0000000..e7b933d --- /dev/null +++ b/test/src/test/foreach.i @@ -0,0 +1,23 @@ +#include <stdbool.h> + +static void foreachfn(void * const _ptr) { + unsigned int * ptr = _ptr; + unsigned int val = *ptr; + val %= 0x2; + *ptr = val; +} + +static bool zaptest_test_foreach(void) { + unsigned int arr[] = { + 0x0u, + 0x1u, + 0x2u, + 0x3u, + }; + zap_foreach(arr,sizeof (arr[0x0u]),sizeof (arr) / sizeof (arr[0x0u]),foreachfn); + zaptest_chk(arr[0x0u],0x0u,unsigned int,"%X"); + zaptest_chk(arr[0x1u],0x1u,unsigned int,"%X"); + zaptest_chk(arr[0x2u],0x0u,unsigned int,"%X"); + zaptest_chk(arr[0x3u],0x1u,unsigned int,"%X"); + return false; +} diff --git a/test/src/test/memcat.i b/test/src/test/memcat.i new file mode 100644 index 0000000..f16faef --- /dev/null +++ b/test/src/test/memcat.i @@ -0,0 +1,43 @@ +#include <stdbool.h> + +static bool zaptest_test_memcat(void) { + unsigned short const arr0[] = { + 0x1u, + 0x3u, + 0x7u, + 0xFu, + 0x1Fu, + 0x3Fu, + 0x7Fu, + 0xFFu, + }; + unsigned short const arr1[] = { + 0x1FFu, + 0x3FFu, + 0x7FFu, + 0xFFFu, + 0x1FFFu, + 0x3FFFu, + 0x7FFFu, + 0xFFFFu, + }; + unsigned short buf[(sizeof (arr0) + sizeof (arr1)) / sizeof (arr0[0x0u])]; + zap_memcat(arr0,sizeof (arr0),arr1,sizeof (arr1),buf); + zaptest_chk(buf[0x0u],0x1u, unsigned int,"%X"); + zaptest_chk(buf[0x1u],0x3u, unsigned int,"%X"); + zaptest_chk(buf[0x2u],0x7u, unsigned int,"%X"); + zaptest_chk(buf[0x3u],0xFu, unsigned int,"%X"); + zaptest_chk(buf[0x4u],0x1F, unsigned int,"%X"); + zaptest_chk(buf[0x5u],0x3Fu, unsigned int,"%X"); + zaptest_chk(buf[0x6u],0x7Fu, unsigned int,"%X"); + zaptest_chk(buf[0x7u],0xFFu, unsigned int,"%X"); + zaptest_chk(buf[0x8u],0x1FFu, unsigned int,"%X"); + zaptest_chk(buf[0x9u],0x3FFu, unsigned int,"%X"); + zaptest_chk(buf[0xAu],0x7FFu, unsigned int,"%X"); + zaptest_chk(buf[0xBu],0xFFFu, unsigned int,"%X"); + zaptest_chk(buf[0xCu],0x1FFFu,unsigned int,"%X"); + zaptest_chk(buf[0xDu],0x3FFFu,unsigned int,"%X"); + zaptest_chk(buf[0xEu],0x7FFFu,unsigned int,"%X"); + zaptest_chk(buf[0xFu],0xFFFFu,unsigned int,"%X"); + return false; +} diff --git a/test/src/test/memcmp.i b/test/src/test/memcmp.i new file mode 100644 index 0000000..d54a062 --- /dev/null +++ b/test/src/test/memcmp.i @@ -0,0 +1,26 @@ +#include <stdbool.h> + +static bool zaptest_test_memcmp(void) { + unsigned char const arr0[] = { + 0x7Fu, + 0x3Fu, + 0xFFu, + }; + unsigned char const arr1[] = { + 0x7Fu, + 0x3Fu, + 0x1Fu, + }; + unsigned char const arr2[] = { + 0x7Fu, + 0x3Fu, + 0xFFu, + }; + zap_cmp cmp = zap_memcmp(arr0,sizeof (arr0),arr1); + zaptest_chk(cmp,zap_gt,signed char,"%hhi") + cmp = zap_memcmp(arr1,sizeof (arr1),arr0); + zaptest_chk(cmp,zap_lt,signed char,"%hhi") + cmp = zap_memcmp(arr0,sizeof (arr0),arr2); + zaptest_chk(cmp,zap_eq,signed char,"%hhi") + return false; +} diff --git a/test/src/test/memcp.i b/test/src/test/memcp.i new file mode 100644 index 0000000..4cfc17c --- /dev/null +++ b/test/src/test/memcp.i @@ -0,0 +1,18 @@ +#include <inttypes.h> +#include <stdbool.h> + +static bool zaptest_test_memcp(void) { + unsigned int arr[] = { + 0xA5D0u, + 0x98FFu, + 0xA29Au, + 0x910Cu, + }; + unsigned int buf[sizeof (arr) / sizeof (arr[0x0u])]; + zap_memcp(arr,sizeof (arr),buf); + zaptest_chk(buf[0x0u],0xA5D0u,unsigned int,"%X"); + zaptest_chk(buf[0x1u],0x98FFu,unsigned int,"%X"); + zaptest_chk(buf[0x2u],0xA29Au,unsigned int,"%X"); + zaptest_chk(buf[0x3u],0x910Cu,unsigned int,"%X"); + return false; +} diff --git a/test/src/test/memeq.i b/test/src/test/memeq.i new file mode 100644 index 0000000..d9de72f --- /dev/null +++ b/test/src/test/memeq.i @@ -0,0 +1,24 @@ +#include <stdbool.h> + +static bool zaptest_test_memeq(void) { + unsigned char const arr0[] = { + 0xFFu, + 0x7Fu, + 0x3Fu, + }; + unsigned char const arr1[] = { + 0xFFu, + 0x7Fu, + 0xFFu, + }; + unsigned char const arr2[] = { + 0xFFu, + 0x7Fu, + 0x3Fu, + }; + zap_cmp eq = zap_memeq(arr0,sizeof (arr0),arr1); + zaptest_chk(eq,zap_false,unsigned char,"%hhX") + eq = zap_memeq(arr0,sizeof (arr0),arr2); + zaptest_chk(eq,zap_true,unsigned char,"%hhX") + return false; +} diff --git a/test/src/test/memfill.i b/test/src/test/memfill.i new file mode 100644 index 0000000..9cb4d6e --- /dev/null +++ b/test/src/test/memfill.i @@ -0,0 +1,23 @@ +#include <stdbool.h> + +static bool zaptest_test_memfill(void) { + unsigned long arr[0x4u]; + zap_memfill(arr,sizeof (arr),0x7Fu); + arr[0x0u] &= 0xFFFFFFFFFFFFFFFFu; + arr[0x1u] &= 0xFFFFFFFFFFFFFFFFu; + arr[0x2u] &= 0xFFFFFFFFFFFFFFFFu; + arr[0x3u] &= 0xFFFFFFFFFFFFFFFFu; + zaptest_chk(arr[0x0u],0x7F7F7F7F7F7F7F7Fu,unsigned long,"%lX"); + zaptest_chk(arr[0x1u],0x7F7F7F7F7F7F7F7Fu,unsigned long,"%lX"); + zaptest_chk(arr[0x2u],0x7F7F7F7F7F7F7F7Fu,unsigned long,"%lX"); + zaptest_chk(arr[0x3u],0x7F7F7F7F7F7F7F7Fu,unsigned long,"%lX"); + zap_memfill(arr + 0x1u,sizeof (arr) - sizeof (arr[0x0u]),0x3Fu); + arr[0x1u] &= 0xFFFFFFFFFFFFFFFFu; + arr[0x2u] &= 0xFFFFFFFFFFFFFFFFu; + arr[0x3u] &= 0xFFFFFFFFFFFFFFFFu; + zaptest_chk(arr[0x0u],0x7F7F7F7F7F7F7F7Fu,unsigned long,"%lX"); + zaptest_chk(arr[0x1u],0x3F3F3F3F3F3F3F3Fu,unsigned long,"%lX"); + zaptest_chk(arr[0x2u],0x3F3F3F3F3F3F3F3Fu,unsigned long,"%lX"); + zaptest_chk(arr[0x3u],0x3F3F3F3F3F3F3F3Fu,unsigned long,"%lX"); + return false; +} diff --git a/test/src/test/memgen.i b/test/src/test/memgen.i new file mode 100644 index 0000000..dcc7c69 --- /dev/null +++ b/test/src/test/memgen.i @@ -0,0 +1,29 @@ +#include <stdbool.h> +#include <stddef.h> + +static unsigned long zaptest_fib(zap_sz const _num) { + if (_num <= 0x1u) { + if (_num == 0x0u) {return 0x0u;} + return 0x1u; + } + return zaptest_fib(_num - 0x1u) + zaptest_fib(_num - 0x2u); +} + +static void zatest_memgenfn(zap_sz const _num,void * const _ptr) { + unsigned long * ptr = _ptr; + *ptr = zaptest_fib(_num); +} + +static bool zaptest_test_memgen(void) { + unsigned long arr[0x8u]; + zap_memgen(arr,sizeof (arr[0x0u]),sizeof (arr) / sizeof (arr[0x0u]),zatest_memgenfn); + zaptest_chk(arr[0x0u],0x0u,unsigned long,"%lX"); + zaptest_chk(arr[0x1u],0x1u,unsigned long,"%lX"); + zaptest_chk(arr[0x2u],0x1u,unsigned long,"%lX"); + zaptest_chk(arr[0x3u],0x2u,unsigned long,"%lX"); + zaptest_chk(arr[0x4u],0x3u,unsigned long,"%lX"); + zaptest_chk(arr[0x5u],0x5u,unsigned long,"%lX"); + zaptest_chk(arr[0x6u],0x8u,unsigned long,"%lX"); + zaptest_chk(arr[0x7u],0xDu,unsigned long,"%lX"); + return false; +} diff --git a/test/src/test/nullptr.i b/test/src/test/nullptr.i new file mode 100644 index 0000000..00b49bd --- /dev/null +++ b/test/src/test/nullptr.i @@ -0,0 +1,7 @@ +#include <stdbool.h> +#include <stddef.h> + +static bool zaptest_test_nullptr(void) { + zaptest_chk((void *)zap_nullptr,(void *)NULL,void *,"%p") + return false; +} diff --git a/test/src/test/strcat.i b/test/src/test/strcat.i new file mode 100644 index 0000000..e037b88 --- /dev/null +++ b/test/src/test/strcat.i @@ -0,0 +1,19 @@ +#include <stdbool.h> + +static bool zaptest_test_strcat(void) { + char const str0[] = "u r "; + char const str1[] = "mr gay"; + char buf[sizeof (str0) + sizeof (str1)]; + zap_strcat(str0,str1,buf); + zaptest_chk(buf[0x0u],'u',char,"'%c'"); + zaptest_chk(buf[0x1u],' ',char,"'%c'"); + zaptest_chk(buf[0x2u],'r',char,"'%c'"); + zaptest_chk(buf[0x3u],' ',char,"'%c'"); + zaptest_chk(buf[0x4u],'m',char,"'%c'"); + zaptest_chk(buf[0x5u],'r',char,"'%c'"); + zaptest_chk(buf[0x6u],' ',char,"'%c'"); + zaptest_chk(buf[0x7u],'g',char,"'%c'"); + zaptest_chk(buf[0x8u],'a',char,"'%c'"); + zaptest_chk(buf[0x9u],'y',char,"'%c'"); + return false; +} diff --git a/test/src/test/strcp.i b/test/src/test/strcp.i new file mode 100644 index 0000000..cd878c9 --- /dev/null +++ b/test/src/test/strcp.i @@ -0,0 +1,42 @@ +#include <stdbool.h> + +static bool zaptest_test_strcp(void) { + char const str[] = "What in the world are you doing?"; + zaptest_log(str,char const *,"%s") + char buf[sizeof (str)]; + zap_strcp(str,buf); + zaptest_chk(buf[0x0u], 'W', char,"'%c'") + zaptest_chk(buf[0x1u], 'h', char,"'%c'") + zaptest_chk(buf[0x2u], 'a', char,"'%c'") + zaptest_chk(buf[0x3u], 't', char,"'%c'") + zaptest_chk(buf[0x4u], ' ', char,"'%c'") + zaptest_chk(buf[0x5u], 'i', char,"'%c'") + zaptest_chk(buf[0x6u], 'n', char,"'%c'") + zaptest_chk(buf[0x7u], ' ', char,"'%c'") + zaptest_chk(buf[0x8u], 't', char,"'%c'") + zaptest_chk(buf[0x9u], 'h', char,"'%c'") + zaptest_chk(buf[0xAu], 'e', char,"'%c'") + zaptest_chk(buf[0xBu], ' ', char,"'%c'") + zaptest_chk(buf[0xCu], 'w', char,"'%c'") + zaptest_chk(buf[0xDu], 'o', char,"'%c'") + zaptest_chk(buf[0xEu], 'r', char,"'%c'") + zaptest_chk(buf[0xFu], 'l', char,"'%c'") + zaptest_chk(buf[0x10u],'d', char,"'%c'") + zaptest_chk(buf[0x11u],' ', char,"'%c'") + zaptest_chk(buf[0x12u],'a', char,"'%c'") + zaptest_chk(buf[0x13u],'r', char,"'%c'") + zaptest_chk(buf[0x14u],'e', char,"'%c'") + zaptest_chk(buf[0x15u],' ', char,"'%c'") + zaptest_chk(buf[0x16u],'y', char,"'%c'") + zaptest_chk(buf[0x17u],'o', char,"'%c'") + zaptest_chk(buf[0x18u],'u', char,"'%c'") + zaptest_chk(buf[0x19u],' ', char,"'%c'") + zaptest_chk(buf[0x1Au],'d', char,"'%c'") + zaptest_chk(buf[0x1Bu],'o', char,"'%c'") + zaptest_chk(buf[0x1Cu],'i', char,"'%c'") + zaptest_chk(buf[0x1Du],'n', char,"'%c'") + zaptest_chk(buf[0x1Eu],'g', char,"'%c'") + zaptest_chk(buf[0x1Fu],'?', char,"'%c'") + zaptest_chk(buf[0x20u],'\x0',char,"'%c'") + return false; +} diff --git a/test/src/test/streq.i b/test/src/test/streq.i new file mode 100644 index 0000000..f9f1d31 --- /dev/null +++ b/test/src/test/streq.i @@ -0,0 +1,17 @@ +#include <stdbool.h> + +static bool zaptest_test_streq(void) { + char const str0[] = "What's up, my guy?"; + char const str1[] = "What's up, my guy?"; + char const str2[] = "I don't know you!"; + zaptest_log(str0,char const *,"%s") + zaptest_log(str1,char const *,"%s") + zaptest_log(str2,char const *,"%s") + zap_bool eq0 = zap_streq(str0,str1); + zap_bool eq1 = zap_streq(str0,str2); + zap_bool eq2 = zap_streq(str1,str2); + zaptest_chk(eq0,zap_true, unsigned char,"%hhX"); + zaptest_chk(eq1,zap_false,unsigned char,"%hhX"); + zaptest_chk(eq2,zap_false,unsigned char,"%hhX"); + return false; +} diff --git a/test/src/test/strfill.i b/test/src/test/strfill.i new file mode 100644 index 0000000..1e2764c --- /dev/null +++ b/test/src/test/strfill.i @@ -0,0 +1,18 @@ +#include <stdbool.h> + +static bool zaptest_test_strfill(void) { + char str[] = { + 'H', + 'e', + 'y', + '!', + '\x0', + }; + zap_strfill(str,'&'); + zaptest_chk(str[0x0u],'&', char,"'%c'"); + zaptest_chk(str[0x1u],'&', char,"'%c'"); + zaptest_chk(str[0x2u],'&', char,"'%c'"); + zaptest_chk(str[0x3u],'&', char,"'%c'"); + zaptest_chk(str[0x4u],'\x0',char,"'%c'"); + return false; +} diff --git a/test/src/test/strlen.i b/test/src/test/strlen.i new file mode 100644 index 0000000..93bec76 --- /dev/null +++ b/test/src/test/strlen.i @@ -0,0 +1,13 @@ +#include <stdbool.h> + +bool zaptest_test_strlen(void) { + char const str0[] = "Hello there! General Kenobi?"; + char const str1[] = "Hello there! General Gayballs?"; + zaptest_log(str0,char const *,"%s") + zaptest_log(str1,char const *,"%s") + zap_sz const len0 = zap_strlen(str0); + zap_sz const len1 = zap_strlen(str1); + zaptest_chk(len0,0x1Cu,zap_sz,"%zX") + zaptest_chk(len1,0x1Eu,zap_sz,"%zX") + return false; +} diff --git a/test/src/test/utf8dec.i b/test/src/test/utf8dec.i new file mode 100644 index 0000000..fdea169 --- /dev/null +++ b/test/src/test/utf8dec.i @@ -0,0 +1,43 @@ +#include <inttypes.h> +#include <stdbool.h> +#include <stdlib.h> +#include <stdio.h> + +static bool zaptest_test_utf8dec(void) { + zap_chr8 const utf8[] = { + 0x26u, + 0xC3u, + 0xB0u, + 0xE0u, + 0xB6u, + 0x9Eu, + 0xE2u, + 0x86u, + 0x8Au, + 0xE2u, + 0x86u, + 0x8Bu, + 0xF0u, + 0x9Fu, + 0x97u, + 0xBFu, + 0x0u, + }; + zap_sz const enclen = zap_utf8declen(utf8); + zaptest_chk(enclen,0x6u,zap_sz,"%zX") + zap_chr20 * const utf20 = malloc(sizeof (zap_chr20) * (enclen + 0x1u)); + if (utf20 == NULL) { + fputs("test.utf8dec: Memory allocation failed!\n\n",stderr); + return true; + } + zap_utf8dec(utf8,utf20); + zaptest_chk(utf20[0x0u],0x26u, zap_chr20,"%" PRIXLEAST32) + zaptest_chk(utf20[0x1u],0xF0u, zap_chr20,"%" PRIXLEAST32) + zaptest_chk(utf20[0x2u],0xD9Eu, zap_chr20,"%" PRIXLEAST32) + zaptest_chk(utf20[0x3u],0x218Au, zap_chr20,"%" PRIXLEAST32) + zaptest_chk(utf20[0x4u],0x218Bu, zap_chr20,"%" PRIXLEAST32) + zaptest_chk(utf20[0x5u],0x1F5FFu,zap_chr20,"%" PRIXLEAST32) + zaptest_chk(utf20[0x6u],0x0u, zap_chr20,"%" PRIXLEAST32) + free(utf20); + return false; +} diff --git a/test/src/test/utf8enc.i b/test/src/test/utf8enc.i new file mode 100644 index 0000000..8bc7abb --- /dev/null +++ b/test/src/test/utf8enc.i @@ -0,0 +1,42 @@ +#include <stdbool.h> +#include <stdlib.h> + +static bool zaptest_test_utf8enc(void) { + zap_chr20 const utf20[] = { + 0x26u, + 0xF0u, + 0xD9Eu, + 0x218Au, + 0x218Bu, + 0x1F5FFu, + 0x0u, + }; + zap_sz const enclen = zap_utf8enclen(utf20); + zaptest_chk(enclen,0x10u,zap_sz,"%zX") + zap_chr8 * const utf8 = malloc(enclen + 0x1u); + if (utf8 == NULL) { + fputs("test.utf8enc: Memory allocation failed!\n\n",stderr); + return true; + } + zap_utf8enc(utf20,utf8); + zaptest_log(utf8,char const *,"%s") /* UB? */ + zaptest_chk(utf8[0x0u], 0x26u,unsigned char,"%hhX") + zaptest_chk(utf8[0x1u], 0xC3u,unsigned char,"%hhX") + zaptest_chk(utf8[0x2u], 0xB0u,unsigned char,"%hhX") + zaptest_chk(utf8[0x3u], 0xE0u,unsigned char,"%hhX") + zaptest_chk(utf8[0x4u], 0xB6u,unsigned char,"%hhX") + zaptest_chk(utf8[0x5u], 0x9Eu,unsigned char,"%hhX") + zaptest_chk(utf8[0x6u], 0xE2u,unsigned char,"%hhX") + zaptest_chk(utf8[0x7u], 0x86u,unsigned char,"%hhX") + zaptest_chk(utf8[0x8u], 0x8Au,unsigned char,"%hhX") + zaptest_chk(utf8[0x9u], 0xE2u,unsigned char,"%hhX") + zaptest_chk(utf8[0xAu], 0x86u,unsigned char,"%hhX") + zaptest_chk(utf8[0xBu], 0x8Bu,unsigned char,"%hhX") + zaptest_chk(utf8[0xCu], 0xF0u,unsigned char,"%hhX") + zaptest_chk(utf8[0xDu], 0x9Fu,unsigned char,"%hhX") + zaptest_chk(utf8[0xEu], 0x97u,unsigned char,"%hhX") + zaptest_chk(utf8[0xFu], 0xBFu,unsigned char,"%hhX") + zaptest_chk(utf8[0x10u],0x0u, unsigned char,"%hhX") + free(utf8); + return false; +} diff --git a/test/src/test/win1252dec.i b/test/src/test/win1252dec.i new file mode 100644 index 0000000..23fbe2b --- /dev/null +++ b/test/src/test/win1252dec.i @@ -0,0 +1,76 @@ +#include <inttypes.h> +#include <stdbool.h> + +static bool zaptest_test_win1252dec(void) { + zap_chr8 const win1252[] = { + 0x26u, + 0xF0u, + 0x80u, + 0x82u, + 0x83u, + 0x84u, + 0x85u, + 0x86u, + 0x87u, + 0x88u, + 0x89u, + 0x8Au, + 0x8Bu, + 0x8Cu, + 0x8Eu, + 0x91u, + 0x92u, + 0x93u, + 0x94u, + 0x95u, + 0x96u, + 0x97u, + 0x98u, + 0x99u, + 0x9Au, + 0x9Bu, + 0x9Cu, + 0x9Eu, + 0x9Fu, + 0x0u, + }; + zap_sz const enclen = sizeof (win1252) - 0x1u; + zaptest_chk(enclen,0x1Du,zap_sz,"%zX") + zap_chr20 * const utf20 = malloc(sizeof (zap_chr20) * (enclen + 0x1u)); + if (utf20 == NULL) { + fputs("test.win1252dec: Memory allocation failed!\n\n",stderr); + return true; + } + zap_win1252dec(win1252,utf20); + zaptest_chk(utf20[0x0u], 0x26u, zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x1u], 0xF0u, zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x2u], 0x20ACu,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x3u], 0x201Au,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x4u], 0x192u, zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x5u], 0x201Eu,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x6u], 0x2026u,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x7u], 0x2020u,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x8u], 0x2021u,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x9u], 0x2C6u, zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0xAu], 0x2030u,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0xBu], 0x160u, zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0xCu], 0x2039u,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0xDu], 0x152u, zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0xEu], 0x17Du, zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0xFu], 0x2018u,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x10u],0x2019u,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x11u],0x201Cu,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x12u],0x201Du,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x13u],0x2022u,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x14u],0x2013u,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x15u],0x2014u,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x16u],0x2DCu, zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x17u],0x2122u,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x18u],0x161u, zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x19u],0x203Au,zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x1Au],0x153u, zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x1Bu],0x17Eu, zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x1Cu],0x178u, zap_chr20,"%" PRIXLEAST32); + zaptest_chk(utf20[0x1Du],0x0u, zap_chr20,"%" PRIXLEAST32); + return false; +} diff --git a/test/src/test/win1252enc.i b/test/src/test/win1252enc.i new file mode 100644 index 0000000..2bfa211 --- /dev/null +++ b/test/src/test/win1252enc.i @@ -0,0 +1,76 @@ +#include <stdbool.h> + +static bool zaptest_test_win1252enc(void) { + zap_chr20 const utf20[] = { + 0x26u, + 0xF0u, + 0x20ACu, + 0x201Au, + 0x192u, + 0x201Eu, + 0x2026u, + 0x2020u, + 0x2021u, + 0x2C6u, + 0x2030u, + 0x160u, + 0x2039u, + 0x152u, + 0x17Du, + 0x2018u, + 0x2019u, + 0x201Cu, + 0x201Du, + 0x2022u, + 0x2013u, + 0x2014u, + 0x2DCu, + 0x2122u, + 0x161u, + 0x203Au, + 0x153u, + 0x17Eu, + 0x178u, + 0x0u, + }; + zap_sz const enclen = sizeof (utf20) / sizeof (utf20[0x0u]) - 0x1u; + zaptest_chk(enclen,0x1Du,zap_sz,"%zX") + zap_chr8 * const win1252 = malloc(enclen + 0x1u); + if (win1252 == NULL) { + fputs("test.win1252enc: Memory allocation failed!\n\n",stderr); + return true; + } + zap_win1252enc(utf20,win1252); + zaptest_log(win1252,char const *,"%s"); /* UB? */ + zaptest_chk(win1252[0x0u], 0x26u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x1u], 0xF0u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x2u], 0x80u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x3u], 0x82u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x4u], 0x83u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x5u], 0x84u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x6u], 0x85u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x7u], 0x86u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x8u], 0x87u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x9u], 0x88u,unsigned char,"%hhX"); + zaptest_chk(win1252[0xAu], 0x89u,unsigned char,"%hhX"); + zaptest_chk(win1252[0xBu], 0x8Au,unsigned char,"%hhX"); + zaptest_chk(win1252[0xCu], 0x8Bu,unsigned char,"%hhX"); + zaptest_chk(win1252[0xDu], 0x8Cu,unsigned char,"%hhX"); + zaptest_chk(win1252[0xEu], 0x8Eu,unsigned char,"%hhX"); + zaptest_chk(win1252[0xFu], 0x91u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x10u],0x92u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x11u],0x93u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x12u],0x94u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x13u],0x95u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x14u],0x96u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x15u],0x97u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x16u],0x98u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x17u],0x99u,unsigned char,"%hhX"); + zaptest_chk(win1252[0x18u],0x9Au,unsigned char,"%hhX"); + zaptest_chk(win1252[0x19u],0x9Bu,unsigned char,"%hhX"); + zaptest_chk(win1252[0x1Au],0x9Cu,unsigned char,"%hhX"); + zaptest_chk(win1252[0x1Bu],0x9Eu,unsigned char,"%hhX"); + zaptest_chk(win1252[0x1Cu],0x9Fu,unsigned char,"%hhX"); + zaptest_chk(win1252[0x1Du],0x0u, unsigned char,"%hhX"); + return false; +} 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 |