diff options
Diffstat (limited to 'zap/src/abs.c')
-rw-r--r-- | zap/src/abs.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/zap/src/abs.c b/zap/src/abs.c new file mode 100644 index 0000000..8fe97e6 --- /dev/null +++ b/zap/src/abs.c @@ -0,0 +1,96 @@ +/* + Copyright 2022 Gabriel Jensen. + This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. + If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. +*/ + +#include <zap/priv.h> + +#include <zap/math.h> + +#include <stdint.h> + +#if zap_priv_fastimpl +__asm__ ( + ".globl zap_abs_c\n" + ".globl zap_abs_i\n" + ".globl zap_abs_l\n" + ".globl zap_abs_ll\n" + ".globl zap_abs_s\n" + + "zap_abs_c:\n" + /* + signed char val + */ +#if defined(sus_arch_amd64) || defined(sus_arch_ia32) + "movb %dil,%al\n" + "sarb $0x3F,%al\n" + "xorb %al,%dil\n" + "subb %al,%dil\n" + "movb %dil,%al\n" + "ret\n" +#endif + + "zap_abs_i:\n" + /* + int val + */ +#if defined(sus_arch_amd64) || defined(sus_arch_ia32) + "movl %edi,%eax\n" + "sarl $0x3F,%eax\n" + "xorl %eax,%edi\n" + "subl %eax,%edi\n" + "movl %edi,%eax\n" + "ret\n" +#endif + + "zap_abs_l:\n" + /* + long val + */ +#if defined(sus_arch_amd64) + "movq %rdi,%rax\n" + "sarq $0x3F,%rax\n" + "xorq %rax,%rdi\n" + "subq %rax,%rdi\n" + "movq %rdi,%rax\n" + "ret\n" +#endif + + "zap_abs_ll:\n" + /* + long long val + */ +#if defined(sus_arch_amd64) + "movq %rdi,%rax\n" + "sarq $0x3F,%rax\n" + "xorq %rax,%rdi\n" + "subq %rax,%rdi\n" + "movq %rdi,%rax\n" + "ret\n" +#endif + + "zap_abs_s:\n" + /* + short val + */ +#if defined(sus_arch_amd64) || defined(sus_arch_ia32) + "movw %di,%ax\n" + "sarw $0x3F,%ax\n" + "xorw %ax,%di\n" + "subw %ax,%di\n" + "movw %di,%ax\n" + "ret\n" +#endif +); +#else +#define zap_local_abs(_typ,_sufx) \ + _typ zap_abs_ ## _sufx (_typ const _val) {return _val > (_typ)0x0 ? _val : -_val;} + +zap_local_abs(signed char,c) +zap_local_abs(int,i) +zap_local_abs(long,l) +zap_local_abs(long long,ll) +zap_local_abs(short,s) + +#endif |