diff options
Diffstat (limited to 'zap/source/amd64')
-rw-r--r-- | zap/source/amd64/mem/fndbyte.S | 44 | ||||
-rw-r--r-- | zap/source/amd64/mem/fndchr.S | 43 | ||||
-rw-r--r-- | zap/source/amd64/mem/foreach.S | 55 | ||||
-rw-r--r-- | zap/source/amd64/mem/memcat.c | 16 | ||||
-rw-r--r-- | zap/source/amd64/mem/memcp.S | 94 | ||||
-rw-r--r-- | zap/source/amd64/mem/memeq.S | 67 | ||||
-rw-r--r-- | zap/source/amd64/mem/memfill.S | 30 | ||||
-rw-r--r-- | zap/source/amd64/mem/memgen.c | 25 | ||||
-rw-r--r-- | zap/source/amd64/mem/strcat.c | 19 | ||||
-rw-r--r-- | zap/source/amd64/mem/strcp.S | 39 | ||||
-rw-r--r-- | zap/source/amd64/mem/streq.S | 43 | ||||
-rw-r--r-- | zap/source/amd64/mem/strfill.S | 34 | ||||
-rw-r--r-- | zap/source/amd64/mem/strlen.S | 33 | ||||
-rw-r--r-- | zap/source/amd64/mem/utf8dec.c | 51 | ||||
-rw-r--r-- | zap/source/amd64/mem/utf8declen.c | 35 | ||||
-rw-r--r-- | zap/source/amd64/mem/utf8enc.S | 139 | ||||
-rw-r--r-- | zap/source/amd64/mem/utf8enclen.S | 67 | ||||
-rw-r--r-- | zap/source/amd64/mem/win1252dec.c | 111 | ||||
-rw-r--r-- | zap/source/amd64/mem/win1252enc.c | 113 |
19 files changed, 1058 insertions, 0 deletions
diff --git a/zap/source/amd64/mem/fndbyte.S b/zap/source/amd64/mem/fndbyte.S new file mode 100644 index 0000000..9298b73 --- /dev/null +++ b/zap/source/amd64/mem/fndbyte.S @@ -0,0 +1,44 @@ +# 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/. + +.globl zap_fndbyte + +zap_fndbyte: + # 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 diff --git a/zap/source/amd64/mem/fndchr.S b/zap/source/amd64/mem/fndchr.S new file mode 100644 index 0000000..1078a10 --- /dev/null +++ b/zap/source/amd64/mem/fndchr.S @@ -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/. + +.globl zap_fndchr + +zap_fndchr: + # 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 diff --git a/zap/source/amd64/mem/foreach.S b/zap/source/amd64/mem/foreach.S new file mode 100644 index 0000000..f19bcfa --- /dev/null +++ b/zap/source/amd64/mem/foreach.S @@ -0,0 +1,55 @@ +# 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/. + +.globl zap_foreach + +zap_foreach: + # 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 diff --git a/zap/source/amd64/mem/memcat.c b/zap/source/amd64/mem/memcat.c new file mode 100644 index 0000000..f3e9a9b --- /dev/null +++ b/zap/source/amd64/mem/memcat.c @@ -0,0 +1,16 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <zap/mem.h> + +#include <stddef.h> + +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/source/amd64/mem/memcp.S b/zap/source/amd64/mem/memcp.S new file mode 100644 index 0000000..5691446 --- /dev/null +++ b/zap/source/amd64/mem/memcp.S @@ -0,0 +1,94 @@ +# Copyright 2022 Gabriel Jensen. +# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. +# If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. + +.globl zap_memcp + +zap_memcp: + # 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 +
\ No newline at end of file diff --git a/zap/source/amd64/mem/memeq.S b/zap/source/amd64/mem/memeq.S new file mode 100644 index 0000000..ba43dfc --- /dev/null +++ b/zap/source/amd64/mem/memeq.S @@ -0,0 +1,67 @@ +# 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/. + +.globl zap_memeq + +zap_memeq: + /* 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 diff --git a/zap/source/amd64/mem/memfill.S b/zap/source/amd64/mem/memfill.S new file mode 100644 index 0000000..e563b55 --- /dev/null +++ b/zap/source/amd64/mem/memfill.S @@ -0,0 +1,30 @@ +# 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/. + +.globl zap_memfill + +zap_memfill: + # 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 diff --git a/zap/source/amd64/mem/memgen.c b/zap/source/amd64/mem/memgen.c new file mode 100644 index 0000000..a39e326 --- /dev/null +++ b/zap/source/amd64/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/source/amd64/mem/strcat.c b/zap/source/amd64/mem/strcat.c new file mode 100644 index 0000000..f7f66c8 --- /dev/null +++ b/zap/source/amd64/mem/strcat.c @@ -0,0 +1,19 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <zap/mem.h> + +#include <stddef.h> + +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/source/amd64/mem/strcp.S b/zap/source/amd64/mem/strcp.S new file mode 100644 index 0000000..eb5c276 --- /dev/null +++ b/zap/source/amd64/mem/strcp.S @@ -0,0 +1,39 @@ +# 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/. + +.globl zap_strcp + +zap_strcp: + # 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 diff --git a/zap/source/amd64/mem/streq.S b/zap/source/amd64/mem/streq.S new file mode 100644 index 0000000..4270e7d --- /dev/null +++ b/zap/source/amd64/mem/streq.S @@ -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/. + +.globl zap_streq + +zap_streq: + # 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 diff --git a/zap/source/amd64/mem/strfill.S b/zap/source/amd64/mem/strfill.S new file mode 100644 index 0000000..590b99f --- /dev/null +++ b/zap/source/amd64/mem/strfill.S @@ -0,0 +1,34 @@ +# 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/. + +.globl zap_strfill + +zap_strfill: + # 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 diff --git a/zap/source/amd64/mem/strlen.S b/zap/source/amd64/mem/strlen.S new file mode 100644 index 0000000..bd83008 --- /dev/null +++ b/zap/source/amd64/mem/strlen.S @@ -0,0 +1,33 @@ +# 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/. + +.globl zap_strlen + +zap_strlen: + # 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 diff --git a/zap/source/amd64/mem/utf8dec.c b/zap/source/amd64/mem/utf8dec.c new file mode 100644 index 0000000..62f3f61 --- /dev/null +++ b/zap/source/amd64/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; + if (oct == 0x0u) {break;} + } +} diff --git a/zap/source/amd64/mem/utf8declen.c b/zap/source/amd64/mem/utf8declen.c new file mode 100644 index 0000000..85062b9 --- /dev/null +++ b/zap/source/amd64/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; + if (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/source/amd64/mem/utf8enc.S b/zap/source/amd64/mem/utf8enc.S new file mode 100644 index 0000000..357bdaa --- /dev/null +++ b/zap/source/amd64/mem/utf8enc.S @@ -0,0 +1,139 @@ +# 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/. + +.globl zap_utf8enc + +zap_utf8enc: + # 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 +
\ No newline at end of file diff --git a/zap/source/amd64/mem/utf8enclen.S b/zap/source/amd64/mem/utf8enclen.S new file mode 100644 index 0000000..2e3b09f --- /dev/null +++ b/zap/source/amd64/mem/utf8enclen.S @@ -0,0 +1,67 @@ +# 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/. + +.globl zap_utf8enclen + +zap_utf8enclen: + # 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 diff --git a/zap/source/amd64/mem/win1252dec.c b/zap/source/amd64/mem/win1252dec.c new file mode 100644 index 0000000..2a5e897 --- /dev/null +++ b/zap/source/amd64/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; + } + if (chr == 0x0u) {break;} + } +} diff --git a/zap/source/amd64/mem/win1252enc.c b/zap/source/amd64/mem/win1252enc.c new file mode 100644 index 0000000..cd313cd --- /dev/null +++ b/zap/source/amd64/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: + if (chr > 0xFFu) { + *out = bad; + break; + } + if (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; + } + if (chr == 0x0u) {break;} + } +} |