summaryrefslogtreecommitdiff
path: root/zap/src/abs.c
diff options
context:
space:
mode:
Diffstat (limited to 'zap/src/abs.c')
-rw-r--r--zap/src/abs.c96
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