diff options
| author | Matt Knight <mattnite@protonmail.com> | 2021-04-10 14:21:59 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-07-08 09:56:40 -0700 |
| commit | fb16633ecb496f3f30cdac11987baad40b7793b2 (patch) | |
| tree | 96d0b726a2fac3faa5f13777652806d846916025 /src/link | |
| parent | 62d27fcfb687e3ab1f10c72513e19529d8ffceed (diff) | |
| download | zig-fb16633ecb496f3f30cdac11987baad40b7793b2.tar.gz zig-fb16633ecb496f3f30cdac11987baad40b7793b2.zip | |
C backend: add/sub/mul wrapping for the C backend
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/C/zig.h | 152 |
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)); +} + |
