diff --git a/stage1/zig.h b/stage1/zig.h index 0b9c6e58ca..67158429fd 100644 --- a/stage1/zig.h +++ b/stage1/zig.h @@ -79,6 +79,9 @@ #elif defined(__I86__) #define zig_x86_16 #define zig_x86 +#elif defined (__ez80) +#define zig_ez80 +#define zig_z80 #endif #if defined(zig_msvc) || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ @@ -409,6 +412,8 @@ #define zig_trap() __asm__ volatile("int $0x3") #elif defined(zig_x86) #define zig_trap() __asm__ volatile("ud2") +#elif defined(zig_z80) +#define zig_trap() __asm__ volatile("rst 00h") #else #define zig_trap() zig_trap_unavailable #endif @@ -511,7 +516,7 @@ zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t); zig_extern void *memset (void *, int, size_t); zig_extern void *memmove (void *, void const *, size_t); -/* ================ Bool and 8/16/32/64-bit Integer Support ================= */ +/* ================ Bool and 8/16/24/32/48/64-bit Integer Support ================= */ #include @@ -590,6 +595,16 @@ typedef signed long long int16_t; #define INT16_MAX ( INT16_C(0x7FFF)) #define UINT16_MAX ( INT16_C(0xFFFF)) +#if defined(zig_ez80) +typedef unsigned int uint24_t; +typedef signed int int24_t; +#define INT24_C(c) c +#define UINT24_C(c) c##U +#endif +#define INT24_MIN (~INT24_C(0x7FFF)) +#define INT24_MAX ( INT24_C(0x7FFF)) +#define UINT24_MAX ( INT24_C(0xFFFF)) + #if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF typedef unsigned char uint32_t; typedef signed char int32_t; @@ -620,6 +635,17 @@ typedef signed long long int32_t; #define INT32_MAX ( INT32_C(0x7FFFFFFF)) #define UINT32_MAX ( INT32_C(0xFFFFFFFF)) +#if defined(zig_ez80) +typedef unsigned __int48 uint48_t; +typedef signed __int48 int48_t; +#define INT48_C(c) c +/* no suffix */ +#define UINT48_C(c) ((uint48_t)(c)) +#endif +#define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF)) +#define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF)) +#define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF)) + #if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF typedef unsigned char uint64_t; typedef signed char int64_t; @@ -663,10 +689,18 @@ typedef ptrdiff_t intptr_t; #define zig_maxInt_i16 INT16_MAX #define zig_minInt_u16 UINT16_C(0) #define zig_maxInt_u16 UINT16_MAX +#define zig_minInt_i24 INT24_MIN +#define zig_maxInt_i24 INT24_MAX +#define zig_minInt_u24 UINT24_C(0) +#define zig_maxInt_u24 UINT24_MAX #define zig_minInt_i32 INT32_MIN #define zig_maxInt_i32 INT32_MAX #define zig_minInt_u32 UINT32_C(0) #define zig_maxInt_u32 UINT32_MAX +#define zig_minInt_i48 INT48_MIN +#define zig_maxInt_i48 INT48_MAX +#define zig_minInt_u48 UINT48_C(0) +#define zig_maxInt_u48 UINT48_MAX #define zig_minInt_i64 INT64_MIN #define zig_maxInt_i64 INT64_MAX #define zig_minInt_u64 UINT64_C(0) @@ -786,6 +820,17 @@ zig_int_helpers(16, unsigned long long) #else zig_int_helpers(16, uint16_t) #endif +#if defined(zig_ez80) +#if UINT24_MAX <= UINT_MAX +zig_int_helpers(24, unsigned int) +#elif UINT24_MAX <= ULONG_MAX +zig_int_helpers(24, unsigned long) +#elif UINT24_MAX <= ULLONG_MAX +zig_int_helpers(24, unsigned long long) +#else +zig_int_helpers(24, uint24_t) +#endif +#endif #if UINT32_MAX <= UINT_MAX zig_int_helpers(32, unsigned int) #elif UINT32_MAX <= ULONG_MAX @@ -795,6 +840,17 @@ zig_int_helpers(32, unsigned long long) #else zig_int_helpers(32, uint32_t) #endif +#if defined(zig_ez80) +#if UINT24_MAX <= UINT_MAX +zig_int_helpers(48, unsigned int) +#elif UINT24_MAX <= ULONG_MAX +zig_int_helpers(48, unsigned long) +#elif UINT24_MAX <= ULLONG_MAX +zig_int_helpers(48, unsigned long long) +#else +zig_int_helpers(48, uint48_t) +#endif +#endif #if UINT64_MAX <= UINT_MAX zig_int_helpers(64, unsigned int) #elif UINT64_MAX <= ULONG_MAX @@ -909,6 +965,66 @@ static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t #endif } +#if defined(zig_ez80) +static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { +#if zig_has_builtin(add_overflow) || defined(zig_gcc) + uint24_t full_res; + bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); + *res = zig_wrap_u24(full_res, bits); + return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); +#else + uint32_t full_res; + bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits); + *res = (uint24_t)full_res; + return overflow; +#endif +} + +static inline bool zig_addo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t bits) { +#if zig_has_builtin(add_overflow) || defined(zig_gcc) + int24_t full_res; + bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); + *res = zig_wrap_i24(full_res, bits); + return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); +#else + int32_t full_res; + bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits); + *res = (int24_t)full_res; + return overflow; +#endif +} +#endif + +#if defined(zig_ez80) +static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { +#if zig_has_builtin(add_overflow) || defined(zig_gcc) + uint48_t full_res; + bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); + *res = zig_wrap_u48(full_res, bits); + return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); +#else + uint64_t full_res; + bool overflow = zig_addo_u64(&full_res, lhs, rhs, bits); + *res = (uint48_t)full_res; + return overflow; +#endif +} + +static inline bool zig_addo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t bits) { +#if zig_has_builtin(add_overflow) || defined(zig_gcc) + int48_t full_res; + bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); + *res = zig_wrap_i48(full_res, bits); + return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); +#else + int64_t full_res; + bool overflow = zig_addo_i64(&full_res, lhs, rhs, bits); + *res = (int48_t)full_res; + return overflow; +#endif +} +#endif + static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { #if zig_has_builtin(sub_overflow) || defined(zig_gcc) uint32_t full_res; @@ -933,6 +1049,7 @@ static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits); } + static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) { #if zig_has_builtin(sub_overflow) || defined(zig_gcc) uint64_t full_res; @@ -1013,6 +1130,66 @@ static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t #endif } +#if defined(zig_ez80) +static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { +#if zig_has_builtin(sub_overflow) || defined(zig_gcc) + uint24_t full_res; + bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); + *res = zig_wrap_u24(full_res, bits); + return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); +#else + uint32_t full_res; + bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits); + *res = (uint24_t)full_res; + return overflow; +#endif +} + +static inline bool zig_subo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t bits) { +#if zig_has_builtin(sub_overflow) || defined(zig_gcc) + int24_t full_res; + bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); + *res = zig_wrap_i24(full_res, bits); + return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); +#else + int32_t full_res; + bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits); + *res = (int24_t)full_res; + return overflow; +#endif +} +#endif + +#if defined(zig_ez80) +static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { +#if zig_has_builtin(sub_overflow) || defined(zig_gcc) + uint48_t full_res; + bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); + *res = zig_wrap_u48(full_res, bits); + return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); +#else + uint64_t full_res; + bool overflow = zig_subo_u64(&full_res, lhs, rhs, bits); + *res = (uint48_t)full_res; + return overflow; +#endif +} + +static inline bool zig_subo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t bits) { +#if zig_has_builtin(sub_overflow) || defined(zig_gcc) + int48_t full_res; + bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); + *res = zig_wrap_i48(full_res, bits); + return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); +#else + int64_t full_res; + bool overflow = zig_subo_i64(&full_res, lhs, rhs, bits); + *res = (int48_t)full_res; + return overflow; +#endif +} +#endif + static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) { #if zig_has_builtin(mul_overflow) || defined(zig_gcc) uint32_t full_res; @@ -1121,6 +1298,66 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t #endif } +#if defined(zig_ez80) +static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) { +#if zig_has_builtin(mul_overflow) || defined(zig_gcc) + uint24_t full_res; + bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); + *res = zig_wrap_u24(full_res, bits); + return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits); +#else + uint32_t full_res; + bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits); + *res = (uint24_t)full_res; + return overflow; +#endif +} + +static inline bool zig_mulo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t bits) { +#if zig_has_builtin(mul_overflow) || defined(zig_gcc) + int24_t full_res; + bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); + *res = zig_wrap_i24(full_res, bits); + return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits); +#else + int32_t full_res; + bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits); + *res = (int24_t)full_res; + return overflow; +#endif +} +#endif + +#if defined(zig_ez80) +static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) { +#if zig_has_builtin(mul_overflow) || defined(zig_gcc) + uint48_t full_res; + bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); + *res = zig_wrap_u48(full_res, bits); + return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits); +#else + uint64_t full_res; + bool overflow = zig_mulo_u64(&full_res, lhs, rhs, bits); + *res = (uint48_t)full_res; + return overflow; +#endif +} + +static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t bits) { +#if zig_has_builtin(mul_overflow) || defined(zig_gcc) + int48_t full_res; + bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); + *res = zig_wrap_i48(full_res, bits); + return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits); +#else + int64_t full_res; + bool overflow = zig_mulo_i64(&full_res, lhs, rhs, bits); + *res = (int48_t)full_res; + return overflow; +#endif +} +#endif + #define zig_int_builtins(w) \ static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \ *res = zig_shlw_u##w(lhs, rhs, bits); \ @@ -1180,7 +1417,13 @@ static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t } zig_int_builtins(8) zig_int_builtins(16) +#if defined(zig_ez80) +zig_int_builtins(24) +#endif zig_int_builtins(32) +#if defined(zig_ez80) +zig_int_builtins(48) +#endif zig_int_builtins(64) #define zig_builtin8(name, val) __builtin_##name(val) @@ -1189,6 +1432,11 @@ typedef unsigned int zig_Builtin8; #define zig_builtin16(name, val) __builtin_##name(val) typedef unsigned int zig_Builtin16; +#if defined(zig_ez80) +#define zig_builtin24(name, val) __builtin_##name(val) +typedef unsigned int zig_Builtin24; +#endif + #if INT_MIN <= INT32_MIN #define zig_builtin32(name, val) __builtin_##name(val) typedef unsigned int zig_Builtin32; @@ -1197,6 +1445,11 @@ typedef unsigned int zig_Builtin32; typedef unsigned long zig_Builtin32; #endif +#if defined(zig_ez80) +#define zig_builtin48(name, val) __builtin_##name(val) +typedef unsigned long long zig_Builtin48; +#endif + #if INT_MIN <= INT64_MIN #define zig_builtin64(name, val) __builtin_##name(val) typedef unsigned int zig_Builtin64; @@ -1231,6 +1484,23 @@ static inline int16_t zig_byte_swap_i16(int16_t val, uint8_t bits) { return zig_wrap_i16((int16_t)zig_byte_swap_u16((uint16_t)val, bits), bits); } +#if defined(zig_ez80) +static inline uint16_t zig_byte_swap_u24(uint24_t val, uint8_t bits) { + uint24_t full_res; +#if zig_has_builtin(bswap24) || defined(zig_gcc) + full_res = __builtin_bswap24(val); +#else + full_res = (uint24_t)zig_byte_swap_u8((uint8_t)(val >> 0), 8) << 16 | + (uint24_t)zig_byte_swap_u16((uint16_t)(val >> 8), 16) >> 0; +#endif + return zig_wrap_u24(full_res >> (24 - bits), bits); +} + +static inline int16_t zig_byte_swap_i24(int24_t val, uint8_t bits) { + return zig_wrap_i24((int24_t)zig_byte_swap_u24((uint24_t)val, bits), bits); +} +#endif + static inline uint32_t zig_byte_swap_u32(uint32_t val, uint8_t bits) { uint32_t full_res; #if zig_has_builtin(bswap32) || defined(zig_gcc) @@ -1246,6 +1516,23 @@ static inline int32_t zig_byte_swap_i32(int32_t val, uint8_t bits) { return zig_wrap_i32((int32_t)zig_byte_swap_u32((uint32_t)val, bits), bits); } +#if defined(zig_ez80) +static inline uint32_t zig_byte_swap_u48(uint48_t val, uint8_t bits) { + uint48_t full_res; +#if zig_has_builtin(bswap48) || defined(zig_gcc) + full_res = __builtin_bswap48(val); +#else + full_res = (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 0), 24) << 24 | + (uint48_t)zig_byte_swap_u24((uint24_t)(val >> 24), 24) >> 0; +#endif + return zig_wrap_u48(full_res >> (48 - bits), bits); +} + +static inline int32_t zig_byte_swap_i48(int48_t val, uint8_t bits) { + return zig_wrap_i48((int48_t)zig_byte_swap_u48((uint48_t)val, bits), bits); +} +#endif + static inline uint64_t zig_byte_swap_u64(uint64_t val, uint8_t bits) { uint64_t full_res; #if zig_has_builtin(bswap64) || defined(zig_gcc) @@ -1294,6 +1581,23 @@ static inline int16_t zig_bit_reverse_i16(int16_t val, uint8_t bits) { return zig_wrap_i16((int16_t)zig_bit_reverse_u16((uint16_t)val, bits), bits); } +#if defined(zig_ez80) +static inline uint24_t zig_bit_reverse_u24(uint24_t val, uint8_t bits) { + uint24_t full_res; +#if zig_has_builtin(bitreverse24) + full_res = __builtin_bitreverse24(val); +#else + full_res = (uint24_t)zig_bit_reverse_u8((uint8_t)(val >> 0), 8) << 16 | + (uint24_t)zig_bit_reverse_u16((uint16_t)(val >> 8), 16) >> 0; +#endif + return zig_wrap_u24(full_res >> (24 - bits), bits); +} + +static inline int24_t zig_bit_reverse_i24(int24_t val, uint8_t bits) { + return zig_wrap_i24((int24_t)zig_bit_reverse_u24((uint24_t)val, bits), bits); +} +#endif + static inline uint32_t zig_bit_reverse_u32(uint32_t val, uint8_t bits) { uint32_t full_res; #if zig_has_builtin(bitreverse32) @@ -1309,6 +1613,23 @@ static inline int32_t zig_bit_reverse_i32(int32_t val, uint8_t bits) { return zig_wrap_i32((int32_t)zig_bit_reverse_u32((uint32_t)val, bits), bits); } +#if defined(zig_ez80) +static inline uint32_t zig_bit_reverse_u48(uint48_t val, uint8_t bits) { + uint48_t full_res; +#if zig_has_builtin(bitreverse48) + full_res = __builtin_bitreverse48(val); +#else + full_res = (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 0), 24) << 24 | + (uint48_t)zig_bit_reverse_u24((uint24_t)(val >> 24), 24) >> 0; +#endif + return zig_wrap_u32(full_res >> (48 - bits), bits); +} + +static inline int32_t zig_bit_reverse_i48(int48_t val, uint8_t bits) { + return zig_wrap_i48((int48_t)zig_bit_reverse_u48((uint48_t)val, bits), bits); +} +#endif + static inline uint64_t zig_bit_reverse_u64(uint64_t val, uint8_t bits) { uint64_t full_res; #if zig_has_builtin(bitreverse64) @@ -1350,7 +1671,13 @@ static inline int64_t zig_bit_reverse_i64(int64_t val, uint8_t bits) { #endif zig_builtin_popcount(8) zig_builtin_popcount(16) +#if defined(zig_ez80) +zig_builtin_popcount(24) +#endif zig_builtin_popcount(32) +#if defined(zig_ez80) +zig_builtin_popcount(48) +#endif zig_builtin_popcount(64) #define zig_builtin_ctz_common(w) \ @@ -1375,7 +1702,13 @@ zig_builtin_popcount(64) #endif zig_builtin_ctz(8) zig_builtin_ctz(16) +#if defined(zig_ez80) +zig_builtin_ctz(24) +#endif zig_builtin_ctz(32) +#if defined(zig_ez80) +zig_builtin_ctz(48) +#endif zig_builtin_ctz(64) #define zig_builtin_clz_common(w) \ @@ -1400,7 +1733,13 @@ zig_builtin_ctz(64) #endif zig_builtin_clz(8) zig_builtin_clz(16) +#if defined(zig_ez80) +zig_builtin_clz(24) +#endif zig_builtin_clz(32) +#if defined(zig_ez80) +zig_builtin_clz(48) +#endif zig_builtin_clz(64) /* ======================== 128-bit Integer Support ========================= */ @@ -1981,6 +2320,20 @@ static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, uint8_t bits) { return zig_bitCast_i128(zig_bit_reverse_u128(zig_bitCast_u128(val), bits)); } +#if zig_has_int128 +#define zig_switch_int128(operand) switch (operand) +#define zig_switch_prong_begin_int128() +#define zig_switch_case_int128(Type, operand, value) case value: +#define zig_switch_prong_end_int128() +#define zig_switch_default_int128() default: +#else // zig_has_int128 +#define zig_switch_int128(operand) +#define zig_switch_prong_begin_int128() if (0 +#define zig_switch_case_int128(Type, operand, value) || (zig_cmp_##Type(operand, value) == 0) +#define zig_switch_prong_end_int128() ) +#define zig_switch_default_int128() +#endif // zig_has_int128 + /* ========================== Big Integer Support =========================== */ static inline uint16_t zig_int_bytes(uint16_t bits) { diff --git a/stage1/zig1.wasm b/stage1/zig1.wasm index 11942012c7..67ca7db75a 100644 Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ