aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
Diffstat (limited to 'src/link')
-rw-r--r--src/link/C/zig.h152
1 files changed, 152 insertions, 0 deletions
diff --git a/src/link/C/zig.h b/src/link/C/zig.h
index a3e571d245..83e6d8006b 100644
--- a/src/link/C/zig.h
+++ b/src/link/C/zig.h
@@ -60,9 +60,161 @@
#define zig_breakpoint() raise(SIGTRAP)
#endif
+
+#define ZIG_UADDW(Type, lhs, rhs, max) \
+ Type thresh = max - rhs; \
+ if (lhs > thresh) { \
+ return lhs - thresh - 1; \
+ } else { \
+ return lhs + rhs; \
+ }
+
+#define ZIG_SADDW(Type, lhs, rhs, min, max) \
+ if ((lhs > 0) && (rhs > 0)) { \
+ Type thresh = max - rhs; \
+ if (lhs > thresh) { \
+ return min + lhs - thresh - 1; \
+ } \
+ } else if ((lhs < 0) && (rhs < 0)) { \
+ Type thresh = min - rhs; \
+ if (lhs < thresh) { \
+ return max + lhs - thresh + 1; \
+ } \
+ } \
+ \
+ return lhs + rhs;
+
+#define ZIG_USUBW(lhs, rhs, max) \
+ if (lhs < rhs) { \
+ return max - rhs - lhs + 1; \
+ } else { \
+ return lhs - rhs; \
+ }
+
+#define ZIG_SSUBW(Type, lhs, rhs, min, max) \
+ if ((lhs > 0) && (rhs < 0)) { \
+ Type thresh = lhs - max; \
+ if (rhs < thresh) { \
+ return min + (thresh - rhs - 1); \
+ } \
+ } else if ((lhs < 0) && (rhs > 0)) { \
+ Type thresh = lhs - min; \
+ if (rhs > thresh) { \
+ return max - (rhs - thresh - 1); \
+ } \
+ } \
+ return lhs - rhs;
+
#include <stdint.h>
#include <stddef.h>
+#include <limits.h>
#define int128_t __int128
#define uint128_t unsigned __int128
ZIG_EXTERN_C void *memcpy (void *ZIG_RESTRICT, const void *ZIG_RESTRICT, size_t);
+/* Wrapping addition operators */
+static inline uint8_t zig_addw_u8(uint8_t lhs, uint8_t rhs, uint8_t max) {
+ ZIG_UADDW(uint8_t, lhs, rhs, max);
+}
+
+static inline int8_t zig_addw_i8(int8_t lhs, int8_t rhs, int8_t min, int8_t max) {
+ ZIG_SADDW(int8_t, lhs, rhs, min, max);
+}
+
+static inline uint16_t zig_addw_u16(uint16_t lhs, uint16_t rhs, uint16_t max) {
+ ZIG_UADDW(uint16_t, lhs, rhs, max);
+}
+
+static inline int16_t zig_addw_i16(int16_t lhs, int16_t rhs, int16_t min, int16_t max) {
+ ZIG_SADDW(int16_t, lhs, rhs, min, max);
+}
+
+static inline uint32_t zig_addw_u32(uint32_t lhs, uint32_t rhs, uint32_t max) {
+ ZIG_UADDW(uint32_t, lhs, rhs, max);
+}
+
+static inline int32_t zig_addw_i32(int32_t lhs, int32_t rhs, int32_t min, int32_t max) {
+ ZIG_SADDW(int32_t, lhs, rhs, min, max);
+}
+
+static inline uint64_t zig_addw_u64(uint64_t lhs, uint64_t rhs, uint64_t max) {
+ ZIG_UADDW(uint64_t, lhs, rhs, max);
+}
+
+static inline int64_t zig_addw_i64(int64_t lhs, int64_t rhs, int64_t min, int64_t max) {
+ ZIG_SADDW(int64_t, lhs, rhs, min, max);
+}
+
+static inline intptr_t zig_addw_isize(intptr_t lhs, intptr_t rhs, intptr_t min, intptr_t max) {
+ return (intptr_t)(((uintptr_t)lhs) + ((uintptr_t)rhs));
+}
+
+static inline short zig_addw_short(short lhs, short rhs, short min, short max) {
+ return (short)(((unsigned short)lhs) + ((unsigned short)rhs));
+}
+
+static inline int zig_addw_int(int lhs, int rhs, int min, int max) {
+ return (int)(((unsigned)lhs) + ((unsigned)rhs));
+}
+
+static inline long zig_addw_long(long lhs, long rhs, long min, long max) {
+ return (long)(((unsigned long)lhs) + ((unsigned long)rhs));
+}
+
+static inline long long zig_addw_longlong(long long lhs, long long rhs, long long min, long long max) {
+ return (long long)(((unsigned long long)lhs) + ((unsigned long long)rhs));
+}
+
+/* Wrapping subtraction operators */
+static inline uint8_t zig_subw_u8(uint8_t lhs, uint8_t rhs, uint8_t max) {
+ ZIG_USUBW(lhs, rhs, max);
+}
+
+static inline int8_t zig_subw_i8(int8_t lhs, int8_t rhs, int8_t min, int8_t max) {
+ ZIG_SSUBW(int8_t, lhs, rhs, min, max);
+}
+
+static inline uint16_t zig_subw_u16(uint16_t lhs, uint16_t rhs, uint16_t max) {
+ ZIG_USUBW(lhs, rhs, max);
+}
+
+static inline int16_t zig_subw_i16(int16_t lhs, int16_t rhs, int16_t min, int16_t max) {
+ ZIG_SSUBW(int16_t, lhs, rhs, min, max);
+}
+
+static inline uint32_t zig_subw_u32(uint32_t lhs, uint32_t rhs, uint32_t max) {
+ ZIG_USUBW(lhs, rhs, max);
+}
+
+static inline int32_t zig_subw_i32(int32_t lhs, int32_t rhs, int32_t min, int32_t max) {
+ ZIG_SSUBW(int32_t, lhs, rhs, min, max);
+}
+
+static inline uint64_t zig_subw_u64(uint64_t lhs, uint64_t rhs, uint64_t max) {
+ ZIG_USUBW(lhs, rhs, max);
+}
+
+static inline int64_t zig_subw_i64(int64_t lhs, int64_t rhs, int64_t min, int64_t max) {
+ ZIG_SSUBW(int64_t, lhs, rhs, min, max);
+}
+
+static inline intptr_t zig_subw_isize(intptr_t lhs, intptr_t rhs, intptr_t min, intptr_t max) {
+ return (intptr_t)(((uintptr_t)lhs) - ((uintptr_t)rhs));
+}
+
+static inline short zig_subw_short(short lhs, short rhs, short min, short max) {
+ return (short)(((unsigned short)lhs) - ((unsigned short)rhs));
+}
+
+static inline int zig_subw_int(int lhs, int rhs, int min, int max) {
+ return (int)(((unsigned)lhs) - ((unsigned)rhs));
+}
+
+static inline long zig_subw_long(long lhs, long rhs, long min, long max) {
+ return (long)(((unsigned long)lhs) - ((unsigned long)rhs));
+}
+
+static inline long long zig_subw_longlong(long long lhs, long long rhs, long long min, long long max) {
+ return (long long)(((unsigned long long)lhs) - ((unsigned long long)rhs));
+}
+