| author | |
| committer | |
| log | 5f5a20ebaf646fe629da370ec56ad86dd2761290 |
| tree | 07153eefc0a6441ae3306202590ff93d21d475a6 |
| parent | 09a96cdfce0540e4c02dd3b0917de6b59edbc95c |
| parent | 4364f5147697f3c6a9147efd74eec82586cf568c |
| signature |
C backend fixes99 files changed, 4277 insertions(+), 3390 deletions(-)
lib/include/zig.h+1219-1319| ... | @@ -1,97 +1,109 @@ | ... | @@ -1,97 +1,109 @@ |
| 1 | #undef linux | 1 | #undef linux |
| 2 | 2 | ||
| 3 | #define __STDC_WANT_IEC_60559_TYPES_EXT__ | ||
| 4 | #include <float.h> | ||
| 5 | #include <limits.h> | ||
| 6 | #include <stddef.h> | ||
| 7 | #include <stdint.h> | ||
| 8 | |||
| 9 | #if defined(__has_builtin) | ||
| 10 | #define zig_has_builtin(builtin) __has_builtin(__builtin_##builtin) | ||
| 11 | #else | ||
| 12 | #define zig_has_builtin(builtin) 0 | ||
| 13 | #endif | ||
| 14 | |||
| 15 | #if defined(__has_attribute) | ||
| 16 | #define zig_has_attribute(attribute) __has_attribute(attribute) | ||
| 17 | #else | ||
| 18 | #define zig_has_attribute(attribute) 0 | ||
| 19 | #endif | ||
| 20 | |||
| 3 | #if __STDC_VERSION__ >= 201112L | 21 | #if __STDC_VERSION__ >= 201112L |
| 4 | #define zig_noreturn _Noreturn | ||
| 5 | #define zig_threadlocal thread_local | 22 | #define zig_threadlocal thread_local |
| 6 | #elif __GNUC__ | 23 | #elif __GNUC__ |
| 7 | #define zig_noreturn __attribute__ ((noreturn)) | ||
| 8 | #define zig_threadlocal __thread | 24 | #define zig_threadlocal __thread |
| 9 | #elif _MSC_VER | 25 | #elif _MSC_VER |
| 10 | #define zig_noreturn __declspec(noreturn) | ||
| 11 | #define zig_threadlocal __declspec(thread) | 26 | #define zig_threadlocal __declspec(thread) |
| 12 | #else | 27 | #else |
| 13 | #define zig_noreturn | ||
| 14 | #define zig_threadlocal zig_threadlocal_unavailable | 28 | #define zig_threadlocal zig_threadlocal_unavailable |
| 15 | #endif | 29 | #endif |
| 16 | 30 | ||
| 17 | #if __GNUC__ | 31 | #if zig_has_attribute(naked) |
| 18 | #define ZIG_COLD __attribute__ ((cold)) | 32 | #define zig_naked __attribute__((naked)) |
| 33 | #elif defined(_MSC_VER) | ||
| 34 | #define zig_naked __declspec(naked) | ||
| 19 | #else | 35 | #else |
| 20 | #define ZIG_COLD | 36 | #define zig_naked zig_naked_unavailable |
| 21 | #endif | 37 | #endif |
| 22 | 38 | ||
| 23 | #if __STDC_VERSION__ >= 199901L | 39 | #if zig_has_attribute(cold) |
| 24 | #define ZIG_RESTRICT restrict | 40 | #define zig_cold __attribute__((cold)) |
| 25 | #elif defined(__GNUC__) | ||
| 26 | #define ZIG_RESTRICT __restrict | ||
| 27 | #else | 41 | #else |
| 28 | #define ZIG_RESTRICT | 42 | #define zig_cold |
| 29 | #endif | 43 | #endif |
| 30 | 44 | ||
| 31 | #if __STDC_VERSION__ >= 201112L | 45 | #if __STDC_VERSION__ >= 199901L |
| 32 | #include <stdalign.h> | 46 | #define zig_restrict restrict |
| 33 | #define ZIG_ALIGN(alignment) alignas(alignment) | ||
| 34 | #elif defined(__GNUC__) | 47 | #elif defined(__GNUC__) |
| 35 | #define ZIG_ALIGN(alignment) __attribute__((aligned(alignment))) | 48 | #define zig_restrict __restrict |
| 36 | #else | 49 | #else |
| 37 | #define ZIG_ALIGN(alignment) zig_compile_error("the C compiler being used does not support aligning variables") | 50 | #define zig_restrict |
| 38 | #endif | 51 | #endif |
| 39 | 52 | ||
| 40 | #if __STDC_VERSION__ >= 199901L | 53 | #if __STDC_VERSION__ >= 201112L |
| 41 | #include <stdbool.h> | 54 | #define zig_align(alignment) _Alignas(alignment) |
| 55 | #elif zig_has_attribute(aligned) | ||
| 56 | #define zig_align(alignment) __attribute__((aligned(alignment))) | ||
| 57 | #elif _MSC_VER | ||
| 42 | #else | 58 | #else |
| 43 | #define bool unsigned char | 59 | #error the C compiler being used does not support aligning variables |
| 44 | #define true 1 | ||
| 45 | #define false 0 | ||
| 46 | #endif | 60 | #endif |
| 47 | 61 | ||
| 48 | #if defined(__GNUC__) | 62 | #if zig_has_builtin(unreachable) |
| 49 | #define zig_unreachable() __builtin_unreachable() | 63 | #define zig_unreachable() __builtin_unreachable() |
| 50 | #else | 64 | #else |
| 51 | #define zig_unreachable() | 65 | #define zig_unreachable() |
| 52 | #endif | 66 | #endif |
| 53 | 67 | ||
| 54 | #ifdef __cplusplus | 68 | #if defined(__cplusplus) |
| 55 | #define ZIG_EXTERN_C extern "C" | 69 | #define zig_extern_c extern "C" |
| 56 | #else | 70 | #else |
| 57 | #define ZIG_EXTERN_C | 71 | #define zig_extern_c |
| 58 | #endif | 72 | #endif |
| 59 | 73 | ||
| 60 | #if defined(_MSC_VER) | 74 | #if zig_has_builtin(debugtrap) |
| 61 | #define zig_breakpoint() __debugbreak() | ||
| 62 | #elif defined(__MINGW32__) || defined(__MINGW64__) | ||
| 63 | #define zig_breakpoint() __debugbreak() | ||
| 64 | #elif defined(__clang__) | ||
| 65 | #define zig_breakpoint() __builtin_debugtrap() | 75 | #define zig_breakpoint() __builtin_debugtrap() |
| 66 | #elif defined(__GNUC__) | 76 | #elif zig_has_builtin(trap) |
| 67 | #define zig_breakpoint() __builtin_trap() | 77 | #define zig_breakpoint() __builtin_trap() |
| 78 | #elif defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) | ||
| 79 | #define zig_breakpoint() __debugbreak() | ||
| 68 | #elif defined(__i386__) || defined(__x86_64__) | 80 | #elif defined(__i386__) || defined(__x86_64__) |
| 69 | #define zig_breakpoint() __asm__ volatile("int $0x03"); | 81 | #define zig_breakpoint() __asm__ volatile("int $0x03"); |
| 70 | #else | 82 | #else |
| 71 | #define zig_breakpoint() raise(SIGTRAP) | 83 | #define zig_breakpoint() raise(SIGTRAP) |
| 72 | #endif | 84 | #endif |
| 73 | 85 | ||
| 74 | #if defined(_MSC_VER) | 86 | #if zig_has_builtin(return_address) |
| 75 | #define zig_return_address() _ReturnAddress() | ||
| 76 | #elif defined(__GNUC__) | ||
| 77 | #define zig_return_address() __builtin_extract_return_addr(__builtin_return_address(0)) | 87 | #define zig_return_address() __builtin_extract_return_addr(__builtin_return_address(0)) |
| 88 | #elif defined(_MSC_VER) | ||
| 89 | #define zig_return_address() _ReturnAddress() | ||
| 78 | #else | 90 | #else |
| 79 | #define zig_return_address() 0 | 91 | #define zig_return_address() 0 |
| 80 | #endif | 92 | #endif |
| 81 | 93 | ||
| 82 | #if defined(__GNUC__) | 94 | #if zig_has_builtin(frame_address) |
| 83 | #define zig_frame_address() __builtin_frame_address(0) | 95 | #define zig_frame_address() __builtin_frame_address(0) |
| 84 | #else | 96 | #else |
| 85 | #define zig_frame_address() 0 | 97 | #define zig_frame_address() 0 |
| 86 | #endif | 98 | #endif |
| 87 | 99 | ||
| 88 | #if defined(__GNUC__) | 100 | #if zig_has_builtin(prefetch) |
| 89 | #define zig_prefetch(addr, rw, locality) __builtin_prefetch(addr, rw, locality) | 101 | #define zig_prefetch(addr, rw, locality) __builtin_prefetch(addr, rw, locality) |
| 90 | #else | 102 | #else |
| 91 | #define zig_prefetch(addr, rw, locality) | 103 | #define zig_prefetch(addr, rw, locality) |
| 92 | #endif | 104 | #endif |
| 93 | 105 | ||
| 94 | #if defined(__clang__) | 106 | #if zig_has_builtin(memory_size) && zig_has_builtin(memory_grow) |
| 95 | #define zig_wasm_memory_size(index) __builtin_wasm_memory_size(index) | 107 | #define zig_wasm_memory_size(index) __builtin_wasm_memory_size(index) |
| 96 | #define zig_wasm_memory_grow(index, delta) __builtin_wasm_memory_grow(index, delta) | 108 | #define zig_wasm_memory_grow(index, delta) __builtin_wasm_memory_grow(index, delta) |
| 97 | #else | 109 | #else |
| ... | @@ -101,19 +113,20 @@ | ... | @@ -101,19 +113,20 @@ |
| 101 | 113 | ||
| 102 | #if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__) | 114 | #if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__) |
| 103 | #include <stdatomic.h> | 115 | #include <stdatomic.h> |
| 116 | #define zig_atomic(type) _Atomic(type) | ||
| 104 | #define zig_cmpxchg_strong(obj, expected, desired, succ, fail) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail) | 117 | #define zig_cmpxchg_strong(obj, expected, desired, succ, fail) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail) |
| 105 | #define zig_cmpxchg_weak (obj, expected, desired, succ, fail) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail) | 118 | #define zig_cmpxchg_weak(obj, expected, desired, succ, fail) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail) |
| 106 | #define zig_atomicrmw_xchg(obj, arg, order) atomic_exchange_explicit (obj, arg, order) | 119 | #define zig_atomicrmw_xchg(obj, arg, order) atomic_exchange_explicit (obj, arg, order) |
| 107 | #define zig_atomicrmw_add (obj, arg, order) atomic_fetch_add_explicit (obj, arg, order) | 120 | #define zig_atomicrmw_add(obj, arg, order) atomic_fetch_add_explicit (obj, arg, order) |
| 108 | #define zig_atomicrmw_sub (obj, arg, order) atomic_fetch_sub_explicit (obj, arg, order) | 121 | #define zig_atomicrmw_sub(obj, arg, order) atomic_fetch_sub_explicit (obj, arg, order) |
| 109 | #define zig_atomicrmw_or (obj, arg, order) atomic_fetch_or_explicit (obj, arg, order) | 122 | #define zig_atomicrmw_or(obj, arg, order) atomic_fetch_or_explicit (obj, arg, order) |
| 110 | #define zig_atomicrmw_xor (obj, arg, order) atomic_fetch_xor_explicit (obj, arg, order) | 123 | #define zig_atomicrmw_xor(obj, arg, order) atomic_fetch_xor_explicit (obj, arg, order) |
| 111 | #define zig_atomicrmw_and (obj, arg, order) atomic_fetch_and_explicit (obj, arg, order) | 124 | #define zig_atomicrmw_and(obj, arg, order) atomic_fetch_and_explicit (obj, arg, order) |
| 112 | #define zig_atomicrmw_nand(obj, arg, order) atomic_fetch_nand_explicit(obj, arg, order) | 125 | #define zig_atomicrmw_nand(obj, arg, order) __atomic_fetch_nand (obj, arg, order) |
| 113 | #define zig_atomicrmw_min (obj, arg, order) atomic_fetch_min_explicit (obj, arg, order) | 126 | #define zig_atomicrmw_min(obj, arg, order) __atomic_fetch_min (obj, arg, order) |
| 114 | #define zig_atomicrmw_max (obj, arg, order) atomic_fetch_max_explicit (obj, arg, order) | 127 | #define zig_atomicrmw_max(obj, arg, order) __atomic_fetch_max (obj, arg, order) |
| 115 | #define zig_atomic_store (obj, arg, order) atomic_store_explicit (obj, arg, order) | 128 | #define zig_atomic_store(obj, arg, order) atomic_store_explicit (obj, arg, order) |
| 116 | #define zig_atomic_load (obj, order) atomic_load_explicit (obj, order) | 129 | #define zig_atomic_load(obj, order) atomic_load_explicit (obj, order) |
| 117 | #define zig_fence(order) atomic_thread_fence(order) | 130 | #define zig_fence(order) atomic_thread_fence(order) |
| 118 | #elif __GNUC__ | 131 | #elif __GNUC__ |
| 119 | #define memory_order_relaxed __ATOMIC_RELAXED | 132 | #define memory_order_relaxed __ATOMIC_RELAXED |
| ... | @@ -122,19 +135,20 @@ | ... | @@ -122,19 +135,20 @@ |
| 122 | #define memory_order_release __ATOMIC_RELEASE | 135 | #define memory_order_release __ATOMIC_RELEASE |
| 123 | #define memory_order_acq_rel __ATOMIC_ACQ_REL | 136 | #define memory_order_acq_rel __ATOMIC_ACQ_REL |
| 124 | #define memory_order_seq_cst __ATOMIC_SEQ_CST | 137 | #define memory_order_seq_cst __ATOMIC_SEQ_CST |
| 125 | #define zig_cmpxchg_strong(obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, false, succ, fail) | 138 | #define zig_atomic(type) type |
| 126 | #define zig_cmpxchg_weak (obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, true , succ, fail) | 139 | #define zig_cmpxchg_strong(obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, zig_false, succ, fail) |
| 140 | #define zig_cmpxchg_weak(obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, zig_true , succ, fail) | ||
| 127 | #define zig_atomicrmw_xchg(obj, arg, order) __atomic_exchange_n(obj, arg, order) | 141 | #define zig_atomicrmw_xchg(obj, arg, order) __atomic_exchange_n(obj, arg, order) |
| 128 | #define zig_atomicrmw_add (obj, arg, order) __atomic_fetch_add (obj, arg, order) | 142 | #define zig_atomicrmw_add(obj, arg, order) __atomic_fetch_add (obj, arg, order) |
| 129 | #define zig_atomicrmw_sub (obj, arg, order) __atomic_fetch_sub (obj, arg, order) | 143 | #define zig_atomicrmw_sub(obj, arg, order) __atomic_fetch_sub (obj, arg, order) |
| 130 | #define zig_atomicrmw_or (obj, arg, order) __atomic_fetch_or (obj, arg, order) | 144 | #define zig_atomicrmw_or(obj, arg, order) __atomic_fetch_or (obj, arg, order) |
| 131 | #define zig_atomicrmw_xor (obj, arg, order) __atomic_fetch_xor (obj, arg, order) | 145 | #define zig_atomicrmw_xor(obj, arg, order) __atomic_fetch_xor (obj, arg, order) |
| 132 | #define zig_atomicrmw_and (obj, arg, order) __atomic_fetch_and (obj, arg, order) | 146 | #define zig_atomicrmw_and(obj, arg, order) __atomic_fetch_and (obj, arg, order) |
| 133 | #define zig_atomicrmw_nand(obj, arg, order) __atomic_fetch_nand(obj, arg, order) | 147 | #define zig_atomicrmw_nand(obj, arg, order) __atomic_fetch_nand(obj, arg, order) |
| 134 | #define zig_atomicrmw_min (obj, arg, order) __atomic_fetch_min (obj, arg, order) | 148 | #define zig_atomicrmw_min(obj, arg, order) __atomic_fetch_min (obj, arg, order) |
| 135 | #define zig_atomicrmw_max (obj, arg, order) __atomic_fetch_max (obj, arg, order) | 149 | #define zig_atomicrmw_max(obj, arg, order) __atomic_fetch_max (obj, arg, order) |
| 136 | #define zig_atomic_store (obj, arg, order) __atomic_store (obj, arg, order) | 150 | #define zig_atomic_store(obj, arg, order) __atomic_store_n (obj, arg, order) |
| 137 | #define zig_atomic_load (obj, order) __atomic_load (obj, order) | 151 | #define zig_atomic_load(obj, order) __atomic_load_n (obj, order) |
| 138 | #define zig_fence(order) __atomic_thread_fence(order) | 152 | #define zig_fence(order) __atomic_thread_fence(order) |
| 139 | #else | 153 | #else |
| 140 | #define memory_order_relaxed 0 | 154 | #define memory_order_relaxed 0 |
| ... | @@ -143,1457 +157,1343 @@ | ... | @@ -143,1457 +157,1343 @@ |
| 143 | #define memory_order_release 3 | 157 | #define memory_order_release 3 |
| 144 | #define memory_order_acq_rel 4 | 158 | #define memory_order_acq_rel 4 |
| 145 | #define memory_order_seq_cst 5 | 159 | #define memory_order_seq_cst 5 |
| 160 | #define zig_atomic(type) type | ||
| 146 | #define zig_cmpxchg_strong(obj, expected, desired, succ, fail) zig_unimplemented() | 161 | #define zig_cmpxchg_strong(obj, expected, desired, succ, fail) zig_unimplemented() |
| 147 | #define zig_cmpxchg_weak (obj, expected, desired, succ, fail) zig_unimplemented() | 162 | #define zig_cmpxchg_weak(obj, expected, desired, succ, fail) zig_unimplemented() |
| 148 | #define zig_atomicrmw_xchg(obj, arg, order) zig_unimplemented() | 163 | #define zig_atomicrmw_xchg(obj, arg, order) zig_unimplemented() |
| 149 | #define zig_atomicrmw_add (obj, arg, order) zig_unimplemented() | 164 | #define zig_atomicrmw_add(obj, arg, order) zig_unimplemented() |
| 150 | #define zig_atomicrmw_sub (obj, arg, order) zig_unimplemented() | 165 | #define zig_atomicrmw_sub(obj, arg, order) zig_unimplemented() |
| 151 | #define zig_atomicrmw_or (obj, arg, order) zig_unimplemented() | 166 | #define zig_atomicrmw_or(obj, arg, order) zig_unimplemented() |
| 152 | #define zig_atomicrmw_xor (obj, arg, order) zig_unimplemented() | 167 | #define zig_atomicrmw_xor(obj, arg, order) zig_unimplemented() |
| 153 | #define zig_atomicrmw_and (obj, arg, order) zig_unimplemented() | 168 | #define zig_atomicrmw_and(obj, arg, order) zig_unimplemented() |
| 154 | #define zig_atomicrmw_nand(obj, arg, order) zig_unimplemented() | 169 | #define zig_atomicrmw_nand(obj, arg, order) zig_unimplemented() |
| 155 | #define zig_atomicrmw_min (obj, arg, order) zig_unimplemented() | 170 | #define zig_atomicrmw_min(obj, arg, order) zig_unimplemented() |
| 156 | #define zig_atomicrmw_max (obj, arg, order) zig_unimplemented() | 171 | #define zig_atomicrmw_max(obj, arg, order) zig_unimplemented() |
| 157 | #define zig_atomic_store (obj, arg, order) zig_unimplemented() | 172 | #define zig_atomic_store(obj, arg, order) zig_unimplemented() |
| 158 | #define zig_atomic_load (obj, order) zig_unimplemented() | 173 | #define zig_atomic_load(obj, order) zig_unimplemented() |
| 159 | #define zig_fence(order) zig_unimplemented() | 174 | #define zig_fence(order) zig_unimplemented() |
| 160 | #endif | 175 | #endif |
| 161 | 176 | ||
| 162 | #include <stdint.h> | 177 | #if __STDC_VERSION__ >= 201112L |
| 163 | #include <stddef.h> | 178 | #define zig_noreturn _Noreturn void |
| 164 | #include <limits.h> | 179 | #elif zig_has_attribute(noreturn) |
| 180 | #define zig_noreturn __attribute__((noreturn)) void | ||
| 181 | #elif _MSC_VER | ||
| 182 | #define zig_noreturn __declspec(noreturn) void | ||
| 183 | #else | ||
| 184 | #define zig_noreturn void | ||
| 185 | #endif | ||
| 165 | 186 | ||
| 166 | #define int128_t __int128 | 187 | #define zig_bitSizeOf(T) (CHAR_BIT * sizeof(T)) |
| 167 | #define uint128_t unsigned __int128 | 188 | |
| 168 | #define UINT128_MAX ((uint128_t)(0xffffffffffffffffull) | 0xffffffffffffffffull) | 189 | typedef void zig_void; |
| 169 | ZIG_EXTERN_C void *memcpy (void *ZIG_RESTRICT, const void *ZIG_RESTRICT, size_t); | 190 | |
| 170 | ZIG_EXTERN_C void *memset (void *, int, size_t); | 191 | #if defined(__cplusplus) |
| 171 | ZIG_EXTERN_C int64_t __addodi4(int64_t lhs, int64_t rhs, int *overflow); | 192 | typedef bool zig_bool; |
| 172 | ZIG_EXTERN_C int128_t __addoti4(int128_t lhs, int128_t rhs, int *overflow); | 193 | #define zig_false false |
| 173 | ZIG_EXTERN_C uint64_t __uaddodi4(uint64_t lhs, uint64_t rhs, int *overflow); | 194 | #define zig_true true |
| 174 | ZIG_EXTERN_C uint128_t __uaddoti4(uint128_t lhs, uint128_t rhs, int *overflow); | 195 | #else |
| 175 | ZIG_EXTERN_C int32_t __subosi4(int32_t lhs, int32_t rhs, int *overflow); | 196 | #if __STDC_VERSION__ >= 199901L |
| 176 | ZIG_EXTERN_C int64_t __subodi4(int64_t lhs, int64_t rhs, int *overflow); | 197 | typedef _Bool zig_bool; |
| 177 | ZIG_EXTERN_C int128_t __suboti4(int128_t lhs, int128_t rhs, int *overflow); | 198 | #else |
| 178 | ZIG_EXTERN_C uint32_t __usubosi4(uint32_t lhs, uint32_t rhs, int *overflow); | 199 | typedef char zig_bool; |
| 179 | ZIG_EXTERN_C uint64_t __usubodi4(uint64_t lhs, uint64_t rhs, int *overflow); | 200 | #endif |
| 180 | ZIG_EXTERN_C uint128_t __usuboti4(uint128_t lhs, uint128_t rhs, int *overflow); | 201 | #define zig_false ((zig_bool)0) |
| 181 | ZIG_EXTERN_C int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow); | 202 | #define zig_true ((zig_bool)1) |
| 182 | ZIG_EXTERN_C int128_t __muloti4(int128_t lhs, int128_t rhs, int *overflow); | 203 | #endif |
| 183 | ZIG_EXTERN_C uint64_t __umulodi4(uint64_t lhs, uint64_t rhs, int *overflow); | 204 | |
| 184 | ZIG_EXTERN_C uint128_t __umuloti4(uint128_t lhs, uint128_t rhs, int *overflow); | 205 | typedef uintptr_t zig_usize; |
| 185 | 206 | typedef intptr_t zig_isize; | |
| 186 | 207 | typedef signed short int zig_c_short; | |
| 187 | static inline uint8_t zig_addw_u8(uint8_t lhs, uint8_t rhs, uint8_t max) { | 208 | typedef unsigned short int zig_c_ushort; |
| 188 | uint8_t thresh = max - rhs; | 209 | typedef signed int zig_c_int; |
| 189 | if (lhs > thresh) { | 210 | typedef unsigned int zig_c_uint; |
| 190 | return lhs - thresh - 1; | 211 | typedef signed long int zig_c_long; |
| 191 | } else { | 212 | typedef unsigned long int zig_c_ulong; |
| 192 | return lhs + rhs; | 213 | typedef signed long long int zig_c_longlong; |
| 193 | } | 214 | typedef unsigned long long int zig_c_ulonglong; |
| 215 | |||
| 216 | typedef uint8_t zig_u8; | ||
| 217 | typedef int8_t zig_i8; | ||
| 218 | typedef uint16_t zig_u16; | ||
| 219 | typedef int16_t zig_i16; | ||
| 220 | typedef uint16_t zig_u16; | ||
| 221 | typedef int16_t zig_i16; | ||
| 222 | typedef uint32_t zig_u32; | ||
| 223 | typedef int32_t zig_i32; | ||
| 224 | typedef uint64_t zig_u64; | ||
| 225 | typedef int64_t zig_i64; | ||
| 226 | |||
| 227 | #define zig_as_u8(val) UINT8_C(val) | ||
| 228 | #define zig_as_i8(val) INT8_C(val) | ||
| 229 | #define zig_as_u16(val) UINT16_C(val) | ||
| 230 | #define zig_as_i16(val) INT16_C(val) | ||
| 231 | #define zig_as_u32(val) UINT32_C(val) | ||
| 232 | #define zig_as_i32(val) INT32_C(val) | ||
| 233 | #define zig_as_u64(val) UINT64_C(val) | ||
| 234 | #define zig_as_i64(val) INT64_C(val) | ||
| 235 | |||
| 236 | #define zig_minInt_u8 zig_as_u8(0) | ||
| 237 | #define zig_maxInt_u8 UINT8_MAX | ||
| 238 | #define zig_minInt_i8 INT8_MIN | ||
| 239 | #define zig_maxInt_i8 INT8_MAX | ||
| 240 | #define zig_minInt_u16 zig_as_u16(0) | ||
| 241 | #define zig_maxInt_u16 UINT16_MAX | ||
| 242 | #define zig_minInt_i16 INT16_MIN | ||
| 243 | #define zig_maxInt_i16 INT16_MAX | ||
| 244 | #define zig_minInt_u32 zig_as_u32(0) | ||
| 245 | #define zig_maxInt_u32 UINT32_MAX | ||
| 246 | #define zig_minInt_i32 INT32_MIN | ||
| 247 | #define zig_maxInt_i32 INT32_MAX | ||
| 248 | #define zig_minInt_u64 zig_as_u64(0) | ||
| 249 | #define zig_maxInt_u64 UINT64_MAX | ||
| 250 | #define zig_minInt_i64 INT64_MIN | ||
| 251 | #define zig_maxInt_i64 INT64_MAX | ||
| 252 | |||
| 253 | #define zig_builtin_f16(name) __##name##h | ||
| 254 | #define zig_builtin_constant_f16(name) zig_suffix_f16(__builtin_##name) | ||
| 255 | #if FLT_MANT_DIG == 11 | ||
| 256 | typedef float zig_f16; | ||
| 257 | #define zig_suffix_f16(x) x##f | ||
| 258 | #elif DBL_MANT_DIG == 11 | ||
| 259 | typedef double zig_f16; | ||
| 260 | #define zig_suffix_f16(x) x | ||
| 261 | #elif LDBL_MANT_DIG == 11 | ||
| 262 | typedef long double zig_f16; | ||
| 263 | #define zig_suffix_f16(x) x##l | ||
| 264 | #elif FLT16_MANT_DIG == 11 | ||
| 265 | typedef _Float16 zig_f16; | ||
| 266 | #define zig_suffix_f16(x) x##f16 | ||
| 267 | #elif defined(__SIZEOF_FP16__) | ||
| 268 | typedef __fp16 zig_f16; | ||
| 269 | #define zig_suffix_f16(x) x##f16 | ||
| 270 | #endif | ||
| 271 | |||
| 272 | #define zig_builtin_f32(name) name##f | ||
| 273 | #define zig_builtin_constant_f32(name) zig_suffix_f32(__builtin_##name) | ||
| 274 | #if FLT_MANT_DIG == 24 | ||
| 275 | typedef float zig_f32; | ||
| 276 | #define zig_suffix_f32(x) x##f | ||
| 277 | #elif DBL_MANT_DIG == 24 | ||
| 278 | typedef double zig_f32; | ||
| 279 | #define zig_suffix_f32(x) x | ||
| 280 | #elif LDBL_MANT_DIG == 24 | ||
| 281 | typedef long double zig_f32; | ||
| 282 | #define zig_suffix_f32(x) x##l | ||
| 283 | #elif FLT32_MANT_DIG == 24 | ||
| 284 | typedef _Float32 zig_f32; | ||
| 285 | #define zig_suffix_f32(x) x##f32 | ||
| 286 | #endif | ||
| 287 | |||
| 288 | #define zig_builtin_f64(name) name | ||
| 289 | #define zig_builtin_constant_f64(name) zig_suffix_f64(__builtin_##name) | ||
| 290 | #if FLT_MANT_DIG == 53 | ||
| 291 | typedef float zig_f64; | ||
| 292 | #define zig_suffix_f64(x) x##f | ||
| 293 | #elif DBL_MANT_DIG == 53 | ||
| 294 | typedef double zig_f64; | ||
| 295 | #define zig_suffix_f64(x) x | ||
| 296 | #elif LDBL_MANT_DIG == 53 | ||
| 297 | typedef long double zig_f64; | ||
| 298 | #define zig_suffix_f64(x) x##l | ||
| 299 | #elif FLT64_MANT_DIG == 53 | ||
| 300 | typedef _Float64 zig_f64; | ||
| 301 | #define zig_suffix_f64(x) x##f64 | ||
| 302 | #elif FLT32X_MANT_DIG == 53 | ||
| 303 | typedef _Float32x zig_f64; | ||
| 304 | #define zig_suffix_f64(x) x##f32x | ||
| 305 | #endif | ||
| 306 | |||
| 307 | #define zig_builtin_f80(name) __##name##x | ||
| 308 | #define zig_builtin_constant_f80(name) zig_suffix_f80(__builtin_##name) | ||
| 309 | #if FLT_MANT_DIG == 64 | ||
| 310 | typedef float zig_f80; | ||
| 311 | #define zig_suffix_f80(x) x##f | ||
| 312 | #elif DBL_MANT_DIG == 64 | ||
| 313 | typedef double zig_f80; | ||
| 314 | #define zig_suffix_f80(x) x | ||
| 315 | #elif LDBL_MANT_DIG == 64 | ||
| 316 | typedef long double zig_f80; | ||
| 317 | #define zig_suffix_f80(x) x##l | ||
| 318 | #elif FLT80_MANT_DIG == 64 | ||
| 319 | typedef _Float80 zig_f80; | ||
| 320 | #define zig_suffix_f80(x) x##f80 | ||
| 321 | #elif FLT64X_MANT_DIG == 64 | ||
| 322 | typedef _Float64x zig_f80; | ||
| 323 | #define zig_suffix_f80(x) x##f64x | ||
| 324 | #elif defined(__SIZEOF_FLOAT80__) | ||
| 325 | typedef __float80 zig_f80; | ||
| 326 | #define zig_suffix_f80(x) x##l | ||
| 327 | #endif | ||
| 328 | |||
| 329 | #define zig_builtin_f128(name) name##q | ||
| 330 | #define zig_builtin_constant_f128(name) zig_suffix_f80(__builtin_##name) | ||
| 331 | #if FLT_MANT_DIG == 113 | ||
| 332 | typedef float zig_f128; | ||
| 333 | #define zig_suffix_f128(x) x##f | ||
| 334 | #elif DBL_MANT_DIG == 113 | ||
| 335 | typedef double zig_f128; | ||
| 336 | #define zig_suffix_f128(x) x | ||
| 337 | #elif LDBL_MANT_DIG == 113 | ||
| 338 | typedef long double zig_f128; | ||
| 339 | #define zig_suffix_f128(x) x##l | ||
| 340 | #elif FLT128_MANT_DIG == 113 | ||
| 341 | typedef _Float128 zig_f128; | ||
| 342 | #define zig_suffix_f128(x) x##f128 | ||
| 343 | #elif FLT64X_MANT_DIG == 113 | ||
| 344 | typedef _Float64x zig_f128; | ||
| 345 | #define zig_suffix_f128(x) x##f64x | ||
| 346 | #elif defined(__SIZEOF_FLOAT128__) | ||
| 347 | typedef __float128 zig_f128; | ||
| 348 | #define zig_suffix_f128(x) x##q | ||
| 349 | #undef zig_builtin_constant_f128 | ||
| 350 | #define zig_builtin_constant_f128(name) __builtin_##name##f128 | ||
| 351 | #endif | ||
| 352 | |||
| 353 | typedef long double zig_c_longdouble; | ||
| 354 | #define zig_suffix_c_longdouble(x) x##l | ||
| 355 | #define zig_builtin_c_longdouble(name) zig_suffix_c_longdouble(name) | ||
| 356 | #define zig_builtin_constant_c_longdouble(name) zig_suffix_c_longdouble(__builtin_##name) | ||
| 357 | |||
| 358 | zig_extern_c void *memcpy (void *zig_restrict, void const *zig_restrict, zig_usize); | ||
| 359 | zig_extern_c void *memset (void *, int, zig_usize); | ||
| 360 | |||
| 361 | /* ==================== 8/16/32/64-bit Integer Routines ===================== */ | ||
| 362 | |||
| 363 | #define zig_maxInt(Type, bits) zig_shr_##Type(zig_maxInt_##Type, (zig_bitSizeOf(zig_##Type) - bits)) | ||
| 364 | #define zig_minInt(Type, bits) zig_not_##Type(zig_maxInt(Type, bits), bits) | ||
| 365 | |||
| 366 | #define zig_int_operator(Type, RhsType, operation, operator) \ | ||
| 367 | static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##RhsType rhs) { \ | ||
| 368 | return lhs operator rhs; \ | ||
| 369 | } | ||
| 370 | #define zig_int_operators(w) \ | ||
| 371 | zig_int_operator(u##w, u##w, and, &) \ | ||
| 372 | zig_int_operator(i##w, i##w, and, &) \ | ||
| 373 | zig_int_operator(u##w, u##w, or, |) \ | ||
| 374 | zig_int_operator(i##w, i##w, or, |) \ | ||
| 375 | zig_int_operator(u##w, u##w, xor, ^) \ | ||
| 376 | zig_int_operator(i##w, i##w, xor, ^) \ | ||
| 377 | zig_int_operator(u##w, u8, shl, <<) \ | ||
| 378 | zig_int_operator(i##w, u8, shl, <<) \ | ||
| 379 | zig_int_operator(u##w, u8, shr, >>) \ | ||
| 380 | zig_int_operator(u##w, u##w, div_floor, /) \ | ||
| 381 | zig_int_operator(u##w, u##w, mod, %) | ||
| 382 | zig_int_operators(8) | ||
| 383 | zig_int_operators(16) | ||
| 384 | zig_int_operators(32) | ||
| 385 | zig_int_operators(64) | ||
| 386 | |||
| 387 | #define zig_int_helpers(w) \ | ||
| 388 | static inline zig_i##w zig_shr_i##w(zig_i##w lhs, zig_u8 rhs) { \ | ||
| 389 | zig_i##w sign_mask = lhs < zig_as_i##w(0) ? -zig_as_i##w(1) : zig_as_i##w(0); \ | ||
| 390 | return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \ | ||
| 391 | } \ | ||
| 392 | \ | ||
| 393 | static inline zig_u##w zig_not_u##w(zig_u##w val, zig_u8 bits) { \ | ||
| 394 | return val ^ zig_maxInt(u##w, bits); \ | ||
| 395 | } \ | ||
| 396 | \ | ||
| 397 | static inline zig_i##w zig_not_i##w(zig_i##w val, zig_u8 bits) { \ | ||
| 398 | (void)bits; \ | ||
| 399 | return ~val; \ | ||
| 400 | } \ | ||
| 401 | \ | ||
| 402 | static inline zig_u##w zig_wrap_u##w(zig_u##w val, zig_u8 bits) { \ | ||
| 403 | return val & zig_maxInt(u##w, bits); \ | ||
| 404 | } \ | ||
| 405 | \ | ||
| 406 | static inline zig_i##w zig_wrap_i##w(zig_i##w val, zig_u8 bits) { \ | ||
| 407 | return (val & zig_as_u##w(1) << (bits - zig_as_u8(1))) != 0 \ | ||
| 408 | ? val | zig_minInt(i##w, bits) : val & zig_maxInt(i##w, bits); \ | ||
| 409 | } \ | ||
| 410 | \ | ||
| 411 | static inline zig_i##w zig_div_floor_i##w(zig_i##w lhs, zig_i##w rhs) { \ | ||
| 412 | return lhs / rhs - (((lhs ^ rhs) & (lhs % rhs)) < zig_as_i##w(0)); \ | ||
| 413 | } \ | ||
| 414 | \ | ||
| 415 | static inline zig_i##w zig_mod_i##w(zig_i##w lhs, zig_i##w rhs) { \ | ||
| 416 | zig_i##w rem = lhs % rhs; \ | ||
| 417 | return rem + (((lhs ^ rhs) & rem) < zig_as_i##w(0) ? rhs : zig_as_i##w(0)); \ | ||
| 418 | } | ||
| 419 | zig_int_helpers(8) | ||
| 420 | zig_int_helpers(16) | ||
| 421 | zig_int_helpers(32) | ||
| 422 | zig_int_helpers(64) | ||
| 423 | |||
| 424 | static inline zig_bool zig_addo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_u8 bits) { | ||
| 425 | #if zig_has_builtin(add_overflow) | ||
| 426 | zig_u32 full_res; | ||
| 427 | zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | ||
| 428 | *res = zig_wrap_u32(full_res, bits); | ||
| 429 | return overflow || full_res < zig_minInt(u32, bits) || full_res > zig_maxInt(u32, bits); | ||
| 430 | #else | ||
| 431 | *res = zig_addw_u32(lhs, rhs, bits); | ||
| 432 | return *res < lhs; | ||
| 433 | #endif | ||
| 194 | } | 434 | } |
| 195 | 435 | ||
| 196 | static inline int8_t zig_addw_i8(int8_t lhs, int8_t rhs, int8_t min, int8_t max) { | 436 | zig_extern_c zig_i32 __addosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow); |
| 197 | if ((lhs > 0) && (rhs > 0)) { | 437 | static inline zig_bool zig_addo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) { |
| 198 | int8_t thresh = max - rhs; | 438 | #if zig_has_builtin(add_overflow) |
| 199 | if (lhs > thresh) { | 439 | zig_i32 full_res; |
| 200 | return min + lhs - thresh - 1; | 440 | zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 201 | } | 441 | #else |
| 202 | } else if ((lhs < 0) && (rhs < 0)) { | 442 | zig_c_int overflow_int; |
| 203 | int8_t thresh = min - rhs; | 443 | zig_u32 full_res = __addosi4(lhs, rhs, &overflow_int); |
| 204 | if (lhs < thresh) { | 444 | zig_bool overflow = overflow_int != 0; |
| 205 | return max + lhs - thresh + 1; | 445 | #endif |
| 206 | } | 446 | *res = zig_wrap_i32(full_res, bits); |
| 207 | } | 447 | return overflow || full_res < zig_minInt(i32, bits) || full_res > zig_maxInt(i32, bits); |
| 208 | return lhs + rhs; | ||
| 209 | } | 448 | } |
| 210 | 449 | ||
| 211 | static inline uint16_t zig_addw_u16(uint16_t lhs, uint16_t rhs, uint16_t max) { | 450 | static inline zig_bool zig_addo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) { |
| 212 | uint16_t thresh = max - rhs; | 451 | #if zig_has_builtin(add_overflow) |
| 213 | if (lhs > thresh) { | 452 | zig_u64 full_res; |
| 214 | return lhs - thresh - 1; | 453 | zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 215 | } else { | 454 | *res = zig_wrap_u64(full_res, bits); |
| 216 | return lhs + rhs; | 455 | return overflow || full_res < zig_minInt(u64, bits) || full_res > zig_maxInt(u64, bits); |
| 217 | } | 456 | #else |
| 457 | *res = zig_addw_u64(lhs, rhs, bits); | ||
| 458 | return *res < lhs; | ||
| 459 | #endif | ||
| 218 | } | 460 | } |
| 219 | 461 | ||
| 220 | static inline int16_t zig_addw_i16(int16_t lhs, int16_t rhs, int16_t min, int16_t max) { | 462 | zig_extern_c zig_i64 __addodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow); |
| 221 | if ((lhs > 0) && (rhs > 0)) { | 463 | static inline zig_bool zig_addo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) { |
| 222 | int16_t thresh = max - rhs; | 464 | #if zig_has_builtin(add_overflow) |
| 223 | if (lhs > thresh) { | 465 | zig_i64 full_res; |
| 224 | return min + lhs - thresh - 1; | 466 | zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 225 | } | 467 | #else |
| 226 | } else if ((lhs < 0) && (rhs < 0)) { | 468 | zig_c_int overflow_int; |
| 227 | int16_t thresh = min - rhs; | 469 | zig_u64 full_res = __addodi4(lhs, rhs, &overflow_int); |
| 228 | if (lhs < thresh) { | 470 | zig_bool overflow = overflow_int != 0; |
| 229 | return max + lhs - thresh + 1; | 471 | #endif |
| 230 | } | 472 | *res = zig_wrap_i64(full_res, bits); |
| 231 | } | 473 | return overflow || full_res < zig_minInt(i64, bits) || full_res > zig_maxInt(i64, bits); |
| 232 | return lhs + rhs; | ||
| 233 | } | 474 | } |
| 234 | 475 | ||
| 235 | static inline uint32_t zig_addw_u32(uint32_t lhs, uint32_t rhs, uint32_t max) { | 476 | static inline zig_bool zig_addo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) { |
| 236 | uint32_t thresh = max - rhs; | 477 | #if zig_has_builtin(add_overflow) |
| 237 | if (lhs > thresh) { | 478 | zig_u8 full_res; |
| 238 | return lhs - thresh - 1; | 479 | zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 239 | } else { | 480 | *res = zig_wrap_u8(full_res, bits); |
| 240 | return lhs + rhs; | 481 | return overflow || full_res < zig_minInt(u8, bits) || full_res > zig_maxInt(u8, bits); |
| 241 | } | 482 | #else |
| 483 | return zig_addo_u32(res, lhs, rhs, bits); | ||
| 484 | #endif | ||
| 242 | } | 485 | } |
| 243 | 486 | ||
| 244 | static inline int32_t zig_addw_i32(int32_t lhs, int32_t rhs, int32_t min, int32_t max) { | 487 | static inline zig_bool zig_addo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) { |
| 245 | if ((lhs > 0) && (rhs > 0)) { | 488 | #if zig_has_builtin(add_overflow) |
| 246 | int32_t thresh = max - rhs; | 489 | zig_i8 full_res; |
| 247 | if (lhs > thresh) { | 490 | zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 248 | return min + lhs - thresh - 1; | 491 | *res = zig_wrap_i8(full_res, bits); |
| 249 | } | 492 | return overflow || full_res < zig_minInt(i8, bits) || full_res > zig_maxInt(i8, bits); |
| 250 | } else if ((lhs < 0) && (rhs < 0)) { | 493 | #else |
| 251 | int32_t thresh = min - rhs; | 494 | return zig_addo_i32(res, lhs, rhs, bits); |
| 252 | if (lhs < thresh) { | 495 | #endif |
| 253 | return max + lhs - thresh + 1; | ||
| 254 | } | ||
| 255 | } | ||
| 256 | return lhs + rhs; | ||
| 257 | } | 496 | } |
| 258 | 497 | ||
| 259 | static inline uint64_t zig_addw_u64(uint64_t lhs, uint64_t rhs, uint64_t max) { | 498 | static inline zig_bool zig_addo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) { |
| 260 | uint64_t thresh = max - rhs; | 499 | #if zig_has_builtin(add_overflow) |
| 261 | if (lhs > thresh) { | 500 | zig_u16 full_res; |
| 262 | return lhs - thresh - 1; | 501 | zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 263 | } else { | 502 | *res = zig_wrap_u16(full_res, bits); |
| 264 | return lhs + rhs; | 503 | return overflow || full_res < zig_minInt(u16, bits) || full_res > zig_maxInt(u16, bits); |
| 265 | } | 504 | #else |
| 505 | return zig_addo_u32(res, lhs, rhs, bits); | ||
| 506 | #endif | ||
| 266 | } | 507 | } |
| 267 | 508 | ||
| 268 | static inline int64_t zig_addw_i64(int64_t lhs, int64_t rhs, int64_t min, int64_t max) { | 509 | static inline zig_bool zig_addo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) { |
| 269 | if ((lhs > 0) && (rhs > 0)) { | 510 | #if zig_has_builtin(add_overflow) |
| 270 | int64_t thresh = max - rhs; | 511 | zig_i16 full_res; |
| 271 | if (lhs > thresh) { | 512 | zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 272 | return min + lhs - thresh - 1; | 513 | *res = zig_wrap_i16(full_res, bits); |
| 273 | } | 514 | return overflow || full_res < zig_minInt(i16, bits) || full_res > zig_maxInt(i16, bits); |
| 274 | } else if ((lhs < 0) && (rhs < 0)) { | 515 | #else |
| 275 | int64_t thresh = min - rhs; | 516 | return zig_addo_i32(res, lhs, rhs, bits); |
| 276 | if (lhs < thresh) { | 517 | #endif |
| 277 | return max + lhs - thresh + 1; | ||
| 278 | } | ||
| 279 | } | ||
| 280 | return lhs + rhs; | ||
| 281 | } | 518 | } |
| 282 | 519 | ||
| 283 | static inline intptr_t zig_addw_isize(intptr_t lhs, intptr_t rhs, intptr_t min, intptr_t max) { | 520 | static inline zig_bool zig_subo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_u8 bits) { |
| 284 | return (intptr_t)(((uintptr_t)lhs) + ((uintptr_t)rhs)); | 521 | #if zig_has_builtin(sub_overflow) |
| 522 | zig_u32 full_res; | ||
| 523 | zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | ||
| 524 | *res = zig_wrap_u32(full_res, bits); | ||
| 525 | return overflow || full_res < zig_minInt(u32, bits) || full_res > zig_maxInt(u32, bits); | ||
| 526 | #else | ||
| 527 | *res = zig_subw_u32(lhs, rhs, bits); | ||
| 528 | return *res > lhs; | ||
| 529 | #endif | ||
| 285 | } | 530 | } |
| 286 | 531 | ||
| 287 | static inline short zig_addw_short(short lhs, short rhs, short min, short max) { | 532 | zig_extern_c zig_i32 __subosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow); |
| 288 | return (short)(((unsigned short)lhs) + ((unsigned short)rhs)); | 533 | static inline zig_bool zig_subo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) { |
| 534 | #if zig_has_builtin(sub_overflow) | ||
| 535 | zig_i32 full_res; | ||
| 536 | zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | ||
| 537 | #else | ||
| 538 | zig_c_int overflow_int; | ||
| 539 | zig_u32 full_res = __subosi4(lhs, rhs, &overflow_int); | ||
| 540 | zig_bool overflow = overflow_int != 0; | ||
| 541 | #endif | ||
| 542 | *res = zig_wrap_i32(full_res, bits); | ||
| 543 | return overflow || full_res < zig_minInt(i32, bits) || full_res > zig_maxInt(i32, bits); | ||
| 289 | } | 544 | } |
| 290 | 545 | ||
| 291 | static inline int zig_addw_int(int lhs, int rhs, int min, int max) { | 546 | static inline zig_bool zig_subo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) { |
| 292 | return (int)(((unsigned)lhs) + ((unsigned)rhs)); | 547 | #if zig_has_builtin(sub_overflow) |
| 548 | zig_u64 full_res; | ||
| 549 | zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | ||
| 550 | *res = zig_wrap_u64(full_res, bits); | ||
| 551 | return overflow || full_res < zig_minInt(u64, bits) || full_res > zig_maxInt(u64, bits); | ||
| 552 | #else | ||
| 553 | *res = zig_subw_u64(lhs, rhs, bits); | ||
| 554 | return *res > lhs; | ||
| 555 | #endif | ||
| 293 | } | 556 | } |
| 294 | 557 | ||
| 295 | static inline long zig_addw_long(long lhs, long rhs, long min, long max) { | 558 | zig_extern_c zig_i64 __subodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow); |
| 296 | return (long)(((unsigned long)lhs) + ((unsigned long)rhs)); | 559 | static inline zig_bool zig_subo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) { |
| 560 | #if zig_has_builtin(sub_overflow) | ||
| 561 | zig_i64 full_res; | ||
| 562 | zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | ||
| 563 | #else | ||
| 564 | zig_c_int overflow_int; | ||
| 565 | zig_u64 full_res = __subodi4(lhs, rhs, &overflow_int); | ||
| 566 | zig_bool overflow = overflow_int != 0; | ||
| 567 | #endif | ||
| 568 | *res = zig_wrap_i64(full_res, bits); | ||
| 569 | return overflow || full_res < zig_minInt(i64, bits) || full_res > zig_maxInt(i64, bits); | ||
| 297 | } | 570 | } |
| 298 | 571 | ||
| 299 | static inline long long zig_addw_longlong(long long lhs, long long rhs, long long min, long long max) { | 572 | static inline zig_bool zig_subo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) { |
| 300 | return (long long)(((unsigned long long)lhs) + ((unsigned long long)rhs)); | 573 | #if zig_has_builtin(sub_overflow) |
| 574 | zig_u8 full_res; | ||
| 575 | zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | ||
| 576 | *res = zig_wrap_u8(full_res, bits); | ||
| 577 | return overflow || full_res < zig_minInt(u8, bits) || full_res > zig_maxInt(u8, bits); | ||
| 578 | #else | ||
| 579 | return zig_subo_u32(res, lhs, rhs, bits); | ||
| 580 | #endif | ||
| 301 | } | 581 | } |
| 302 | 582 | ||
| 303 | static inline uint8_t zig_subw_u8(uint8_t lhs, uint8_t rhs, uint8_t max) { | 583 | static inline zig_bool zig_subo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) { |
| 304 | if (lhs < rhs) { | 584 | #if zig_has_builtin(sub_overflow) |
| 305 | return max - rhs - lhs + 1; | 585 | zig_i8 full_res; |
| 306 | } else { | 586 | zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 307 | return lhs - rhs; | 587 | *res = zig_wrap_i8(full_res, bits); |
| 308 | } | 588 | return overflow || full_res < zig_minInt(i8, bits) || full_res > zig_maxInt(i8, bits); |
| 589 | #else | ||
| 590 | return zig_subo_i32(res, lhs, rhs, bits); | ||
| 591 | #endif | ||
| 309 | } | 592 | } |
| 310 | 593 | ||
| 311 | static inline int8_t zig_subw_i8(int8_t lhs, int8_t rhs, int8_t min, int8_t max) { | 594 | static inline zig_bool zig_subo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) { |
| 312 | if ((lhs > 0) && (rhs < 0)) { | 595 | #if zig_has_builtin(sub_overflow) |
| 313 | int8_t thresh = lhs - max; | 596 | zig_u16 full_res; |
| 314 | if (rhs < thresh) { | 597 | zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 315 | return min + (thresh - rhs - 1); | 598 | *res = zig_wrap_u16(full_res, bits); |
| 316 | } | 599 | return overflow || full_res < zig_minInt(u16, bits) || full_res > zig_maxInt(u16, bits); |
| 317 | } else if ((lhs < 0) && (rhs > 0)) { | 600 | #else |
| 318 | int8_t thresh = lhs - min; | 601 | return zig_subo_u32(res, lhs, rhs, bits); |
| 319 | if (rhs > thresh) { | 602 | #endif |
| 320 | return max - (rhs - thresh - 1); | ||
| 321 | } | ||
| 322 | } | ||
| 323 | return lhs - rhs; | ||
| 324 | } | 603 | } |
| 325 | 604 | ||
| 326 | static inline uint16_t zig_subw_u16(uint16_t lhs, uint16_t rhs, uint16_t max) { | 605 | static inline zig_bool zig_subo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) { |
| 327 | if (lhs < rhs) { | 606 | #if zig_has_builtin(sub_overflow) |
| 328 | return max - rhs - lhs + 1; | 607 | zig_i16 full_res; |
| 329 | } else { | 608 | zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 330 | return lhs - rhs; | 609 | *res = zig_wrap_i16(full_res, bits); |
| 331 | } | 610 | return overflow || full_res < zig_minInt(i16, bits) || full_res > zig_maxInt(i16, bits); |
| 611 | #else | ||
| 612 | return zig_subo_i32(res, lhs, rhs, bits); | ||
| 613 | #endif | ||
| 332 | } | 614 | } |
| 333 | 615 | ||
| 334 | static inline int16_t zig_subw_i16(int16_t lhs, int16_t rhs, int16_t min, int16_t max) { | 616 | static inline zig_bool zig_mulo_u32(zig_u32 *res, zig_u32 lhs, zig_u32 rhs, zig_u8 bits) { |
| 335 | if ((lhs > 0) && (rhs < 0)) { | 617 | #if zig_has_builtin(mul_overflow) |
| 336 | int16_t thresh = lhs - max; | 618 | zig_u32 full_res; |
| 337 | if (rhs < thresh) { | 619 | zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 338 | return min + (thresh - rhs - 1); | 620 | *res = zig_wrap_u32(full_res, bits); |
| 339 | } | 621 | return overflow || full_res < zig_minInt(u32, bits) || full_res > zig_maxInt(u32, bits); |
| 340 | } else if ((lhs < 0) && (rhs > 0)) { | 622 | #else |
| 341 | int16_t thresh = lhs - min; | 623 | *res = zig_mulw_u32(lhs, rhs, bits); |
| 342 | if (rhs > thresh) { | 624 | return rhs != zig_as_u32(0) && lhs > zig_maxInt(u32, bits) / rhs; |
| 343 | return max - (rhs - thresh - 1); | 625 | #endif |
| 344 | } | ||
| 345 | } | ||
| 346 | return lhs - rhs; | ||
| 347 | } | 626 | } |
| 348 | 627 | ||
| 349 | static inline uint32_t zig_subw_u32(uint32_t lhs, uint32_t rhs, uint32_t max) { | 628 | zig_extern_c zig_i32 __mulosi4(zig_i32 lhs, zig_i32 rhs, zig_c_int *overflow); |
| 350 | if (lhs < rhs) { | 629 | static inline zig_bool zig_mulo_i32(zig_i32 *res, zig_i32 lhs, zig_i32 rhs, zig_u8 bits) { |
| 351 | return max - rhs - lhs + 1; | 630 | #if zig_has_builtin(mul_overflow) |
| 352 | } else { | 631 | zig_i32 full_res; |
| 353 | return lhs - rhs; | 632 | zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 354 | } | 633 | #else |
| 634 | zig_c_int overflow_int; | ||
| 635 | zig_u32 full_res = __mulosi4(lhs, rhs, &overflow_int); | ||
| 636 | zig_bool overflow = overflow_int != 0; | ||
| 637 | #endif | ||
| 638 | *res = zig_wrap_i32(full_res, bits); | ||
| 639 | return overflow || full_res < zig_minInt(i32, bits) || full_res > zig_maxInt(i32, bits); | ||
| 355 | } | 640 | } |
| 356 | 641 | ||
| 357 | static inline int32_t zig_subw_i32(int32_t lhs, int32_t rhs, int32_t min, int32_t max) { | 642 | static inline zig_bool zig_mulo_u64(zig_u64 *res, zig_u64 lhs, zig_u64 rhs, zig_u8 bits) { |
| 358 | if ((lhs > 0) && (rhs < 0)) { | 643 | #if zig_has_builtin(mul_overflow) |
| 359 | int32_t thresh = lhs - max; | 644 | zig_u64 full_res; |
| 360 | if (rhs < thresh) { | 645 | zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 361 | return min + (thresh - rhs - 1); | 646 | *res = zig_wrap_u64(full_res, bits); |
| 362 | } | 647 | return overflow || full_res < zig_minInt(u64, bits) || full_res > zig_maxInt(u64, bits); |
| 363 | } else if ((lhs < 0) && (rhs > 0)) { | 648 | #else |
| 364 | int32_t thresh = lhs - min; | 649 | *res = zig_mulw_u64(lhs, rhs, bits); |
| 365 | if (rhs > thresh) { | 650 | return rhs != zig_as_u64(0) && lhs > zig_maxInt(u64, bits) / rhs; |
| 366 | return max - (rhs - thresh - 1); | 651 | #endif |
| 367 | } | ||
| 368 | } | ||
| 369 | return lhs - rhs; | ||
| 370 | } | 652 | } |
| 371 | 653 | ||
| 372 | static inline uint64_t zig_subw_u64(uint64_t lhs, uint64_t rhs, uint64_t max) { | 654 | zig_extern_c zig_i64 __mulodi4(zig_i64 lhs, zig_i64 rhs, zig_c_int *overflow); |
| 373 | if (lhs < rhs) { | 655 | static inline zig_bool zig_mulo_i64(zig_i64 *res, zig_i64 lhs, zig_i64 rhs, zig_u8 bits) { |
| 374 | return max - rhs - lhs + 1; | 656 | #if zig_has_builtin(mul_overflow) |
| 375 | } else { | 657 | zig_i64 full_res; |
| 376 | return lhs - rhs; | 658 | zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 377 | } | 659 | #else |
| 660 | zig_c_int overflow_int; | ||
| 661 | zig_u64 full_res = __mulodi4(lhs, rhs, &overflow_int); | ||
| 662 | zig_bool overflow = overflow_int != 0; | ||
| 663 | #endif | ||
| 664 | *res = zig_wrap_i64(full_res, bits); | ||
| 665 | return overflow || full_res < zig_minInt(i64, bits) || full_res > zig_maxInt(i64, bits); | ||
| 378 | } | 666 | } |
| 379 | 667 | ||
| 380 | static inline int64_t zig_subw_i64(int64_t lhs, int64_t rhs, int64_t min, int64_t max) { | 668 | static inline zig_bool zig_mulo_u8(zig_u8 *res, zig_u8 lhs, zig_u8 rhs, zig_u8 bits) { |
| 381 | if ((lhs > 0) && (rhs < 0)) { | 669 | #if zig_has_builtin(mul_overflow) |
| 382 | int64_t thresh = lhs - max; | 670 | zig_u8 full_res; |
| 383 | if (rhs < thresh) { | 671 | zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 384 | return min + (thresh - rhs - 1); | 672 | *res = zig_wrap_u8(full_res, bits); |
| 385 | } | 673 | return overflow || full_res < zig_minInt(u8, bits) || full_res > zig_maxInt(u8, bits); |
| 386 | } else if ((lhs < 0) && (rhs > 0)) { | 674 | #else |
| 387 | int64_t thresh = lhs - min; | 675 | return zig_mulo_u32(res, lhs, rhs, bits); |
| 388 | if (rhs > thresh) { | 676 | #endif |
| 389 | return max - (rhs - thresh - 1); | ||
| 390 | } | ||
| 391 | } | ||
| 392 | return lhs - rhs; | ||
| 393 | } | 677 | } |
| 394 | 678 | ||
| 395 | static inline intptr_t zig_subw_isize(intptr_t lhs, intptr_t rhs, intptr_t min, intptr_t max) { | 679 | static inline zig_bool zig_mulo_i8(zig_i8 *res, zig_i8 lhs, zig_i8 rhs, zig_u8 bits) { |
| 396 | return (intptr_t)(((uintptr_t)lhs) - ((uintptr_t)rhs)); | 680 | #if zig_has_builtin(mul_overflow) |
| 681 | zig_i8 full_res; | ||
| 682 | zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | ||
| 683 | *res = zig_wrap_i8(full_res, bits); | ||
| 684 | return overflow || full_res < zig_minInt(i8, bits) || full_res > zig_maxInt(i8, bits); | ||
| 685 | #else | ||
| 686 | return zig_mulo_i32(res, lhs, rhs, bits); | ||
| 687 | #endif | ||
| 397 | } | 688 | } |
| 398 | 689 | ||
| 399 | static inline short zig_subw_short(short lhs, short rhs, short min, short max) { | 690 | static inline zig_bool zig_mulo_u16(zig_u16 *res, zig_u16 lhs, zig_u16 rhs, zig_u8 bits) { |
| 400 | return (short)(((unsigned short)lhs) - ((unsigned short)rhs)); | 691 | #if zig_has_builtin(mul_overflow) |
| 692 | zig_u16 full_res; | ||
| 693 | zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | ||
| 694 | *res = zig_wrap_u16(full_res, bits); | ||
| 695 | return overflow || full_res < zig_minInt(u16, bits) || full_res > zig_maxInt(u16, bits); | ||
| 696 | #else | ||
| 697 | return zig_mulo_u32(res, lhs, rhs, bits); | ||
| 698 | #endif | ||
| 401 | } | 699 | } |
| 402 | 700 | ||
| 403 | static inline int zig_subw_int(int lhs, int rhs, int min, int max) { | 701 | static inline zig_bool zig_mulo_i16(zig_i16 *res, zig_i16 lhs, zig_i16 rhs, zig_u8 bits) { |
| 404 | return (int)(((unsigned)lhs) - ((unsigned)rhs)); | 702 | #if zig_has_builtin(mul_overflow) |
| 703 | zig_i16 full_res; | ||
| 704 | zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); | ||
| 705 | *res = zig_wrap_i16(full_res, bits); | ||
| 706 | return overflow || full_res < zig_minInt(i16, bits) || full_res > zig_maxInt(i16, bits); | ||
| 707 | #else | ||
| 708 | return zig_mulo_i32(res, lhs, rhs, bits); | ||
| 709 | #endif | ||
| 405 | } | 710 | } |
| 406 | 711 | ||
| 407 | static inline long zig_subw_long(long lhs, long rhs, long min, long max) { | 712 | #define zig_int_builtins(w) \ |
| 408 | return (long)(((unsigned long)lhs) - ((unsigned long)rhs)); | 713 | static inline zig_u##w zig_shlw_u##w(zig_u##w lhs, zig_u8 rhs, zig_u8 bits) { \ |
| 714 | return zig_wrap_u##w(zig_shl_u##w(lhs, rhs), bits); \ | ||
| 715 | } \ | ||
| 716 | \ | ||
| 717 | static inline zig_i##w zig_shlw_i##w(zig_i##w lhs, zig_u8 rhs, zig_u8 bits) { \ | ||
| 718 | return zig_wrap_i##w((zig_i##w)zig_shl_u##w((zig_u##w)lhs, (zig_u##w)rhs), bits); \ | ||
| 719 | } \ | ||
| 720 | \ | ||
| 721 | static inline zig_u##w zig_addw_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \ | ||
| 722 | return zig_wrap_u##w(lhs + rhs, bits); \ | ||
| 723 | } \ | ||
| 724 | \ | ||
| 725 | static inline zig_i##w zig_addw_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \ | ||
| 726 | return zig_wrap_i##w((zig_i##w)((zig_u##w)lhs + (zig_u##w)rhs), bits); \ | ||
| 727 | } \ | ||
| 728 | \ | ||
| 729 | static inline zig_u##w zig_subw_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \ | ||
| 730 | return zig_wrap_u##w(lhs - rhs, bits); \ | ||
| 731 | } \ | ||
| 732 | \ | ||
| 733 | static inline zig_i##w zig_subw_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \ | ||
| 734 | return zig_wrap_i##w((zig_i##w)((zig_u##w)lhs - (zig_u##w)rhs), bits); \ | ||
| 735 | } \ | ||
| 736 | \ | ||
| 737 | static inline zig_u##w zig_mulw_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \ | ||
| 738 | return zig_wrap_u##w(lhs * rhs, bits); \ | ||
| 739 | } \ | ||
| 740 | \ | ||
| 741 | static inline zig_i##w zig_mulw_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \ | ||
| 742 | return zig_wrap_i##w((zig_i##w)((zig_u##w)lhs * (zig_u##w)rhs), bits); \ | ||
| 743 | } \ | ||
| 744 | \ | ||
| 745 | static inline zig_bool zig_shlo_u##w(zig_u##w *res, zig_u##w lhs, zig_u8 rhs, zig_u8 bits) { \ | ||
| 746 | *res = zig_shlw_u##w(lhs, rhs, bits); \ | ||
| 747 | return (lhs & zig_maxInt_u##w << (bits - rhs)) != zig_as_u##w(0); \ | ||
| 748 | } \ | ||
| 749 | \ | ||
| 750 | static inline zig_bool zig_shlo_i##w(zig_i##w *res, zig_i##w lhs, zig_u8 rhs, zig_u8 bits) { \ | ||
| 751 | *res = zig_shlw_i##w(lhs, rhs, bits); \ | ||
| 752 | zig_i##w mask = (zig_i##w)(zig_maxInt_u##w << (bits - rhs - 1)); \ | ||
| 753 | return (lhs & mask) != zig_as_i##w(0) && (lhs & mask) != mask; \ | ||
| 754 | } \ | ||
| 755 | \ | ||
| 756 | static inline zig_u##w zig_shls_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \ | ||
| 757 | zig_u##w res; \ | ||
| 758 | if (rhs >= bits) return lhs != zig_as_u##w(0) ? zig_maxInt(u##w, bits) : lhs; \ | ||
| 759 | return zig_shlo_u##w(&res, lhs, (zig_u8)rhs, bits) ? zig_maxInt(u##w, bits) : res; \ | ||
| 760 | } \ | ||
| 761 | \ | ||
| 762 | static inline zig_i##w zig_shls_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \ | ||
| 763 | zig_i##w res; \ | ||
| 764 | if ((zig_u##w)rhs < (zig_u##w)bits && !zig_shlo_i##w(&res, lhs, rhs, bits)) return res; \ | ||
| 765 | return lhs < zig_as_i##w(0) ? zig_minInt(i##w, bits) : zig_maxInt(i##w, bits); \ | ||
| 766 | } \ | ||
| 767 | \ | ||
| 768 | static inline zig_u##w zig_adds_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \ | ||
| 769 | zig_u##w res; \ | ||
| 770 | return zig_addo_u##w(&res, lhs, rhs, bits) ? zig_maxInt(u##w, bits) : res; \ | ||
| 771 | } \ | ||
| 772 | \ | ||
| 773 | static inline zig_i##w zig_adds_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \ | ||
| 774 | zig_i##w res; \ | ||
| 775 | if (!zig_addo_i##w(&res, lhs, rhs, bits)) return res; \ | ||
| 776 | return res >= zig_as_i##w(0) ? zig_minInt(i##w, bits) : zig_maxInt(i##w, bits); \ | ||
| 777 | } \ | ||
| 778 | \ | ||
| 779 | static inline zig_u##w zig_subs_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \ | ||
| 780 | zig_u##w res; \ | ||
| 781 | return zig_subo_u##w(&res, lhs, rhs, bits) ? zig_minInt(u##w, bits) : res; \ | ||
| 782 | } \ | ||
| 783 | \ | ||
| 784 | static inline zig_i##w zig_subs_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \ | ||
| 785 | zig_i##w res; \ | ||
| 786 | if (!zig_subo_i##w(&res, lhs, rhs, bits)) return res; \ | ||
| 787 | return res >= zig_as_i##w(0) ? zig_minInt(i##w, bits) : zig_maxInt(i##w, bits); \ | ||
| 788 | } \ | ||
| 789 | \ | ||
| 790 | static inline zig_u##w zig_muls_u##w(zig_u##w lhs, zig_u##w rhs, zig_u8 bits) { \ | ||
| 791 | zig_u##w res; \ | ||
| 792 | return zig_mulo_u##w(&res, lhs, rhs, bits) ? zig_maxInt(u##w, bits) : res; \ | ||
| 793 | } \ | ||
| 794 | \ | ||
| 795 | static inline zig_i##w zig_muls_i##w(zig_i##w lhs, zig_i##w rhs, zig_u8 bits) { \ | ||
| 796 | zig_i##w res; \ | ||
| 797 | if (!zig_mulo_i##w(&res, lhs, rhs, bits)) return res; \ | ||
| 798 | return (lhs ^ rhs) < zig_as_i##w(0) ? zig_minInt(i##w, bits) : zig_maxInt(i##w, bits); \ | ||
| 799 | } | ||
| 800 | zig_int_builtins(8) | ||
| 801 | zig_int_builtins(16) | ||
| 802 | zig_int_builtins(32) | ||
| 803 | zig_int_builtins(64) | ||
| 804 | |||
| 805 | #define zig_builtin8(name, val) __builtin_##name(val) | ||
| 806 | typedef zig_c_uint zig_Builtin8; | ||
| 807 | |||
| 808 | #define zig_builtin16(name, val) __builtin_##name(val) | ||
| 809 | typedef zig_c_uint zig_Builtin16; | ||
| 810 | |||
| 811 | #if INT_MIN <= INT32_MIN | ||
| 812 | #define zig_builtin32(name, val) __builtin_##name(val) | ||
| 813 | typedef zig_c_uint zig_Builtin32; | ||
| 814 | #elif LONG_MIN <= INT32_MIN | ||
| 815 | #define zig_builtin32(name, val) __builtin_##name##l(val) | ||
| 816 | typedef zig_c_ulong zig_Builtin32; | ||
| 817 | #endif | ||
| 818 | |||
| 819 | #if INT_MIN <= INT64_MIN | ||
| 820 | #define zig_builtin64(name, val) __builtin_##name(val) | ||
| 821 | typedef zig_c_uint zig_Builtin64; | ||
| 822 | #elif LONG_MIN <= INT64_MIN | ||
| 823 | #define zig_builtin64(name, val) __builtin_##name##l(val) | ||
| 824 | typedef zig_c_ulong zig_Builtin64; | ||
| 825 | #elif LLONG_MIN <= INT64_MIN | ||
| 826 | #define zig_builtin64(name, val) __builtin_##name##ll(val) | ||
| 827 | typedef zig_c_ulonglong zig_Builtin64; | ||
| 828 | #endif | ||
| 829 | |||
| 830 | #if zig_has_builtin(clz) | ||
| 831 | #define zig_builtin_clz(w) \ | ||
| 832 | static inline zig_u8 zig_clz_u##w(zig_u##w val, zig_u8 bits) { \ | ||
| 833 | if (val == 0) return bits; \ | ||
| 834 | return zig_builtin##w(clz, val) - (zig_bitSizeOf(zig_Builtin##w) - bits); \ | ||
| 835 | } \ | ||
| 836 | \ | ||
| 837 | static inline zig_u8 zig_clz_i##w(zig_i##w val, zig_u8 bits) { \ | ||
| 838 | return zig_clz_u##w((zig_u##w)val, bits); \ | ||
| 839 | } | ||
| 840 | zig_builtin_clz(8) | ||
| 841 | zig_builtin_clz(16) | ||
| 842 | zig_builtin_clz(32) | ||
| 843 | zig_builtin_clz(64) | ||
| 844 | #endif | ||
| 845 | |||
| 846 | #if zig_has_builtin(ctz) | ||
| 847 | #define zig_builtin_ctz(w) \ | ||
| 848 | static inline zig_u8 zig_ctz_u##w(zig_u##w val, zig_u8 bits) { \ | ||
| 849 | if (val == 0) return bits; \ | ||
| 850 | return zig_builtin##w(ctz, val); \ | ||
| 851 | } \ | ||
| 852 | \ | ||
| 853 | static inline zig_u8 zig_ctz_i##w(zig_i##w val, zig_u8 bits) { \ | ||
| 854 | return zig_ctz_u##w((zig_u##w)val, bits); \ | ||
| 855 | } | ||
| 856 | zig_builtin_ctz(8) | ||
| 857 | zig_builtin_ctz(16) | ||
| 858 | zig_builtin_ctz(32) | ||
| 859 | zig_builtin_ctz(64) | ||
| 860 | #endif | ||
| 861 | |||
| 862 | #if zig_has_builtin(popcount) | ||
| 863 | #define zig_builtin_popcount(w) \ | ||
| 864 | static inline zig_u8 zig_popcount_u##w(zig_u##w val, zig_u8 bits) { \ | ||
| 865 | (void)bits; \ | ||
| 866 | return zig_builtin##w(popcount, val); \ | ||
| 867 | } \ | ||
| 868 | \ | ||
| 869 | static inline zig_u8 zig_popcount_i##w(zig_i##w val, zig_u8 bits) { \ | ||
| 870 | \ | ||
| 871 | return zig_popcount_u##w((zig_u##w)val, bits); \ | ||
| 872 | } | ||
| 873 | zig_builtin_popcount(8) | ||
| 874 | zig_builtin_popcount(16) | ||
| 875 | zig_builtin_popcount(32) | ||
| 876 | zig_builtin_popcount(64) | ||
| 877 | #endif | ||
| 878 | |||
| 879 | static inline zig_u8 zig_byte_swap_u8(zig_u8 val, zig_u8 bits) { | ||
| 880 | return zig_wrap_u8(val >> (8 - bits), bits); | ||
| 409 | } | 881 | } |
| 410 | 882 | ||
| 411 | static inline long long zig_subw_longlong(long long lhs, long long rhs, long long min, long long max) { | 883 | static inline zig_i8 zig_byte_swap_i8(zig_i8 val, zig_u8 bits) { |
| 412 | return (long long)(((unsigned long long)lhs) - ((unsigned long long)rhs)); | 884 | return zig_wrap_i8((zig_i8)zig_byte_swap_u8((zig_u8)val, bits), bits); |
| 413 | } | 885 | } |
| 414 | 886 | ||
| 415 | static inline bool zig_addo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) { | 887 | static inline zig_u16 zig_byte_swap_u16(zig_u16 val, zig_u8 bits) { |
| 416 | #if defined(__GNUC__) && INT8_MAX == INT_MAX | 888 | zig_u16 full_res; |
| 417 | if (min == INT8_MIN && max == INT8_MAX) { | 889 | #if zig_has_builtin(bswap16) |
| 418 | return __builtin_sadd_overflow(lhs, rhs, (int*)res); | 890 | full_res = __builtin_bswap16(val); |
| 419 | } | 891 | #else |
| 420 | #elif defined(__GNUC__) && INT8_MAX == LONG_MAX | 892 | full_res = (zig_u16)zig_byte_swap_u8((zig_u8)(val >> 0)) << 8 | |
| 421 | if (min == INT8_MIN && max == INT8_MAX) { | 893 | (zig_u16)zig_byte_swap_u8((zig_u8)(val >> 8)) >> 0; |
| 422 | return __builtin_saddl_overflow(lhs, rhs, (long*)res); | ||
| 423 | } | ||
| 424 | #elif defined(__GNUC__) && INT8_MAX == LLONG_MAX | ||
| 425 | if (min == INT8_MIN && max == INT8_MAX) { | ||
| 426 | return __builtin_saddll_overflow(lhs, rhs, (long long*)res); | ||
| 427 | } | ||
| 428 | #endif | 894 | #endif |
| 429 | int16_t big_result = (int16_t)lhs + (int16_t)rhs; | 895 | return zig_wrap_u16(full_res >> (16 - bits), bits); |
| 430 | if (big_result > max) { | ||
| 431 | *res = big_result - ((int16_t)max - (int16_t)min); | ||
| 432 | return true; | ||
| 433 | } | ||
| 434 | if (big_result < min) { | ||
| 435 | *res = big_result + ((int16_t)max - (int16_t)min); | ||
| 436 | return true; | ||
| 437 | } | ||
| 438 | *res = big_result; | ||
| 439 | return false; | ||
| 440 | } | 896 | } |
| 441 | 897 | ||
| 442 | static inline bool zig_addo_i16(int16_t lhs, int16_t rhs, int16_t *res, int16_t min, int16_t max) { | 898 | static inline zig_i16 zig_byte_swap_i16(zig_i16 val, zig_u8 bits) { |
| 443 | #if defined(__GNUC__) && INT16_MAX == INT_MAX | 899 | return zig_wrap_i16((zig_i16)zig_byte_swap_u16((zig_u16)val, bits), bits); |
| 444 | if (min == INT16_MIN && max == INT16_MAX) { | ||
| 445 | return __builtin_sadd_overflow(lhs, rhs, (int*)res); | ||
| 446 | } | ||
| 447 | #elif defined(__GNUC__) && INT16_MAX == LONG_MAX | ||
| 448 | if (min == INT16_MIN && max == INT16_MAX) { | ||
| 449 | return __builtin_saddl_overflow(lhs, rhs, (long*)res); | ||
| 450 | } | ||
| 451 | #elif defined(__GNUC__) && INT16_MAX == LLONG_MAX | ||
| 452 | if (min == INT16_MIN && max == INT16_MAX) { | ||
| 453 | return __builtin_saddll_overflow(lhs, rhs, (long long*)res); | ||
| 454 | } | ||
| 455 | #endif | ||
| 456 | int32_t big_result = (int32_t)lhs + (int32_t)rhs; | ||
| 457 | if (big_result > max) { | ||
| 458 | *res = big_result - ((int32_t)max - (int32_t)min); | ||
| 459 | return true; | ||
| 460 | } | ||
| 461 | if (big_result < min) { | ||
| 462 | *res = big_result + ((int32_t)max - (int32_t)min); | ||
| 463 | return true; | ||
| 464 | } | ||
| 465 | *res = big_result; | ||
| 466 | return false; | ||
| 467 | } | 900 | } |
| 468 | 901 | ||
| 469 | static inline bool zig_addo_i32(int32_t lhs, int32_t rhs, int32_t *res, int32_t min, int32_t max) { | 902 | static inline zig_u32 zig_byte_swap_u32(zig_u32 val, zig_u8 bits) { |
| 470 | #if defined(__GNUC__) && INT32_MAX == INT_MAX | 903 | zig_u32 full_res; |
| 471 | if (min == INT32_MIN && max == INT32_MAX) { | 904 | #if zig_has_builtin(bswap32) |
| 472 | return __builtin_sadd_overflow(lhs, rhs, (int*)res); | 905 | full_res = __builtin_bswap32(val); |
| 473 | } | ||
| 474 | #elif defined(__GNUC__) && INT32_MAX == LONG_MAX | ||
| 475 | if (min == INT32_MIN && max == INT32_MAX) { | ||
| 476 | return __builtin_saddl_overflow(lhs, rhs, (long*)res); | ||
| 477 | } | ||
| 478 | #elif defined(__GNUC__) && INT32_MAX == LLONG_MAX | ||
| 479 | if (min == INT32_MIN && max == INT32_MAX) { | ||
| 480 | return __builtin_saddll_overflow(lhs, rhs, (long long*)res); | ||
| 481 | } | ||
| 482 | #endif | ||
| 483 | int64_t big_result = (int64_t)lhs + (int64_t)rhs; | ||
| 484 | if (big_result > max) { | ||
| 485 | *res = big_result - ((int64_t)max - (int64_t)min); | ||
| 486 | return true; | ||
| 487 | } | ||
| 488 | if (big_result < min) { | ||
| 489 | *res = big_result + ((int64_t)max - (int64_t)min); | ||
| 490 | return true; | ||
| 491 | } | ||
| 492 | *res = big_result; | ||
| 493 | return false; | ||
| 494 | } | ||
| 495 | |||
| 496 | static inline bool zig_addo_i64(int64_t lhs, int64_t rhs, int64_t *res, int64_t min, int64_t max) { | ||
| 497 | bool overflow; | ||
| 498 | #if defined(__GNUC__) && INT64_MAX == INT_MAX | ||
| 499 | overflow = __builtin_sadd_overflow(lhs, rhs, (int*)res); | ||
| 500 | #elif defined(__GNUC__) && INT64_MAX == LONG_MAX | ||
| 501 | overflow = __builtin_saddl_overflow(lhs, rhs, (long*)res); | ||
| 502 | #elif defined(__GNUC__) && INT64_MAX == LLONG_MAX | ||
| 503 | overflow = __builtin_saddll_overflow(lhs, rhs, (long long*)res); | ||
| 504 | #else | 906 | #else |
| 505 | int int_overflow; | 907 | full_res = (zig_u32)zig_byte_swap_u16((zig_u16)(val >> 0)) << 16 | |
| 506 | *res = __addodi4(lhs, rhs, &int_overflow); | 908 | (zig_u32)zig_byte_swap_u16((zig_u16)(val >> 16)) >> 0; |
| 507 | overflow = int_overflow != 0; | 909 | #endif |
| 508 | #endif | 910 | return zig_wrap_u32(full_res >> (32 - bits), bits); |
| 509 | if (!overflow) { | ||
| 510 | if (*res > max) { | ||
| 511 | // TODO adjust the result to be the truncated bits | ||
| 512 | return true; | ||
| 513 | } else if (*res < min) { | ||
| 514 | // TODO adjust the result to be the truncated bits | ||
| 515 | return true; | ||
| 516 | } | ||
| 517 | } | ||
| 518 | return overflow; | ||
| 519 | } | 911 | } |
| 520 | 912 | ||
| 521 | static inline bool zig_addo_i128(int128_t lhs, int128_t rhs, int128_t *res, int128_t min, int128_t max) { | 913 | static inline zig_i32 zig_byte_swap_i32(zig_i32 val, zig_u8 bits) { |
| 522 | bool overflow; | 914 | return zig_wrap_i32((zig_i32)zig_byte_swap_u32((zig_u32)val, bits), bits); |
| 523 | #if defined(__GNUC__) && INT128_MAX == INT_MAX | ||
| 524 | overflow = __builtin_sadd_overflow(lhs, rhs, (int*)res); | ||
| 525 | #elif defined(__GNUC__) && INT128_MAX == LONG_MAX | ||
| 526 | overflow = __builtin_saddl_overflow(lhs, rhs, (long*)res); | ||
| 527 | #elif defined(__GNUC__) && INT128_MAX == LLONG_MAX | ||
| 528 | overflow = __builtin_saddll_overflow(lhs, rhs, (long long*)res); | ||
| 529 | #else | ||
| 530 | int int_overflow; | ||
| 531 | *res = __addoti4(lhs, rhs, &int_overflow); | ||
| 532 | overflow = int_overflow != 0; | ||
| 533 | #endif | ||
| 534 | if (!overflow) { | ||
| 535 | if (*res > max) { | ||
| 536 | // TODO adjust the result to be the truncated bits | ||
| 537 | return true; | ||
| 538 | } else if (*res < min) { | ||
| 539 | // TODO adjust the result to be the truncated bits | ||
| 540 | return true; | ||
| 541 | } | ||
| 542 | } | ||
| 543 | return overflow; | ||
| 544 | } | 915 | } |
| 545 | 916 | ||
| 546 | static inline bool zig_addo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t max) { | 917 | static inline zig_u64 zig_byte_swap_u64(zig_u64 val, zig_u8 bits) { |
| 547 | #if defined(__GNUC__) && UINT8_MAX == UINT_MAX | 918 | zig_u64 full_res; |
| 548 | if (max == UINT8_MAX) { | 919 | #if zig_has_builtin(bswap64) |
| 549 | return __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res); | 920 | full_res = __builtin_bswap64(val); |
| 550 | } | 921 | #else |
| 551 | #elif defined(__GNUC__) && UINT8_MAX == ULONG_MAX | 922 | full_res = (zig_u64)zig_byte_swap_u32((zig_u32)(val >> 0)) << 32 | |
| 552 | if (max == UINT8_MAX) { | 923 | (zig_u64)zig_byte_swap_u32((zig_u32)(val >> 32)) >> 0; |
| 553 | return __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res); | ||
| 554 | } | ||
| 555 | #elif defined(__GNUC__) && UINT8_MAX == ULLONG_MAX | ||
| 556 | if (max == UINT8_MAX) { | ||
| 557 | return __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res); | ||
| 558 | } | ||
| 559 | #endif | 924 | #endif |
| 560 | uint16_t big_result = (uint16_t)lhs + (uint16_t)rhs; | 925 | return zig_wrap_u64(full_res >> (64 - bits), bits); |
| 561 | if (big_result > max) { | ||
| 562 | *res = big_result - max - 1; | ||
| 563 | return true; | ||
| 564 | } | ||
| 565 | *res = big_result; | ||
| 566 | return false; | ||
| 567 | } | 926 | } |
| 568 | 927 | ||
| 569 | static inline uint16_t zig_addo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint16_t max) { | 928 | static inline zig_i64 zig_byte_swap_i64(zig_i64 val, zig_u8 bits) { |
| 570 | #if defined(__GNUC__) && UINT16_MAX == UINT_MAX | 929 | return zig_wrap_i64((zig_i64)zig_byte_swap_u64((zig_u64)val, bits), bits); |
| 571 | if (max == UINT16_MAX) { | ||
| 572 | return __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res); | ||
| 573 | } | ||
| 574 | #elif defined(__GNUC__) && UINT16_MAX == ULONG_MAX | ||
| 575 | if (max == UINT16_MAX) { | ||
| 576 | return __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res); | ||
| 577 | } | ||
| 578 | #elif defined(__GNUC__) && UINT16_MAX == ULLONG_MAX | ||
| 579 | if (max == UINT16_MAX) { | ||
| 580 | return __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res); | ||
| 581 | } | ||
| 582 | #endif | ||
| 583 | uint32_t big_result = (uint32_t)lhs + (uint32_t)rhs; | ||
| 584 | if (big_result > max) { | ||
| 585 | *res = big_result - max - 1; | ||
| 586 | return true; | ||
| 587 | } | ||
| 588 | *res = big_result; | ||
| 589 | return false; | ||
| 590 | } | 930 | } |
| 591 | 931 | ||
| 592 | static inline uint32_t zig_addo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint32_t max) { | 932 | static inline zig_u8 zig_bit_reverse_u8(zig_u8 val, zig_u8 bits) { |
| 593 | #if defined(__GNUC__) && UINT32_MAX == UINT_MAX | 933 | zig_u8 full_res; |
| 594 | if (max == UINT32_MAX) { | 934 | #if zig_has_builtin(bitreverse8) |
| 595 | return __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res); | 935 | full_res = __builtin_bitreverse8(val); |
| 596 | } | 936 | #else |
| 597 | #elif defined(__GNUC__) && UINT32_MAX == ULONG_MAX | 937 | static zig_u8 const lut[0x10] = { |
| 598 | if (max == UINT32_MAX) { | 938 | 0b0000, 0b1000, 0b0100, 0b1100, |
| 599 | return __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res); | 939 | 0b0010, 0b1010, 0b0110, 0b1110, |
| 600 | } | 940 | 0b0001, 0b1001, 0b0101, 0b1101, |
| 601 | #elif defined(__GNUC__) && UINT32_MAX == ULLONG_MAX | 941 | 0b0011, 0b1011, 0b0111, 0b1111, |
| 602 | if (max == UINT32_MAX) { | 942 | }; |
| 603 | return __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res); | 943 | full_res = lut[val >> 0 & 0xF] << 4 | lut[val >> 4 & 0xF] << 0; |
| 604 | } | ||
| 605 | #endif | 944 | #endif |
| 606 | uint64_t big_result = (uint64_t)lhs + (uint64_t)rhs; | 945 | return zig_wrap_u8(full_res >> (8 - bits), bits); |
| 607 | if (big_result > max) { | 946 | } |
| 608 | *res = big_result - max - 1; | 947 | |
| 609 | return true; | 948 | static inline zig_i8 zig_bit_reverse_i8(zig_i8 val, zig_u8 bits) { |
| 610 | } | 949 | return zig_wrap_i8((zig_i8)zig_bit_reverse_u8((zig_u8)val, bits), bits); |
| 611 | *res = big_result; | 950 | } |
| 612 | return false; | 951 | |
| 613 | } | 952 | static inline zig_u16 zig_bit_reverse_u16(zig_u16 val, zig_u8 bits) { |
| 614 | 953 | zig_u16 full_res; | |
| 615 | static inline uint64_t zig_addo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint64_t max) { | 954 | #if zig_has_builtin(bitreverse16) |
| 616 | bool overflow; | 955 | full_res = __builtin_bitreverse16(val); |
| 617 | #if defined(__GNUC__) && UINT64_MAX == UINT_MAX | ||
| 618 | overflow = __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res); | ||
| 619 | #elif defined(__GNUC__) && UINT64_MAX == ULONG_MAX | ||
| 620 | overflow = __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res); | ||
| 621 | #elif defined(__GNUC__) && UINT64_MAX == ULLONG_MAX | ||
| 622 | overflow = __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res); | ||
| 623 | #else | 956 | #else |
| 624 | int int_overflow; | 957 | full_res = (zig_u16)zig_bit_reverse_u8((zig_u8)(val >> 0)) << 8 | |
| 625 | *res = __uaddodi4(lhs, rhs, &int_overflow); | 958 | (zig_u16)zig_bit_reverse_u8((zig_u8)(val >> 8)) >> 0; |
| 626 | overflow = int_overflow != 0; | ||
| 627 | #endif | 959 | #endif |
| 628 | if (*res > max && !overflow) { | 960 | return zig_wrap_u16(full_res >> (16 - bits), bits); |
| 629 | *res -= max - 1; | ||
| 630 | return true; | ||
| 631 | } | ||
| 632 | return overflow; | ||
| 633 | } | 961 | } |
| 634 | 962 | ||
| 635 | static inline uint128_t zig_addo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) { | 963 | static inline zig_i16 zig_bit_reverse_i16(zig_i16 val, zig_u8 bits) { |
| 636 | int overflow; | 964 | return zig_wrap_i16((zig_i16)zig_bit_reverse_u16((zig_u16)val, bits), bits); |
| 637 | *res = __uaddoti4(lhs, rhs, &overflow); | ||
| 638 | if (*res > max && overflow == 0) { | ||
| 639 | *res -= max - 1; | ||
| 640 | return true; | ||
| 641 | } | ||
| 642 | return overflow != 0; | ||
| 643 | } | 965 | } |
| 644 | 966 | ||
| 645 | static inline bool zig_subo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) { | 967 | static inline zig_u32 zig_bit_reverse_u32(zig_u32 val, zig_u8 bits) { |
| 646 | #if defined(__GNUC__) && INT8_MAX == INT_MAX | 968 | zig_u32 full_res; |
| 647 | if (min == INT8_MIN && max == INT8_MAX) { | 969 | #if zig_has_builtin(bitreverse32) |
| 648 | return __builtin_ssub_overflow(lhs, rhs, (int*)res); | 970 | full_res = __builtin_bitreverse32(val); |
| 649 | } | 971 | #else |
| 650 | #elif defined(__GNUC__) && INT8_MAX == LONG_MAX | 972 | full_res = (zig_u32)zig_bit_reverse_u16((zig_u16)(val >> 0)) << 16 | |
| 651 | if (min == INT8_MIN && max == INT8_MAX) { | 973 | (zig_u32)zig_bit_reverse_u16((zig_u16)(val >> 16)) >> 0; |
| 652 | return __builtin_ssubl_overflow(lhs, rhs, (long*)res); | ||
| 653 | } | ||
| 654 | #elif defined(__GNUC__) && INT8_MAX == LLONG_MAX | ||
| 655 | if (min == INT8_MIN && max == INT8_MAX) { | ||
| 656 | return __builtin_ssubll_overflow(lhs, rhs, (long long*)res); | ||
| 657 | } | ||
| 658 | #endif | 974 | #endif |
| 659 | int16_t big_result = (int16_t)lhs - (int16_t)rhs; | 975 | return zig_wrap_u32(full_res >> (32 - bits), bits); |
| 660 | if (big_result > max) { | ||
| 661 | *res = big_result - ((int16_t)max - (int16_t)min); | ||
| 662 | return true; | ||
| 663 | } | ||
| 664 | if (big_result < min) { | ||
| 665 | *res = big_result + ((int16_t)max - (int16_t)min); | ||
| 666 | return true; | ||
| 667 | } | ||
| 668 | *res = big_result; | ||
| 669 | return false; | ||
| 670 | } | 976 | } |
| 671 | 977 | ||
| 672 | static inline bool zig_subo_i16(int16_t lhs, int16_t rhs, int16_t *res, int16_t min, int16_t max) { | 978 | static inline zig_i32 zig_bit_reverse_i32(zig_i32 val, zig_u8 bits) { |
| 673 | #if defined(__GNUC__) && INT16_MAX == INT_MAX | 979 | return zig_wrap_i32((zig_i32)zig_bit_reverse_u32((zig_u32)val, bits), bits); |
| 674 | if (min == INT16_MIN && max == INT16_MAX) { | 980 | } |
| 675 | return __builtin_ssub_overflow(lhs, rhs, (int*)res); | 981 | |
| 676 | } | 982 | static inline zig_u64 zig_bit_reverse_u64(zig_u64 val, zig_u8 bits) { |
| 677 | #elif defined(__GNUC__) && INT16_MAX == LONG_MAX | 983 | zig_u64 full_res; |
| 678 | if (min == INT16_MIN && max == INT16_MAX) { | 984 | #if zig_has_builtin(bitreverse64) |
| 679 | return __builtin_ssubl_overflow(lhs, rhs, (long*)res); | 985 | full_res = __builtin_bitreverse64(val); |
| 680 | } | 986 | #else |
| 681 | #elif defined(__GNUC__) && INT16_MAX == LLONG_MAX | 987 | full_res = (zig_u64)zig_bit_reverse_u32((zig_u32)(val >> 0)) << 32 | |
| 682 | if (min == INT16_MIN && max == INT16_MAX) { | 988 | (zig_u64)zig_bit_reverse_u32((zig_u32)(val >> 32)) >> 0; |
| 683 | return __builtin_ssubll_overflow(lhs, rhs, (long long*)res); | ||
| 684 | } | ||
| 685 | #endif | 989 | #endif |
| 686 | int32_t big_result = (int32_t)lhs - (int32_t)rhs; | 990 | return zig_wrap_u64(full_res >> (64 - bits), bits); |
| 687 | if (big_result > max) { | ||
| 688 | *res = big_result - ((int32_t)max - (int32_t)min); | ||
| 689 | return true; | ||
| 690 | } | ||
| 691 | if (big_result < min) { | ||
| 692 | *res = big_result + ((int32_t)max - (int32_t)min); | ||
| 693 | return true; | ||
| 694 | } | ||
| 695 | *res = big_result; | ||
| 696 | return false; | ||
| 697 | } | 991 | } |
| 698 | 992 | ||
| 699 | static inline bool zig_subo_i32(int32_t lhs, int32_t rhs, int32_t *res, int32_t min, int32_t max) { | 993 | static inline zig_i64 zig_bit_reverse_i64(zig_i64 val, zig_u8 bits) { |
| 700 | #if defined(__GNUC__) && INT32_MAX == INT_MAX | 994 | return zig_wrap_i64((zig_i64)zig_bit_reverse_u64((zig_u64)val, bits), bits); |
| 701 | if (min == INT32_MIN && max == INT32_MAX) { | 995 | } |
| 702 | return __builtin_ssub_overflow(lhs, rhs, (int*)res); | 996 | |
| 703 | } | 997 | /* ======================== 128-bit Integer Routines ======================== */ |
| 704 | #elif defined(__GNUC__) && INT32_MAX == LONG_MAX | 998 | |
| 705 | if (min == INT32_MIN && max == INT32_MAX) { | 999 | #if !defined(zig_has_int128) |
| 706 | return __builtin_ssubl_overflow(lhs, rhs, (long*)res); | 1000 | # if defined(__SIZEOF_INT128__) |
| 707 | } | 1001 | # define zig_has_int128 1 |
| 708 | #elif defined(__GNUC__) && INT32_MAX == LLONG_MAX | 1002 | # else |
| 709 | if (min == INT32_MIN && max == INT32_MAX) { | 1003 | # define zig_has_int128 0 |
| 710 | return __builtin_ssubll_overflow(lhs, rhs, (long long*)res); | 1004 | # endif |
| 711 | } | ||
| 712 | #endif | 1005 | #endif |
| 713 | int64_t big_result = (int64_t)lhs - (int64_t)rhs; | 1006 | |
| 714 | if (big_result > max) { | 1007 | #if zig_has_int128 |
| 715 | *res = big_result - ((int64_t)max - (int64_t)min); | 1008 | |
| 716 | return true; | 1009 | typedef unsigned __int128 zig_u128; |
| 1010 | typedef signed __int128 zig_i128; | ||
| 1011 | |||
| 1012 | #define zig_as_u128(hi, lo) ((zig_u128)(hi)<<64|(lo)) | ||
| 1013 | #define zig_as_i128(hi, lo) ((zig_i128)zig_as_u128(hi, lo)) | ||
| 1014 | #define zig_hi_u128(val) ((zig_u64)((val) >> 64)) | ||
| 1015 | #define zig_lo_u128(val) ((zig_u64)((val) >> 0)) | ||
| 1016 | #define zig_hi_i128(val) ((zig_i64)((val) >> 64)) | ||
| 1017 | #define zig_lo_i128(val) ((zig_u64)((val) >> 0)) | ||
| 1018 | #define zig_bitcast_u128(val) ((zig_u128)(val)) | ||
| 1019 | #define zig_bitcast_i128(val) ((zig_i128)(val)) | ||
| 1020 | #define zig_cmp_int128(Type) \ | ||
| 1021 | static inline zig_i8 zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \ | ||
| 1022 | return (lhs > rhs) - (lhs < rhs); \ | ||
| 717 | } | 1023 | } |
| 718 | if (big_result < min) { | 1024 | #define zig_bit_int128(Type, operation, operator) \ |
| 719 | *res = big_result + ((int64_t)max - (int64_t)min); | 1025 | static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ |
| 720 | return true; | 1026 | return lhs operator rhs; \ |
| 721 | } | 1027 | } |
| 722 | *res = big_result; | 1028 | |
| 723 | return false; | 1029 | #else /* zig_has_int128 */ |
| 724 | } | 1030 | |
| 725 | 1031 | #if __LITTLE_ENDIAN__ || _MSC_VER | |
| 726 | static inline bool zig_subo_i64(int64_t lhs, int64_t rhs, int64_t *res, int64_t min, int64_t max) { | 1032 | typedef struct { zig_align(16) zig_u64 lo; zig_u64 hi; } zig_u128; |
| 727 | bool overflow; | 1033 | typedef struct { zig_align(16) zig_u64 lo; zig_i64 hi; } zig_i128; |
| 728 | #if defined(__GNUC__) && INT64_MAX == INT_MAX | ||
| 729 | overflow = __builtin_ssub_overflow(lhs, rhs, (int*)res); | ||
| 730 | #elif defined(__GNUC__) && INT64_MAX == LONG_MAX | ||
| 731 | overflow = __builtin_ssubl_overflow(lhs, rhs, (long*)res); | ||
| 732 | #elif defined(__GNUC__) && INT64_MAX == LLONG_MAX | ||
| 733 | overflow = __builtin_ssubll_overflow(lhs, rhs, (long long*)res); | ||
| 734 | #else | 1034 | #else |
| 735 | int int_overflow; | 1035 | typedef struct { zig_align(16) zig_u64 hi; zig_u64 lo; } zig_u128; |
| 736 | *res = __subodi4(lhs, rhs, &int_overflow); | 1036 | typedef struct { zig_align(16) zig_i64 hi; zig_u64 lo; } zig_i128; |
| 737 | overflow = int_overflow != 0; | 1037 | #endif |
| 738 | #endif | 1038 | |
| 739 | if (!overflow) { | 1039 | #define zig_as_u128(hi, lo) ((zig_u128){ .h##i = (hi), .l##o = (lo) }) |
| 740 | if (*res > max) { | 1040 | #define zig_as_i128(hi, lo) ((zig_i128){ .h##i = (hi), .l##o = (lo) }) |
| 741 | // TODO adjust the result to be the truncated bits | 1041 | #define zig_hi_u128(val) ((val).hi) |
| 742 | return true; | 1042 | #define zig_lo_u128(val) ((val).lo) |
| 743 | } else if (*res < min) { | 1043 | #define zig_hi_i128(val) ((val).hi) |
| 744 | // TODO adjust the result to be the truncated bits | 1044 | #define zig_lo_i128(val) ((val).lo) |
| 745 | return true; | 1045 | #define zig_bitcast_u128(val) zig_as_u128((zig_u64)(val).hi, (val).lo) |
| 746 | } | 1046 | #define zig_bitcast_i128(val) zig_as_i128((zig_i64)(val).hi, (val).lo) |
| 1047 | #define zig_cmp_int128(Type) \ | ||
| 1048 | static inline zig_i8 zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \ | ||
| 1049 | return (lhs.hi == rhs.hi) \ | ||
| 1050 | ? (lhs.lo > rhs.lo) - (lhs.lo < rhs.lo) \ | ||
| 1051 | : (lhs.hi > rhs.hi) - (lhs.hi < rhs.hi); \ | ||
| 747 | } | 1052 | } |
| 748 | return overflow; | 1053 | #define zig_bit_int128(Type, operation, operator) \ |
| 1054 | static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \ | ||
| 1055 | return (zig_##Type){ .hi = lhs.hi operator rhs.hi, .lo = lhs.lo operator rhs.lo }; \ | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | #endif /* zig_has_int128 */ | ||
| 1059 | |||
| 1060 | #define zig_minInt_u128 zig_as_u128(zig_minInt_u64, zig_minInt_u64) | ||
| 1061 | #define zig_maxInt_u128 zig_as_u128(zig_maxInt_u64, zig_maxInt_u64) | ||
| 1062 | #define zig_minInt_i128 zig_as_i128(zig_minInt_i64, zig_minInt_u64) | ||
| 1063 | #define zig_maxInt_i128 zig_as_i128(zig_maxInt_i64, zig_maxInt_u64) | ||
| 1064 | |||
| 1065 | zig_cmp_int128(u128) | ||
| 1066 | zig_cmp_int128(i128) | ||
| 1067 | |||
| 1068 | zig_bit_int128(u128, and, &) | ||
| 1069 | zig_bit_int128(i128, and, &) | ||
| 1070 | |||
| 1071 | zig_bit_int128(u128, or, |) | ||
| 1072 | zig_bit_int128(i128, or, |) | ||
| 1073 | |||
| 1074 | zig_bit_int128(u128, xor, ^) | ||
| 1075 | zig_bit_int128(i128, xor, ^) | ||
| 1076 | |||
| 1077 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, zig_u8 rhs); | ||
| 1078 | |||
| 1079 | #if zig_has_int128 | ||
| 1080 | |||
| 1081 | static inline zig_u128 zig_not_u128(zig_u128 val, zig_u8 bits) { | ||
| 1082 | return val ^ zig_maxInt(u128, bits); | ||
| 749 | } | 1083 | } |
| 750 | 1084 | ||
| 751 | static inline bool zig_subo_i128(int128_t lhs, int128_t rhs, int128_t *res, int128_t min, int128_t max) { | 1085 | static inline zig_i128 zig_not_i128(zig_i128 val, zig_u8 bits) { |
| 752 | bool overflow; | 1086 | (void)bits; |
| 753 | #if defined(__GNUC__) && INT128_MAX == INT_MAX | 1087 | return ~val; |
| 754 | overflow = __builtin_ssub_overflow(lhs, rhs, (int*)res); | ||
| 755 | #elif defined(__GNUC__) && INT128_MAX == LONG_MAX | ||
| 756 | overflow = __builtin_ssubl_overflow(lhs, rhs, (long*)res); | ||
| 757 | #elif defined(__GNUC__) && INT128_MAX == LLONG_MAX | ||
| 758 | overflow = __builtin_ssubll_overflow(lhs, rhs, (long long*)res); | ||
| 759 | #else | ||
| 760 | int int_overflow; | ||
| 761 | *res = __suboti4(lhs, rhs, &int_overflow); | ||
| 762 | overflow = int_overflow != 0; | ||
| 763 | #endif | ||
| 764 | if (!overflow) { | ||
| 765 | if (*res > max) { | ||
| 766 | // TODO adjust the result to be the truncated bits | ||
| 767 | return true; | ||
| 768 | } else if (*res < min) { | ||
| 769 | // TODO adjust the result to be the truncated bits | ||
| 770 | return true; | ||
| 771 | } | ||
| 772 | } | ||
| 773 | return overflow; | ||
| 774 | } | 1088 | } |
| 775 | 1089 | ||
| 776 | static inline bool zig_subo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t max) { | 1090 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, zig_u8 rhs) { |
| 777 | #if defined(__GNUC__) && UINT8_MAX == UINT_MAX | 1091 | return lhs >> rhs; |
| 778 | return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res); | ||
| 779 | #elif defined(__GNUC__) && UINT8_MAX == ULONG_MAX | ||
| 780 | return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res); | ||
| 781 | #elif defined(__GNUC__) && UINT8_MAX == ULLONG_MAX | ||
| 782 | return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res); | ||
| 783 | #endif | ||
| 784 | if (rhs > lhs) { | ||
| 785 | *res = max - (rhs - lhs - 1); | ||
| 786 | return true; | ||
| 787 | } | ||
| 788 | *res = lhs - rhs; | ||
| 789 | return false; | ||
| 790 | } | 1092 | } |
| 791 | 1093 | ||
| 792 | static inline uint16_t zig_subo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint16_t max) { | 1094 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, zig_u8 rhs) { |
| 793 | #if defined(__GNUC__) && UINT16_MAX == UINT_MAX | 1095 | return lhs << rhs; |
| 794 | return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res); | ||
| 795 | #elif defined(__GNUC__) && UINT16_MAX == ULONG_MAX | ||
| 796 | return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res); | ||
| 797 | #elif defined(__GNUC__) && UINT16_MAX == ULLONG_MAX | ||
| 798 | return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res); | ||
| 799 | #endif | ||
| 800 | if (rhs > lhs) { | ||
| 801 | *res = max - (rhs - lhs - 1); | ||
| 802 | return true; | ||
| 803 | } | ||
| 804 | *res = lhs - rhs; | ||
| 805 | return false; | ||
| 806 | } | ||
| 807 | |||
| 808 | static inline uint32_t zig_subo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint32_t max) { | ||
| 809 | if (max == UINT32_MAX) { | ||
| 810 | #if defined(__GNUC__) && UINT32_MAX == UINT_MAX | ||
| 811 | return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res); | ||
| 812 | #elif defined(__GNUC__) && UINT32_MAX == ULONG_MAX | ||
| 813 | return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res); | ||
| 814 | #elif defined(__GNUC__) && UINT32_MAX == ULLONG_MAX | ||
| 815 | return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res); | ||
| 816 | #endif | ||
| 817 | int int_overflow; | ||
| 818 | *res = __usubosi4(lhs, rhs, &int_overflow); | ||
| 819 | return int_overflow != 0; | ||
| 820 | } else { | ||
| 821 | if (rhs > lhs) { | ||
| 822 | *res = max - (rhs - lhs - 1); | ||
| 823 | return true; | ||
| 824 | } | ||
| 825 | *res = lhs - rhs; | ||
| 826 | return false; | ||
| 827 | } | ||
| 828 | } | 1096 | } |
| 829 | 1097 | ||
| 830 | static inline uint64_t zig_subo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint64_t max) { | 1098 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, zig_u8 rhs) { |
| 831 | if (max == UINT64_MAX) { | 1099 | return lhs << rhs; |
| 832 | #if defined(__GNUC__) && UINT64_MAX == UINT_MAX | ||
| 833 | return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res); | ||
| 834 | #elif defined(__GNUC__) && UINT64_MAX == ULONG_MAX | ||
| 835 | return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res); | ||
| 836 | #elif defined(__GNUC__) && UINT64_MAX == ULLONG_MAX | ||
| 837 | return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res); | ||
| 838 | #else | ||
| 839 | int int_overflow; | ||
| 840 | *res = __usubodi4(lhs, rhs, &int_overflow); | ||
| 841 | return int_overflow != 0; | ||
| 842 | #endif | ||
| 843 | } else { | ||
| 844 | if (rhs > lhs) { | ||
| 845 | *res = max - (rhs - lhs - 1); | ||
| 846 | return true; | ||
| 847 | } | ||
| 848 | *res = lhs - rhs; | ||
| 849 | return false; | ||
| 850 | } | ||
| 851 | } | 1100 | } |
| 852 | 1101 | ||
| 853 | static inline uint128_t zig_subo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) { | 1102 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { |
| 854 | if (max == UINT128_MAX) { | 1103 | return lhs + rhs; |
| 855 | int int_overflow; | ||
| 856 | *res = __usuboti4(lhs, rhs, &int_overflow); | ||
| 857 | return int_overflow != 0; | ||
| 858 | } else { | ||
| 859 | if (rhs > lhs) { | ||
| 860 | *res = max - (rhs - lhs - 1); | ||
| 861 | return true; | ||
| 862 | } | ||
| 863 | *res = lhs - rhs; | ||
| 864 | return false; | ||
| 865 | } | ||
| 866 | } | 1104 | } |
| 867 | 1105 | ||
| 868 | static inline bool zig_mulo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) { | 1106 | static inline zig_i128 zig_add_i128(zig_i128 lhs, zig_i128 rhs) { |
| 869 | #if defined(__GNUC__) && INT8_MAX == INT_MAX | 1107 | return lhs + rhs; |
| 870 | if (min == INT8_MIN && max == INT8_MAX) { | ||
| 871 | return __builtin_smul_overflow(lhs, rhs, (int*)res); | ||
| 872 | } | ||
| 873 | #elif defined(__GNUC__) && INT8_MAX == LONG_MAX | ||
| 874 | if (min == INT8_MIN && max == INT8_MAX) { | ||
| 875 | return __builtin_smull_overflow(lhs, rhs, (long*)res); | ||
| 876 | } | ||
| 877 | #elif defined(__GNUC__) && INT8_MAX == LLONG_MAX | ||
| 878 | if (min == INT8_MIN && max == INT8_MAX) { | ||
| 879 | return __builtin_smulll_overflow(lhs, rhs, (long long*)res); | ||
| 880 | } | ||
| 881 | #endif | ||
| 882 | int16_t big_result = (int16_t)lhs * (int16_t)rhs; | ||
| 883 | if (big_result > max) { | ||
| 884 | *res = big_result - ((int16_t)max - (int16_t)min); | ||
| 885 | return true; | ||
| 886 | } | ||
| 887 | if (big_result < min) { | ||
| 888 | *res = big_result + ((int16_t)max - (int16_t)min); | ||
| 889 | return true; | ||
| 890 | } | ||
| 891 | *res = big_result; | ||
| 892 | return false; | ||
| 893 | } | 1108 | } |
| 894 | 1109 | ||
| 895 | static inline bool zig_mulo_i16(int16_t lhs, int16_t rhs, int16_t *res, int16_t min, int16_t max) { | 1110 | static inline zig_u128 zig_sub_u128(zig_u128 lhs, zig_u128 rhs) { |
| 896 | #if defined(__GNUC__) && INT16_MAX == INT_MAX | 1111 | return lhs - rhs; |
| 897 | if (min == INT16_MIN && max == INT16_MAX) { | ||
| 898 | return __builtin_smul_overflow(lhs, rhs, (int*)res); | ||
| 899 | } | ||
| 900 | #elif defined(__GNUC__) && INT16_MAX == LONG_MAX | ||
| 901 | if (min == INT16_MIN && max == INT16_MAX) { | ||
| 902 | return __builtin_smull_overflow(lhs, rhs, (long*)res); | ||
| 903 | } | ||
| 904 | #elif defined(__GNUC__) && INT16_MAX == LLONG_MAX | ||
| 905 | if (min == INT16_MIN && max == INT16_MAX) { | ||
| 906 | return __builtin_smulll_overflow(lhs, rhs, (long long*)res); | ||
| 907 | } | ||
| 908 | #endif | ||
| 909 | int32_t big_result = (int32_t)lhs * (int32_t)rhs; | ||
| 910 | if (big_result > max) { | ||
| 911 | *res = big_result - ((int32_t)max - (int32_t)min); | ||
| 912 | return true; | ||
| 913 | } | ||
| 914 | if (big_result < min) { | ||
| 915 | *res = big_result + ((int32_t)max - (int32_t)min); | ||
| 916 | return true; | ||
| 917 | } | ||
| 918 | *res = big_result; | ||
| 919 | return false; | ||
| 920 | } | 1112 | } |
| 921 | 1113 | ||
| 922 | static inline bool zig_mulo_i32(int32_t lhs, int32_t rhs, int32_t *res, int32_t min, int32_t max) { | 1114 | static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) { |
| 923 | #if defined(__GNUC__) && INT32_MAX == INT_MAX | 1115 | return lhs - rhs; |
| 924 | if (min == INT32_MIN && max == INT32_MAX) { | ||
| 925 | return __builtin_smul_overflow(lhs, rhs, (int*)res); | ||
| 926 | } | ||
| 927 | #elif defined(__GNUC__) && INT32_MAX == LONG_MAX | ||
| 928 | if (min == INT32_MIN && max == INT32_MAX) { | ||
| 929 | return __builtin_smull_overflow(lhs, rhs, (long*)res); | ||
| 930 | } | ||
| 931 | #elif defined(__GNUC__) && INT32_MAX == LLONG_MAX | ||
| 932 | if (min == INT32_MIN && max == INT32_MAX) { | ||
| 933 | return __builtin_smulll_overflow(lhs, rhs, (long long*)res); | ||
| 934 | } | ||
| 935 | #endif | ||
| 936 | int64_t big_result = (int64_t)lhs * (int64_t)rhs; | ||
| 937 | if (big_result > max) { | ||
| 938 | *res = big_result - ((int64_t)max - (int64_t)min); | ||
| 939 | return true; | ||
| 940 | } | ||
| 941 | if (big_result < min) { | ||
| 942 | *res = big_result + ((int64_t)max - (int64_t)min); | ||
| 943 | return true; | ||
| 944 | } | ||
| 945 | *res = big_result; | ||
| 946 | return false; | ||
| 947 | } | ||
| 948 | |||
| 949 | static inline bool zig_mulo_i64(int64_t lhs, int64_t rhs, int64_t *res, int64_t min, int64_t max) { | ||
| 950 | bool overflow; | ||
| 951 | #if defined(__GNUC__) && INT64_MAX == INT_MAX | ||
| 952 | overflow = __builtin_smul_overflow(lhs, rhs, (int*)res); | ||
| 953 | #elif defined(__GNUC__) && INT64_MAX == LONG_MAX | ||
| 954 | overflow = __builtin_smull_overflow(lhs, rhs, (long*)res); | ||
| 955 | #elif defined(__GNUC__) && INT64_MAX == LLONG_MAX | ||
| 956 | overflow = __builtin_smulll_overflow(lhs, rhs, (long long*)res); | ||
| 957 | #else | ||
| 958 | int int_overflow; | ||
| 959 | *res = __mulodi4(lhs, rhs, &int_overflow); | ||
| 960 | overflow = int_overflow != 0; | ||
| 961 | #endif | ||
| 962 | if (!overflow) { | ||
| 963 | if (*res > max) { | ||
| 964 | // TODO adjust the result to be the truncated bits | ||
| 965 | return true; | ||
| 966 | } else if (*res < min) { | ||
| 967 | // TODO adjust the result to be the truncated bits | ||
| 968 | return true; | ||
| 969 | } | ||
| 970 | } | ||
| 971 | return overflow; | ||
| 972 | } | 1116 | } |
| 973 | 1117 | ||
| 974 | static inline bool zig_mulo_i128(int128_t lhs, int128_t rhs, int128_t *res, int128_t min, int128_t max) { | 1118 | static inline zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) { |
| 975 | bool overflow; | 1119 | return lhs * rhs; |
| 976 | #if defined(__GNUC__) && INT128_MAX == INT_MAX | ||
| 977 | overflow = __builtin_smul_overflow(lhs, rhs, (int*)res); | ||
| 978 | #elif defined(__GNUC__) && INT128_MAX == LONG_MAX | ||
| 979 | overflow = __builtin_smull_overflow(lhs, rhs, (long*)res); | ||
| 980 | #elif defined(__GNUC__) && INT128_MAX == LLONG_MAX | ||
| 981 | overflow = __builtin_smulll_overflow(lhs, rhs, (long long*)res); | ||
| 982 | #else | ||
| 983 | int int_overflow; | ||
| 984 | *res = __muloti4(lhs, rhs, &int_overflow); | ||
| 985 | overflow = int_overflow != 0; | ||
| 986 | #endif | ||
| 987 | if (!overflow) { | ||
| 988 | if (*res > max) { | ||
| 989 | // TODO adjust the result to be the truncated bits | ||
| 990 | return true; | ||
| 991 | } else if (*res < min) { | ||
| 992 | // TODO adjust the result to be the truncated bits | ||
| 993 | return true; | ||
| 994 | } | ||
| 995 | } | ||
| 996 | return overflow; | ||
| 997 | } | 1120 | } |
| 998 | 1121 | ||
| 999 | static inline bool zig_mulo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t max) { | 1122 | static inline zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1000 | #if defined(__GNUC__) && UINT8_MAX == UINT_MAX | 1123 | return lhs * rhs; |
| 1001 | if (max == UINT8_MAX) { | ||
| 1002 | return __builtin_umul_overflow(lhs, rhs, (unsigned int*)res); | ||
| 1003 | } | ||
| 1004 | #elif defined(__GNUC__) && UINT8_MAX == ULONG_MAX | ||
| 1005 | if (max == UINT8_MAX) { | ||
| 1006 | return __builtin_umull_overflow(lhs, rhs, (unsigned long*)res); | ||
| 1007 | } | ||
| 1008 | #elif defined(__GNUC__) && UINT8_MAX == ULLONG_MAX | ||
| 1009 | if (max == UINT8_MAX) { | ||
| 1010 | return __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res); | ||
| 1011 | } | ||
| 1012 | #endif | ||
| 1013 | uint16_t big_result = (uint16_t)lhs * (uint16_t)rhs; | ||
| 1014 | if (big_result > max) { | ||
| 1015 | *res = big_result - max - 1; | ||
| 1016 | return true; | ||
| 1017 | } | ||
| 1018 | *res = big_result; | ||
| 1019 | return false; | ||
| 1020 | } | 1124 | } |
| 1021 | 1125 | ||
| 1022 | static inline uint16_t zig_mulo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint16_t max) { | 1126 | static inline zig_u128 zig_div_trunc_u128(zig_u128 lhs, zig_u128 rhs) { |
| 1023 | #if defined(__GNUC__) && UINT16_MAX == UINT_MAX | 1127 | return lhs / rhs; |
| 1024 | if (max == UINT16_MAX) { | ||
| 1025 | return __builtin_umul_overflow(lhs, rhs, (unsigned int*)res); | ||
| 1026 | } | ||
| 1027 | #elif defined(__GNUC__) && UINT16_MAX == ULONG_MAX | ||
| 1028 | if (max == UINT16_MAX) { | ||
| 1029 | return __builtin_umull_overflow(lhs, rhs, (unsigned long*)res); | ||
| 1030 | } | ||
| 1031 | #elif defined(__GNUC__) && UINT16_MAX == ULLONG_MAX | ||
| 1032 | if (max == UINT16_MAX) { | ||
| 1033 | return __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res); | ||
| 1034 | } | ||
| 1035 | #endif | ||
| 1036 | uint32_t big_result = (uint32_t)lhs * (uint32_t)rhs; | ||
| 1037 | if (big_result > max) { | ||
| 1038 | *res = big_result - max - 1; | ||
| 1039 | return true; | ||
| 1040 | } | ||
| 1041 | *res = big_result; | ||
| 1042 | return false; | ||
| 1043 | } | 1128 | } |
| 1044 | 1129 | ||
| 1045 | static inline uint32_t zig_mulo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint32_t max) { | 1130 | static inline zig_i128 zig_div_trunc_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1046 | #if defined(__GNUC__) && UINT32_MAX == UINT_MAX | 1131 | return lhs / rhs; |
| 1047 | if (max == UINT32_MAX) { | ||
| 1048 | return __builtin_umul_overflow(lhs, rhs, (unsigned int*)res); | ||
| 1049 | } | ||
| 1050 | #elif defined(__GNUC__) && UINT32_MAX == ULONG_MAX | ||
| 1051 | if (max == UINT32_MAX) { | ||
| 1052 | return __builtin_umull_overflow(lhs, rhs, (unsigned long*)res); | ||
| 1053 | } | ||
| 1054 | #elif defined(__GNUC__) && UINT32_MAX == ULLONG_MAX | ||
| 1055 | if (max == UINT32_MAX) { | ||
| 1056 | return __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res); | ||
| 1057 | } | ||
| 1058 | #endif | ||
| 1059 | uint64_t big_result = (uint64_t)lhs * (uint64_t)rhs; | ||
| 1060 | if (big_result > max) { | ||
| 1061 | *res = big_result - max - 1; | ||
| 1062 | return true; | ||
| 1063 | } | ||
| 1064 | *res = big_result; | ||
| 1065 | return false; | ||
| 1066 | } | ||
| 1067 | |||
| 1068 | static inline uint64_t zig_mulo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint64_t max) { | ||
| 1069 | bool overflow; | ||
| 1070 | #if defined(__GNUC__) && UINT64_MAX == UINT_MAX | ||
| 1071 | overflow = __builtin_umul_overflow(lhs, rhs, (unsigned int*)res); | ||
| 1072 | #elif defined(__GNUC__) && UINT64_MAX == ULONG_MAX | ||
| 1073 | overflow = __builtin_umull_overflow(lhs, rhs, (unsigned long*)res); | ||
| 1074 | #elif defined(__GNUC__) && UINT64_MAX == ULLONG_MAX | ||
| 1075 | overflow = __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res); | ||
| 1076 | #else | ||
| 1077 | int int_overflow; | ||
| 1078 | *res = __umulodi4(lhs, rhs, &int_overflow); | ||
| 1079 | overflow = int_overflow != 0; | ||
| 1080 | #endif | ||
| 1081 | if (*res > max && !overflow) { | ||
| 1082 | *res -= max - 1; | ||
| 1083 | return true; | ||
| 1084 | } | ||
| 1085 | return overflow; | ||
| 1086 | } | 1132 | } |
| 1087 | 1133 | ||
| 1088 | static inline uint128_t zig_mulo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) { | 1134 | static inline zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) { |
| 1089 | int overflow; | 1135 | return lhs % rhs; |
| 1090 | *res = __umuloti4(lhs, rhs, &overflow); | 1136 | } |
| 1091 | if (*res > max && overflow == 0) { | 1137 | |
| 1092 | *res -= max - 1; | 1138 | static inline zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1093 | return true; | 1139 | return lhs % rhs; |
| 1094 | } | 1140 | } |
| 1095 | return overflow != 0; | 1141 | |
| 1142 | static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) { | ||
| 1143 | return zig_div_trunc_i128(lhs, rhs) - (((lhs ^ rhs) & zig_rem_i128(lhs, rhs)) < zig_as_i128(0, 0)); | ||
| 1144 | } | ||
| 1145 | |||
| 1146 | static inline zig_i128 zig_mod_i128(zig_i128 lhs, zig_i128 rhs) { | ||
| 1147 | zig_i128 rem = zig_rem_i128(lhs, rhs); | ||
| 1148 | return rem + (((lhs ^ rhs) & rem) < zig_as_i128(0, 0) ? rhs : zig_as_i128(0, 0)); | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | #else /* zig_has_int128 */ | ||
| 1152 | |||
| 1153 | static inline zig_u128 zig_not_u128(zig_u128 val, zig_u8 bits) { | ||
| 1154 | return (zig_u128){ .hi = zig_not_u64(val.hi, bits - zig_as_u8(64)), .lo = zig_not_u64(val.lo, zig_as_u8(64)) }; | ||
| 1096 | } | 1155 | } |
| 1097 | 1156 | ||
| 1098 | static inline float zig_bitcast_f32_u32(uint32_t arg) { | 1157 | static inline zig_i128 zig_not_i128(zig_i128 val, zig_u8 bits) { |
| 1099 | float dest; | 1158 | return (zig_i128){ .hi = zig_not_i64(val.hi, bits - zig_as_u8(64)), .lo = zig_not_u64(val.lo, zig_as_u8(64)) }; |
| 1100 | memcpy(&dest, &arg, sizeof dest); | ||
| 1101 | return dest; | ||
| 1102 | } | ||
| 1103 | |||
| 1104 | static inline float zig_bitcast_f64_u64(uint64_t arg) { | ||
| 1105 | double dest; | ||
| 1106 | memcpy(&dest, &arg, sizeof dest); | ||
| 1107 | return dest; | ||
| 1108 | } | ||
| 1109 | |||
| 1110 | #define zig_add_sat_u(ZT, T) static inline T zig_adds_##ZT(T x, T y, T max) { \ | ||
| 1111 | return (x > max - y) ? max : x + y; \ | ||
| 1112 | } | ||
| 1113 | |||
| 1114 | #define zig_add_sat_s(ZT, T, T2) static inline T zig_adds_##ZT(T2 x, T2 y, T2 min, T2 max) { \ | ||
| 1115 | T2 res = x + y; \ | ||
| 1116 | return (res < min) ? min : (res > max) ? max : res; \ | ||
| 1117 | } | 1159 | } |
| 1118 | 1160 | ||
| 1119 | zig_add_sat_u( u8, uint8_t) | 1161 | static inline zig_u128 zig_shr_u128(zig_u128 lhs, zig_u8 rhs) { |
| 1120 | zig_add_sat_s( i8, int8_t, int16_t) | 1162 | if (rhs >= zig_as_u8(64)) return (zig_u128){ .hi = lhs.hi << (rhs - zig_as_u8(64)), .lo = zig_minInt_u64 }; |
| 1121 | zig_add_sat_u(u16, uint16_t) | 1163 | return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (zig_as_u8(64) - rhs), .lo = lhs.lo << rhs }; |
| 1122 | zig_add_sat_s(i16, int16_t, int32_t) | ||
| 1123 | zig_add_sat_u(u32, uint32_t) | ||
| 1124 | zig_add_sat_s(i32, int32_t, int64_t) | ||
| 1125 | zig_add_sat_u(u64, uint64_t) | ||
| 1126 | zig_add_sat_s(i64, int64_t, int128_t) | ||
| 1127 | zig_add_sat_s(isize, intptr_t, int128_t) | ||
| 1128 | zig_add_sat_s(short, short, int) | ||
| 1129 | zig_add_sat_s(int, int, long) | ||
| 1130 | zig_add_sat_s(long, long, long long) | ||
| 1131 | |||
| 1132 | #define zig_sub_sat_u(ZT, T) static inline T zig_subs_##ZT(T x, T y, T max) { \ | ||
| 1133 | return (x > max + y) ? max : x - y; \ | ||
| 1134 | } | 1164 | } |
| 1135 | 1165 | ||
| 1136 | #define zig_sub_sat_s(ZT, T, T2) static inline T zig_subs_##ZT(T2 x, T2 y, T2 min, T2 max) { \ | 1166 | static inline zig_u128 zig_shl_u128(zig_u128 lhs, zig_u8 rhs) { |
| 1137 | T2 res = x - y; \ | 1167 | if (rhs >= zig_as_u8(64)) return (zig_u128){ .hi = lhs.hi << (rhs - zig_as_u8(64)), .lo = zig_minInt_u64 }; |
| 1138 | return (res < min) ? min : (res > max) ? max : res; \ | 1168 | return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (zig_as_u8(64) - rhs), .lo = lhs.lo << rhs }; |
| 1139 | } | 1169 | } |
| 1140 | |||
| 1141 | zig_sub_sat_u( u8, uint8_t) | ||
| 1142 | zig_sub_sat_s( i8, int8_t, int16_t) | ||
| 1143 | zig_sub_sat_u(u16, uint16_t) | ||
| 1144 | zig_sub_sat_s(i16, int16_t, int32_t) | ||
| 1145 | zig_sub_sat_u(u32, uint32_t) | ||
| 1146 | zig_sub_sat_s(i32, int32_t, int64_t) | ||
| 1147 | zig_sub_sat_u(u64, uint64_t) | ||
| 1148 | zig_sub_sat_s(i64, int64_t, int128_t) | ||
| 1149 | zig_sub_sat_s(isize, intptr_t, int128_t) | ||
| 1150 | zig_sub_sat_s(short, short, int) | ||
| 1151 | zig_sub_sat_s(int, int, long) | ||
| 1152 | zig_sub_sat_s(long, long, long long) | ||
| 1153 | 1170 | ||
| 1171 | static inline zig_i128 zig_shl_i128(zig_i128 lhs, zig_u8 rhs) { | ||
| 1172 | if (rhs >= zig_as_u8(64)) return (zig_i128){ .hi = lhs.hi << (rhs - zig_as_u8(64)), .lo = zig_minInt_u64 }; | ||
| 1173 | return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (zig_as_u8(64) - rhs), .lo = lhs.lo << rhs }; | ||
| 1174 | } | ||
| 1175 | |||
| 1176 | static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) { | ||
| 1177 | zig_u128 res; | ||
| 1178 | res.hi = lhs.hi + rhs.hi + zig_addo_u64(&res.lo, lhs.lo, rhs.lo, zig_maxInt_u64); | ||
| 1179 | return res; | ||
| 1180 | } | ||
| 1154 | 1181 | ||
| 1155 | #define zig_mul_sat_u(ZT, T, T2) static inline T zig_muls_##ZT(T2 x, T2 y, T2 max) { \ | 1182 | static inline zig_i128 zig_add_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1156 | T2 res = x * y; \ | 1183 | zig_i128 res; |
| 1157 | return (res > max) ? max : res; \ | 1184 | res.hi = lhs.hi + rhs.hi + zig_addo_u64(&res.lo, lhs.lo, rhs.lo, zig_maxInt_u64); |
| 1185 | return res; | ||
| 1158 | } | 1186 | } |
| 1159 | 1187 | ||
| 1160 | #define zig_mul_sat_s(ZT, T, T2) static inline T zig_muls_##ZT(T2 x, T2 y, T2 min, T2 max) { \ | 1188 | static inline zig_u128 zig_sub_u128(zig_u128 lhs, zig_u128 rhs) { |
| 1161 | T2 res = x * y; \ | 1189 | zig_u128 res; |
| 1162 | return (res < min) ? min : (res > max) ? max : res; \ | 1190 | res.hi = lhs.hi - rhs.hi - zig_subo_u64(&res.lo, lhs.lo, rhs.lo, zig_maxInt_u64); |
| 1191 | return res; | ||
| 1163 | } | 1192 | } |
| 1164 | 1193 | ||
| 1165 | zig_mul_sat_u(u8, uint8_t, uint16_t) | 1194 | static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1166 | zig_mul_sat_s(i8, int8_t, int16_t) | 1195 | zig_i128 res; |
| 1167 | zig_mul_sat_u(u16, uint16_t, uint32_t) | 1196 | res.hi = lhs.hi - rhs.hi - zig_subo_u64(&res.lo, lhs.lo, rhs.lo, zig_maxInt_u64); |
| 1168 | zig_mul_sat_s(i16, int16_t, int32_t) | 1197 | return res; |
| 1169 | zig_mul_sat_u(u32, uint32_t, uint64_t) | 1198 | } |
| 1170 | zig_mul_sat_s(i32, int32_t, int64_t) | ||
| 1171 | zig_mul_sat_u(u64, uint64_t, uint128_t) | ||
| 1172 | zig_mul_sat_s(i64, int64_t, int128_t) | ||
| 1173 | zig_mul_sat_s(isize, intptr_t, int128_t) | ||
| 1174 | zig_mul_sat_s(short, short, int) | ||
| 1175 | zig_mul_sat_s(int, int, long) | ||
| 1176 | zig_mul_sat_s(long, long, long long) | ||
| 1177 | 1199 | ||
| 1178 | #define zig_shl_sat_u(ZT, T, bits) static inline T zig_shls_##ZT(T x, T y, T max) { \ | 1200 | static inline zig_i128 zig_div_floor_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1179 | if(x == 0) return 0; \ | 1201 | return zig_sub_i128(zig_div_trunc_i128(lhs, rhs), (((lhs.hi ^ rhs.hi) & zig_rem_i128(lhs, rhs).hi) < zig_as_i64(0)) ? zig_as_i128(0, 1) : zig_as_i128(0, 0)); |
| 1180 | T bits_set = 64 - __builtin_clzll(x); \ | ||
| 1181 | return (bits_set + y > bits) ? max : x << y; \ | ||
| 1182 | } | 1202 | } |
| 1183 | 1203 | ||
| 1184 | #define zig_shl_sat_s(ZT, T, bits) static inline T zig_shls_##ZT(T x, T y, T min, T max) { \ | 1204 | static inline zig_i128 zig_mod_i128(zig_i128 lhs, zig_i128 rhs) { |
| 1185 | if(x == 0) return 0; \ | 1205 | zig_i128 rem = zig_rem_i128(lhs, rhs); |
| 1186 | T x_twos_comp = x < 0 ? -x : x; \ | 1206 | return rem + (((lhs.hi ^ rhs.hi) & rem.hi) < zig_as_i64(0) ? rhs : zig_as_i128(0, 0)); |
| 1187 | T bits_set = 64 - __builtin_clzll(x_twos_comp); \ | ||
| 1188 | T min_or_max = (x < 0) ? min : max; \ | ||
| 1189 | return (y + bits_set > bits ) ? min_or_max : x << y; \ | ||
| 1190 | } | 1207 | } |
| 1191 | 1208 | ||
| 1192 | zig_shl_sat_u(u8, uint8_t, 8) | 1209 | #endif /* zig_has_int128 */ |
| 1193 | zig_shl_sat_s(i8, int8_t, 7) | ||
| 1194 | zig_shl_sat_u(u16, uint16_t, 16) | ||
| 1195 | zig_shl_sat_s(i16, int16_t, 15) | ||
| 1196 | zig_shl_sat_u(u32, uint32_t, 32) | ||
| 1197 | zig_shl_sat_s(i32, int32_t, 31) | ||
| 1198 | zig_shl_sat_u(u64, uint64_t, 64) | ||
| 1199 | zig_shl_sat_s(i64, int64_t, 63) | ||
| 1200 | zig_shl_sat_s(isize, intptr_t, ((sizeof(intptr_t)) * CHAR_BIT - 1)) | ||
| 1201 | zig_shl_sat_s(short, short, ((sizeof(short )) * CHAR_BIT - 1)) | ||
| 1202 | zig_shl_sat_s(int, int, ((sizeof(int )) * CHAR_BIT - 1)) | ||
| 1203 | zig_shl_sat_s(long, long, ((sizeof(long )) * CHAR_BIT - 1)) | ||
| 1204 | 1210 | ||
| 1205 | #define zig_bitsizeof(T) (CHAR_BIT * sizeof(T)) | 1211 | #define zig_div_floor_u128 zig_div_trunc_u128 |
| 1206 | #define zig_bit_mask(T, bit_width) \ | 1212 | #define zig_mod_u128 zig_rem_u128 |
| 1207 | ((bit_width) == zig_bitsizeof(T) \ | ||
| 1208 | ? ((T)-1) \ | ||
| 1209 | : (((T)1 << (T)(bit_width)) - 1)) | ||
| 1210 | 1213 | ||
| 1211 | static inline int zig_clz(unsigned int value, uint8_t zig_type_bit_width) { | 1214 | static inline zig_i128 zig_shr_i128(zig_i128 lhs, zig_u8 rhs) { |
| 1212 | if (value == 0) return zig_type_bit_width; | 1215 | zig_i128 sign_mask = zig_cmp_i128(lhs, zig_as_i128(0, 0)) < zig_as_i8(0) ? -zig_as_i128(0, 1) : zig_as_i128(0, 0); |
| 1213 | return __builtin_clz(value) - zig_bitsizeof(unsigned int) + zig_type_bit_width; | 1216 | return zig_xor_i128(zig_bitcast_i128(zig_shr_u128(zig_bitcast_u128(zig_xor_i128(lhs, sign_mask)), rhs)), sign_mask); |
| 1214 | } | 1217 | } |
| 1215 | 1218 | ||
| 1216 | static inline int zig_clzl(unsigned long value, uint8_t zig_type_bit_width) { | 1219 | static inline zig_u128 zig_wrap_u128(zig_u128 val, zig_u8 bits) { |
| 1217 | if (value == 0) return zig_type_bit_width; | 1220 | return zig_and_u128(val, zig_maxInt(u128, bits)); |
| 1218 | return __builtin_clzl(value) - zig_bitsizeof(unsigned long) + zig_type_bit_width; | ||
| 1219 | } | 1221 | } |
| 1220 | 1222 | ||
| 1221 | static inline int zig_clzll(unsigned long long value, uint8_t zig_type_bit_width) { | 1223 | static inline zig_i128 zig_wrap_i128(zig_i128 val, zig_u8 bits) { |
| 1222 | if (value == 0) return zig_type_bit_width; | 1224 | return zig_as_i128(zig_wrap_i64(zig_hi_i128(val), bits - zig_as_u8(64)), zig_lo_i128(val)); |
| 1223 | return __builtin_clzll(value) - zig_bitsizeof(unsigned long long) + zig_type_bit_width; | ||
| 1224 | } | 1225 | } |
| 1225 | 1226 | ||
| 1226 | #define zig_clz_u8 zig_clz | 1227 | static inline zig_u128 zig_shlw_u128(zig_u128 lhs, zig_u8 rhs, zig_u8 bits) { |
| 1227 | #define zig_clz_i8 zig_clz | 1228 | return zig_wrap_u128(zig_shl_u128(lhs, rhs), bits); |
| 1228 | #define zig_clz_u16 zig_clz | 1229 | } |
| 1229 | #define zig_clz_i16 zig_clz | ||
| 1230 | #define zig_clz_u32 zig_clzl | ||
| 1231 | #define zig_clz_i32 zig_clzl | ||
| 1232 | #define zig_clz_u64 zig_clzll | ||
| 1233 | #define zig_clz_i64 zig_clzll | ||
| 1234 | 1230 | ||
| 1235 | static inline int zig_clz_u128(uint128_t value, uint8_t zig_type_bit_width) { | 1231 | static inline zig_i128 zig_shlw_i128(zig_i128 lhs, zig_u8 rhs, zig_u8 bits) { |
| 1236 | if (value == 0) return zig_type_bit_width; | 1232 | return zig_wrap_i128(zig_bitcast_i128(zig_shl_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits); |
| 1237 | const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width); | ||
| 1238 | const uint64_t hi = (value & mask) >> 64; | ||
| 1239 | const uint64_t lo = (value & mask); | ||
| 1240 | const int leading_zeroes = ( | ||
| 1241 | hi != 0 ? __builtin_clzll(hi) : 64 + (lo != 0 ? __builtin_clzll(lo) : 64)); | ||
| 1242 | return leading_zeroes - zig_bitsizeof(uint128_t) + zig_type_bit_width; | ||
| 1243 | } | 1233 | } |
| 1244 | 1234 | ||
| 1245 | #define zig_clz_i128 zig_clz_u128 | 1235 | static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u8 rhs, zig_u8 bits) { |
| 1236 | return zig_wrap_u128(zig_add_u128(lhs, rhs), bits); | ||
| 1237 | } | ||
| 1246 | 1238 | ||
| 1247 | static inline int zig_ctz(unsigned int value, uint8_t zig_type_bit_width) { | 1239 | static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { |
| 1248 | if (value == 0) return zig_type_bit_width; | 1240 | return zig_wrap_i128(zig_bitcast_i128(zig_add_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits); |
| 1249 | return __builtin_ctz(value & zig_bit_mask(unsigned int, zig_type_bit_width)); | ||
| 1250 | } | 1241 | } |
| 1251 | 1242 | ||
| 1252 | static inline int zig_ctzl(unsigned long value, uint8_t zig_type_bit_width) { | 1243 | static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { |
| 1253 | if (value == 0) return zig_type_bit_width; | 1244 | return zig_wrap_u128(zig_sub_u128(lhs, rhs), bits); |
| 1254 | return __builtin_ctzl(value & zig_bit_mask(unsigned long, zig_type_bit_width)); | ||
| 1255 | } | 1245 | } |
| 1256 | 1246 | ||
| 1257 | static inline int zig_ctzll(unsigned long value, uint8_t zig_type_bit_width) { | 1247 | static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { |
| 1258 | if (value == 0) return zig_type_bit_width; | 1248 | return zig_wrap_i128(zig_bitcast_i128(zig_sub_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits); |
| 1259 | return __builtin_ctzll(value & zig_bit_mask(unsigned long, zig_type_bit_width)); | ||
| 1260 | } | 1249 | } |
| 1261 | 1250 | ||
| 1262 | #define zig_ctz_u8 zig_ctz | 1251 | static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { |
| 1263 | #define zig_ctz_i8 zig_ctz | 1252 | return zig_wrap_u128(zig_mul_u128(lhs, rhs), bits); |
| 1264 | #define zig_ctz_u16 zig_ctz | 1253 | } |
| 1265 | #define zig_ctz_i16 zig_ctz | ||
| 1266 | #define zig_ctz_u32 zig_ctzl | ||
| 1267 | #define zig_ctz_i32 zig_ctzl | ||
| 1268 | #define zig_ctz_u64 zig_ctzll | ||
| 1269 | #define zig_ctz_i64 zig_ctzll | ||
| 1270 | 1254 | ||
| 1271 | static inline int zig_ctz_u128(uint128_t value, uint8_t zig_type_bit_width) { | 1255 | static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { |
| 1272 | const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width); | 1256 | return zig_wrap_i128(zig_bitcast_i128(zig_mul_u128(zig_bitcast_u128(lhs), zig_bitcast_u128(rhs))), bits); |
| 1273 | const uint64_t hi = (value & mask) >> 64; | ||
| 1274 | const uint64_t lo = (value & mask); | ||
| 1275 | return (lo != 0 ? __builtin_ctzll(lo) : 64 + (hi != 0 ? __builtin_ctzll(hi) : 64)); | ||
| 1276 | } | 1257 | } |
| 1277 | 1258 | ||
| 1278 | #define zig_ctz_i128 zig_ctz_u128 | 1259 | #if zig_has_int128 |
| 1279 | 1260 | ||
| 1280 | static inline int zig_popcount(unsigned int value, uint8_t zig_type_bit_width) { | 1261 | static inline zig_bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, zig_u8 rhs, zig_u8 bits) { |
| 1281 | return __builtin_popcount(value & zig_bit_mask(unsigned int, zig_type_bit_width)); | 1262 | *res = zig_shlw_u128(lhs, rhs, bits); |
| 1263 | return zig_and_u128(lhs, zig_shl_u128(zig_maxInt_u128, bits - rhs)) != zig_as_u128(0, 0); | ||
| 1282 | } | 1264 | } |
| 1283 | 1265 | ||
| 1284 | static inline int zig_popcountl(unsigned long value, uint8_t zig_type_bit_width) { | 1266 | static inline zig_bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, zig_u8 rhs, zig_u8 bits) { |
| 1285 | return __builtin_popcountl(value & zig_bit_mask(unsigned long, zig_type_bit_width)); | 1267 | *res = zig_shlw_i128(lhs, rhs, bits); |
| 1268 | zig_i128 mask = zig_bitcast_i128(zig_shl_u128(zig_maxInt_u128, bits - rhs - zig_as_u8(1))); | ||
| 1269 | return zig_cmp_i128(zig_and_i128(lhs, mask), zig_as_i128(0, 0)) != zig_as_i8(0) && | ||
| 1270 | zig_cmp_i128(zig_and_i128(lhs, mask), mask) != zig_as_i8(0); | ||
| 1286 | } | 1271 | } |
| 1287 | 1272 | ||
| 1288 | static inline int zig_popcountll(unsigned long value, uint8_t zig_type_bit_width) { | 1273 | static inline zig_bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { |
| 1289 | return __builtin_popcountll(value & zig_bit_mask(unsigned long, zig_type_bit_width)); | 1274 | #if zig_has_builtin(add_overflow) |
| 1275 | zig_u128 full_res; | ||
| 1276 | zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); | ||
| 1277 | *res = zig_wrap_u128(full_res, bits); | ||
| 1278 | return overflow || full_res < zig_minInt(u128, bits) || full_res > zig_maxInt(u128, bits); | ||
| 1279 | #else | ||
| 1280 | *res = zig_addw_u128(lhs, rhs, bits); | ||
| 1281 | return *res < lhs; | ||
| 1282 | #endif | ||
| 1290 | } | 1283 | } |
| 1291 | 1284 | ||
| 1292 | #define zig_popcount_u8 zig_popcount | 1285 | zig_extern_c zig_i128 __addoti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow); |
| 1293 | #define zig_popcount_i8 zig_popcount | 1286 | static inline zig_bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { |
| 1294 | #define zig_popcount_u16 zig_popcount | 1287 | #if zig_has_builtin(add_overflow) |
| 1295 | #define zig_popcount_i16 zig_popcount | 1288 | zig_i128 full_res; |
| 1296 | #define zig_popcount_u32 zig_popcountl | 1289 | zig_bool overflow = __builtin_add_overflow(lhs, rhs, &full_res); |
| 1297 | #define zig_popcount_i32 zig_popcountl | 1290 | #else |
| 1298 | #define zig_popcount_u64 zig_popcountll | 1291 | zig_c_int overflow_int; |
| 1299 | #define zig_popcount_i64 zig_popcountll | 1292 | zig_i128 full_res = __addoti4(lhs, rhs, &overflow_int); |
| 1293 | zig_bool overflow = overflow_int != 0; | ||
| 1294 | #endif | ||
| 1295 | *res = zig_wrap_i128(full_res, bits); | ||
| 1296 | return overflow || full_res < zig_minInt(i128, bits) || full_res > zig_maxInt(i128, bits); | ||
| 1297 | } | ||
| 1300 | 1298 | ||
| 1301 | static inline int zig_popcount_u128(uint128_t value, uint8_t zig_type_bit_width) { | 1299 | static inline zig_bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { |
| 1302 | const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width); | 1300 | #if zig_has_builtin(sub_overflow) |
| 1303 | const uint64_t hi = (value & mask) >> 64; | 1301 | zig_u128 full_res; |
| 1304 | const uint64_t lo = (value & mask); | 1302 | zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); |
| 1305 | return __builtin_popcountll(hi) + __builtin_popcountll(lo); | 1303 | *res = zig_wrap_u128(full_res, bits); |
| 1304 | return overflow || full_res < zig_minInt(u128, bits) || full_res > zig_maxInt(u128, bits); | ||
| 1305 | #else | ||
| 1306 | *res = zig_subw_u128(lhs, rhs, bits); | ||
| 1307 | return *res > lhs; | ||
| 1308 | #endif | ||
| 1306 | } | 1309 | } |
| 1307 | 1310 | ||
| 1308 | #define zig_popcount_i128 zig_popcount_u128 | 1311 | zig_extern_c zig_i128 __suboti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow); |
| 1312 | static inline zig_bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { | ||
| 1313 | #if zig_has_builtin(sub_overflow) | ||
| 1314 | zig_i128 full_res; | ||
| 1315 | zig_bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res); | ||
| 1316 | #else | ||
| 1317 | zig_c_int overflow_int; | ||
| 1318 | zig_i128 full_res = __suboti4(lhs, rhs, &overflow_int); | ||
| 1319 | zig_bool overflow = overflow_int != 0; | ||
| 1320 | #endif | ||
| 1321 | *res = zig_wrap_i128(full_res, bits); | ||
| 1322 | return overflow || full_res < zig_minInt(i128, bits) || full_res > zig_maxInt(i128, bits); | ||
| 1323 | } | ||
| 1309 | 1324 | ||
| 1310 | static inline bool zig_shlo_i8(int8_t lhs, int8_t rhs, int8_t *res, uint8_t bits) { | 1325 | static inline zig_bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { |
| 1311 | *res = lhs << rhs; | 1326 | #if zig_has_builtin(mul_overflow) |
| 1312 | if (zig_clz_i8(lhs, bits) >= rhs) return false; | 1327 | zig_u128 full_res; |
| 1313 | *res &= UINT8_MAX >> (8 - bits); | 1328 | zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1314 | return true; | 1329 | *res = zig_wrap_u128(full_res, bits); |
| 1330 | return overflow || full_res < zig_minInt(u128, bits) || full_res > zig_maxInt(u128, bits); | ||
| 1331 | #else | ||
| 1332 | *res = zig_mulw_u128(lhs, rhs, bits); | ||
| 1333 | return rhs != zig_as_u128(0, 0) && lhs > zig_maxInt(u128, bits) / rhs; | ||
| 1334 | #endif | ||
| 1315 | } | 1335 | } |
| 1316 | 1336 | ||
| 1317 | static inline bool zig_shlo_i16(int16_t lhs, int16_t rhs, int16_t *res, uint8_t bits) { | 1337 | zig_extern_c zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, zig_c_int *overflow); |
| 1318 | *res = lhs << rhs; | 1338 | static inline zig_bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { |
| 1319 | if (zig_clz_i16(lhs, bits) >= rhs) return false; | 1339 | #if zig_has_builtin(mul_overflow) |
| 1320 | *res &= UINT16_MAX >> (16 - bits); | 1340 | zig_i128 full_res; |
| 1321 | return true; | 1341 | zig_bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res); |
| 1342 | #else | ||
| 1343 | zig_c_int overflow_int; | ||
| 1344 | zig_i128 full_res = __muloti4(lhs, rhs, &overflow); | ||
| 1345 | zig_bool overflow = overflow_int != 0; | ||
| 1346 | #endif | ||
| 1347 | *res = zig_wrap_i128(full_res, bits); | ||
| 1348 | return overflow || full_res < zig_minInt(i128, bits) || full_res > zig_maxInt(i128, bits); | ||
| 1322 | } | 1349 | } |
| 1323 | 1350 | ||
| 1324 | static inline bool zig_shlo_i32(int32_t lhs, int32_t rhs, int32_t *res, uint8_t bits) { | 1351 | #else /* zig_has_int128 */ |
| 1325 | *res = lhs << rhs; | 1352 | |
| 1326 | if (zig_clz_i32(lhs, bits) >= rhs) return false; | 1353 | static inline zig_bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs) { |
| 1327 | *res &= UINT32_MAX >> (32 - bits); | 1354 | return zig_addo_u64(&res->hi, lhs.hi, rhs.hi, UINT64_MAX) | |
| 1328 | return true; | 1355 | zig_addo_u64(&res->hi, res->hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT64_MAX)); |
| 1329 | } | 1356 | } |
| 1330 | 1357 | ||
| 1331 | static inline bool zig_shlo_i64(int64_t lhs, int64_t rhs, int64_t *res, uint8_t bits) { | 1358 | static inline zig_bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs) { |
| 1332 | *res = lhs << rhs; | 1359 | return zig_subo_u64(&res->hi, lhs.hi, rhs.hi, UINT64_MAX) | |
| 1333 | if (zig_clz_i64(lhs, bits) >= rhs) return false; | 1360 | zig_subo_u64(&res->hi, res->hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT64_MAX)); |
| 1334 | *res &= UINT64_MAX >> (64 - bits); | ||
| 1335 | return true; | ||
| 1336 | } | 1361 | } |
| 1337 | 1362 | ||
| 1338 | static inline bool zig_shlo_i128(int128_t lhs, int128_t rhs, int128_t *res, uint8_t bits) { | 1363 | #endif /* zig_has_int128 */ |
| 1339 | *res = lhs << rhs; | 1364 | |
| 1340 | if (zig_clz_i128(lhs, bits) >= rhs) return false; | 1365 | static inline zig_u128 zig_shls_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { |
| 1341 | *res &= UINT128_MAX >> (128 - bits); | 1366 | zig_u128 res; |
| 1342 | return true; | 1367 | if (zig_cmp_u128(rhs, zig_as_u128(0, bits)) >= zig_as_i8(0)) |
| 1368 | return zig_cmp_u128(lhs, zig_as_u128(0, 0)) != zig_as_i8(0) ? zig_maxInt(u128, bits) : lhs; | ||
| 1369 | return zig_shlo_u128(&res, lhs, (zig_u8)rhs, bits) ? zig_maxInt(u128, bits) : res; | ||
| 1343 | } | 1370 | } |
| 1344 | 1371 | ||
| 1345 | static inline bool zig_shlo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t bits) { | 1372 | static inline zig_i128 zig_shls_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { |
| 1346 | *res = lhs << rhs; | 1373 | zig_i128 res; |
| 1347 | if (zig_clz_u8(lhs, bits) >= rhs) return false; | 1374 | if (zig_cmp_u128(zig_bitcast_u128(rhs), zig_as_u128(0, bits)) < zig_as_i8(0) && !zig_shlo_i128(&res, lhs, rhs, bits)) return res; |
| 1348 | *res &= UINT8_MAX >> (8 - bits); | 1375 | return zig_cmp_i128(lhs, zig_as_i128(0, 0)) < zig_as_i8(0) ? zig_minInt(i128, bits) : zig_maxInt(i128, bits); |
| 1349 | return true; | ||
| 1350 | } | 1376 | } |
| 1351 | 1377 | ||
| 1352 | static inline uint16_t zig_shlo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint8_t bits) { | 1378 | static inline zig_u128 zig_adds_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { |
| 1353 | *res = lhs << rhs; | 1379 | zig_u128 res; |
| 1354 | if (zig_clz_u16(lhs, bits) >= rhs) return false; | 1380 | return zig_addo_u128(&res, lhs, rhs, bits) ? zig_maxInt(u128, bits) : res; |
| 1355 | *res &= UINT16_MAX >> (16 - bits); | ||
| 1356 | return true; | ||
| 1357 | } | 1381 | } |
| 1358 | 1382 | ||
| 1359 | static inline uint32_t zig_shlo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint8_t bits) { | 1383 | static inline zig_i128 zig_adds_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { |
| 1360 | *res = lhs << rhs; | 1384 | zig_i128 res; |
| 1361 | if (zig_clz_u32(lhs, bits) >= rhs) return false; | 1385 | if (!zig_addo_i128(&res, lhs, rhs, bits)) return res; |
| 1362 | *res &= UINT32_MAX >> (32 - bits); | 1386 | return zig_cmp_i128(res, zig_as_i128(0, 0)) >= zig_as_i8(0) ? zig_minInt(i128, bits) : zig_maxInt(i128, bits); |
| 1363 | return true; | ||
| 1364 | } | 1387 | } |
| 1365 | 1388 | ||
| 1366 | static inline uint64_t zig_shlo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint8_t bits) { | 1389 | static inline zig_u128 zig_subs_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { |
| 1367 | *res = lhs << rhs; | 1390 | zig_u128 res; |
| 1368 | if (zig_clz_u64(lhs, bits) >= rhs) return false; | 1391 | return zig_subo_u128(&res, lhs, rhs, bits) ? zig_minInt(u128, bits) : res; |
| 1369 | *res &= UINT64_MAX >> (64 - bits); | ||
| 1370 | return true; | ||
| 1371 | } | 1392 | } |
| 1372 | 1393 | ||
| 1373 | static inline uint128_t zig_shlo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint8_t bits) { | 1394 | static inline zig_i128 zig_subs_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { |
| 1374 | *res = lhs << rhs; | 1395 | zig_i128 res; |
| 1375 | if (zig_clz_u128(lhs, bits) >= rhs) return false; | 1396 | if (!zig_subo_i128(&res, lhs, rhs, bits)) return res; |
| 1376 | *res &= UINT128_MAX >> (128 - bits); | 1397 | return zig_cmp_i128(res, zig_as_i128(0, 0)) >= zig_as_i8(0) ? zig_minInt(i128, bits) : zig_maxInt(i128, bits); |
| 1377 | return true; | ||
| 1378 | } | 1398 | } |
| 1379 | 1399 | ||
| 1380 | #define zig_sign_extend(T) \ | 1400 | static inline zig_u128 zig_muls_u128(zig_u128 lhs, zig_u128 rhs, zig_u8 bits) { |
| 1381 | static inline T zig_sign_extend_##T(T value, uint8_t zig_type_bit_width) { \ | 1401 | zig_u128 res; |
| 1382 | const T m = (T)1 << (T)(zig_type_bit_width - 1); \ | 1402 | return zig_mulo_u128(&res, lhs, rhs, bits) ? zig_maxInt(u128, bits) : res; |
| 1383 | return (value ^ m) - m; \ | 1403 | } |
| 1384 | } | ||
| 1385 | 1404 | ||
| 1386 | zig_sign_extend(uint8_t) | 1405 | static inline zig_i128 zig_muls_i128(zig_i128 lhs, zig_i128 rhs, zig_u8 bits) { |
| 1387 | zig_sign_extend(uint16_t) | 1406 | zig_i128 res; |
| 1388 | zig_sign_extend(uint32_t) | 1407 | if (!zig_mulo_i128(&res, lhs, rhs, bits)) return res; |
| 1389 | zig_sign_extend(uint64_t) | 1408 | return zig_cmp_i128(zig_xor_i128(lhs, rhs), zig_as_i128(0, 0)) < zig_as_i8(0) ? zig_minInt(i128, bits) : zig_maxInt(i128, bits); |
| 1390 | zig_sign_extend(uint128_t) | 1409 | } |
| 1391 | 1410 | ||
| 1392 | #define zig_byte_swap_u(ZigTypeBits, CTypeBits) \ | 1411 | static inline zig_u8 zig_clz_u128(zig_u128 val, zig_u8 bits) { |
| 1393 | static inline uint##CTypeBits##_t zig_byte_swap_u##ZigTypeBits(uint##CTypeBits##_t value, uint8_t zig_type_bit_width) { \ | 1412 | if (zig_hi_u128(val) != 0) return zig_clz_u64(zig_hi_u128(val), bits - zig_as_u8(64)); |
| 1394 | return __builtin_bswap##CTypeBits(value) >> (CTypeBits - zig_type_bit_width); \ | 1413 | return zig_clz_u64(zig_lo_u128(val), zig_as_u8(64)) + zig_as_u8(64); |
| 1395 | } | 1414 | } |
| 1396 | 1415 | ||
| 1397 | #define zig_byte_swap_s(ZigTypeBits, CTypeBits) \ | 1416 | static inline zig_u8 zig_clz_i128(zig_i128 val, zig_u8 bits) { |
| 1398 | static inline int##CTypeBits##_t zig_byte_swap_i##ZigTypeBits(int##CTypeBits##_t value, uint8_t zig_type_bit_width) { \ | 1417 | return zig_clz_u128(zig_bitcast_u128(val), bits); |
| 1399 | const uint##CTypeBits##_t swapped = zig_byte_swap_u##ZigTypeBits(value, zig_type_bit_width); \ | 1418 | } |
| 1400 | return zig_sign_extend_uint##CTypeBits##_t(swapped, zig_type_bit_width); \ | ||
| 1401 | } | ||
| 1402 | 1419 | ||
| 1403 | #define zig_byte_swap(ZigTypeBits, CTypeBits) \ | 1420 | static inline zig_u8 zig_ctz_u128(zig_u128 val, zig_u8 bits) { |
| 1404 | zig_byte_swap_u(ZigTypeBits, CTypeBits) \ | 1421 | if (zig_lo_u128(val) != 0) return zig_ctz_u64(zig_lo_u128(val), zig_as_u8(64)); |
| 1405 | zig_byte_swap_s(ZigTypeBits, CTypeBits) | 1422 | return zig_ctz_u64(zig_hi_u128(val), bits - zig_as_u8(64)) + zig_as_u8(64); |
| 1406 | 1423 | } | |
| 1407 | zig_byte_swap( 8, 16) | ||
| 1408 | zig_byte_swap(16, 16) | ||
| 1409 | zig_byte_swap(32, 32) | ||
| 1410 | zig_byte_swap(64, 64) | ||
| 1411 | |||
| 1412 | static inline uint128_t zig_byte_swap_u128(uint128_t value, uint8_t zig_type_bit_width) { | ||
| 1413 | const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width); | ||
| 1414 | const uint128_t hi = __builtin_bswap64((uint64_t)(value >> 64)); | ||
| 1415 | const uint128_t lo = __builtin_bswap64((uint64_t)value); | ||
| 1416 | return (((lo << 64 | hi) >> (128 - zig_type_bit_width))) & mask; | ||
| 1417 | } | ||
| 1418 | |||
| 1419 | zig_byte_swap_s(128, 128) | ||
| 1420 | |||
| 1421 | static const uint8_t zig_bit_reverse_lut[256] = { | ||
| 1422 | 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, | ||
| 1423 | 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, | ||
| 1424 | 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, | ||
| 1425 | 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, | ||
| 1426 | 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc, | ||
| 1427 | 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, | ||
| 1428 | 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, | ||
| 1429 | 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, | ||
| 1430 | 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, | ||
| 1431 | 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, | ||
| 1432 | 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, | ||
| 1433 | 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, | ||
| 1434 | 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9, | ||
| 1435 | 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, | ||
| 1436 | 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, | ||
| 1437 | 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, | ||
| 1438 | 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, | ||
| 1439 | 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, | ||
| 1440 | 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, | ||
| 1441 | 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, | ||
| 1442 | 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, | ||
| 1443 | 0x3f, 0xbf, 0x7f, 0xff | ||
| 1444 | }; | ||
| 1445 | |||
| 1446 | static inline uint8_t zig_bit_reverse_u8(uint8_t value, uint8_t zig_type_bit_width) { | ||
| 1447 | const uint8_t reversed = zig_bit_reverse_lut[value] >> (8 - zig_type_bit_width); | ||
| 1448 | return zig_sign_extend_uint8_t(reversed, zig_type_bit_width); | ||
| 1449 | } | ||
| 1450 | |||
| 1451 | #define zig_bit_reverse_i8 zig_bit_reverse_u8 | ||
| 1452 | |||
| 1453 | static inline uint16_t zig_bit_reverse_u16(uint16_t value, uint8_t zig_type_bit_width) { | ||
| 1454 | const uint16_t swapped = zig_byte_swap_u16(value, zig_type_bit_width); | ||
| 1455 | const uint16_t reversed = ( | ||
| 1456 | ((uint16_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) | | ||
| 1457 | ((uint16_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00)); | ||
| 1458 | return zig_sign_extend_uint16_t( | ||
| 1459 | reversed & zig_bit_mask(uint16_t, zig_type_bit_width), | ||
| 1460 | zig_type_bit_width); | ||
| 1461 | } | ||
| 1462 | |||
| 1463 | #define zig_bit_reverse_i16 zig_bit_reverse_u16 | ||
| 1464 | |||
| 1465 | static inline uint32_t zig_bit_reverse_u32(uint32_t value, uint8_t zig_type_bit_width) { | ||
| 1466 | const uint32_t swapped = zig_byte_swap_u32(value, zig_type_bit_width); | ||
| 1467 | const uint32_t reversed = ( | ||
| 1468 | ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x18) & 0xff] << 0x18) | | ||
| 1469 | ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x10) & 0xff] << 0x10) | | ||
| 1470 | ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) | | ||
| 1471 | ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00)); | ||
| 1472 | return zig_sign_extend_uint32_t( | ||
| 1473 | reversed & zig_bit_mask(uint32_t, zig_type_bit_width), | ||
| 1474 | zig_type_bit_width); | ||
| 1475 | } | ||
| 1476 | |||
| 1477 | #define zig_bit_reverse_i32 zig_bit_reverse_u32 | ||
| 1478 | |||
| 1479 | static inline uint64_t zig_bit_reverse_u64(uint64_t value, uint8_t zig_type_bit_width) { | ||
| 1480 | const uint64_t swapped = zig_byte_swap_u64(value, zig_type_bit_width); | ||
| 1481 | const uint64_t reversed = ( | ||
| 1482 | ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x38) & 0xff] << 0x38) | | ||
| 1483 | ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x30) & 0xff] << 0x30) | | ||
| 1484 | ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x28) & 0xff] << 0x28) | | ||
| 1485 | ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x20) & 0xff] << 0x20) | | ||
| 1486 | ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x18) & 0xff] << 0x18) | | ||
| 1487 | ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x10) & 0xff] << 0x10) | | ||
| 1488 | ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) | | ||
| 1489 | ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00)); | ||
| 1490 | return zig_sign_extend_uint64_t( | ||
| 1491 | reversed & zig_bit_mask(uint64_t, zig_type_bit_width), | ||
| 1492 | zig_type_bit_width); | ||
| 1493 | } | ||
| 1494 | |||
| 1495 | #define zig_bit_reverse_i64 zig_bit_reverse_u64 | ||
| 1496 | |||
| 1497 | static inline uint128_t zig_bit_reverse_u128(uint128_t value, uint8_t zig_type_bit_width) { | ||
| 1498 | const uint128_t swapped = zig_byte_swap_u128(value, zig_type_bit_width); | ||
| 1499 | const uint128_t reversed = ( | ||
| 1500 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x78) & 0xff] << 0x78) | | ||
| 1501 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x70) & 0xff] << 0x70) | | ||
| 1502 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x68) & 0xff] << 0x68) | | ||
| 1503 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x60) & 0xff] << 0x60) | | ||
| 1504 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x58) & 0xff] << 0x58) | | ||
| 1505 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x50) & 0xff] << 0x50) | | ||
| 1506 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x48) & 0xff] << 0x48) | | ||
| 1507 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x40) & 0xff] << 0x40) | | ||
| 1508 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x38) & 0xff] << 0x38) | | ||
| 1509 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x30) & 0xff] << 0x30) | | ||
| 1510 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x28) & 0xff] << 0x28) | | ||
| 1511 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x20) & 0xff] << 0x20) | | ||
| 1512 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x18) & 0xff] << 0x18) | | ||
| 1513 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x10) & 0xff] << 0x10) | | ||
| 1514 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) | | ||
| 1515 | ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00)); | ||
| 1516 | return zig_sign_extend_uint128_t( | ||
| 1517 | reversed & zig_bit_mask(uint128_t, zig_type_bit_width), | ||
| 1518 | zig_type_bit_width); | ||
| 1519 | } | ||
| 1520 | |||
| 1521 | #define zig_bit_reverse_i128 zig_bit_reverse_u128 | ||
| 1522 | |||
| 1523 | static inline float zig_div_truncf(float numerator, float denominator) { | ||
| 1524 | return __builtin_truncf(numerator / denominator); | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | static inline double zig_div_trunc(double numerator, double denominator) { | ||
| 1528 | return __builtin_trunc(numerator / denominator); | ||
| 1529 | } | ||
| 1530 | |||
| 1531 | static inline long double zig_div_truncl(long double numerator, long double denominator) { | ||
| 1532 | return __builtin_truncf(numerator / denominator); | ||
| 1533 | } | ||
| 1534 | |||
| 1535 | #define zig_div_trunc_f16 zig_div_truncf | ||
| 1536 | #define zig_div_trunc_f32 zig_div_truncf | ||
| 1537 | #define zig_div_trunc_f64 zig_div_trunc | ||
| 1538 | #define zig_div_trunc_f80 zig_div_truncl | ||
| 1539 | #define zig_div_trunc_f128 zig_div_truncl | ||
| 1540 | |||
| 1541 | #define zig_div_floorf(numerator, denominator) \ | ||
| 1542 | __builtin_floorf((float)(numerator) / (float)(denominator)) | ||
| 1543 | |||
| 1544 | #define zig_div_floor(numerator, denominator) \ | ||
| 1545 | __builtin_floor((double)(numerator) / (double)(denominator)) | ||
| 1546 | |||
| 1547 | #define zig_div_floorl(numerator, denominator) \ | ||
| 1548 | __builtin_floorl((long double)(numerator) / (long double)(denominator)) | ||
| 1549 | 1424 | ||
| 1550 | #define zig_div_floor_f16 zig_div_floorf | 1425 | static inline zig_u8 zig_ctz_i128(zig_i128 val, zig_u8 bits) { |
| 1551 | #define zig_div_floor_f32 zig_div_floorf | 1426 | return zig_ctz_u128(zig_bitcast_u128(val), bits); |
| 1552 | #define zig_div_floor_f64 zig_div_floor | ||
| 1553 | #define zig_div_floor_f80 zig_div_floorl | ||
| 1554 | #define zig_div_floor_f128 zig_div_floorl | ||
| 1555 | |||
| 1556 | #define zig_div_floor_u8 zig_div_floorf | ||
| 1557 | #define zig_div_floor_i8 zig_div_floorf | ||
| 1558 | #define zig_div_floor_u16 zig_div_floorf | ||
| 1559 | #define zig_div_floor_i16 zig_div_floorf | ||
| 1560 | #define zig_div_floor_u32 zig_div_floor | ||
| 1561 | #define zig_div_floor_i32 zig_div_floor | ||
| 1562 | #define zig_div_floor_u64 zig_div_floor | ||
| 1563 | #define zig_div_floor_i64 zig_div_floor | ||
| 1564 | #define zig_div_floor_u128 zig_div_floorl | ||
| 1565 | #define zig_div_floor_i128 zig_div_floorl | ||
| 1566 | |||
| 1567 | static inline float zig_modf(float numerator, float denominator) { | ||
| 1568 | return (numerator - (zig_div_floorf(numerator, denominator) * denominator)); | ||
| 1569 | } | ||
| 1570 | |||
| 1571 | static inline double zig_mod(double numerator, double denominator) { | ||
| 1572 | return (numerator - (zig_div_floor(numerator, denominator) * denominator)); | ||
| 1573 | } | 1427 | } |
| 1574 | 1428 | ||
| 1575 | static inline long double zig_modl(long double numerator, long double denominator) { | 1429 | static inline zig_u8 zig_popcount_u128(zig_u128 val, zig_u8 bits) { |
| 1576 | return (numerator - (zig_div_floorl(numerator, denominator) * denominator)); | 1430 | return zig_popcount_u64(zig_hi_u128(val), bits - zig_as_u8(64)) + |
| 1577 | } | 1431 | zig_popcount_u64(zig_lo_u128(val), zig_as_u8(64)); |
| 1578 | 1432 | } | |
| 1579 | #define zig_mod_f16 zig_modf | ||
| 1580 | #define zig_mod_f32 zig_modf | ||
| 1581 | #define zig_mod_f64 zig_mod | ||
| 1582 | #define zig_mod_f80 zig_modl | ||
| 1583 | #define zig_mod_f128 zig_modl | ||
| 1584 | |||
| 1585 | #define zig_mod_int(ZigType, CType) \ | ||
| 1586 | static inline CType zig_mod_##ZigType(CType numerator, CType denominator) { \ | ||
| 1587 | return (numerator - (zig_div_floor_##ZigType(numerator, denominator) * denominator)); \ | ||
| 1588 | } | ||
| 1589 | 1433 | ||
| 1590 | zig_mod_int( u8, uint8_t) | 1434 | static inline zig_u8 zig_popcount_i128(zig_i128 val, zig_u8 bits) { |
| 1591 | zig_mod_int( i8, int8_t) | 1435 | return zig_popcount_u128(zig_bitcast_u128(val), bits); |
| 1592 | zig_mod_int( u16, uint16_t) | 1436 | } |
| 1593 | zig_mod_int( i16, int16_t) | 1437 | |
| 1594 | zig_mod_int( u32, uint32_t) | 1438 | static inline zig_u128 zig_byte_swap_u128(zig_u128 val, zig_u8 bits) { |
| 1595 | zig_mod_int( i32, int32_t) | 1439 | zig_u128 full_res; |
| 1596 | zig_mod_int( u64, uint64_t) | 1440 | #if zig_has_builtin(bswap128) |
| 1597 | zig_mod_int( i64, int64_t) | 1441 | full_res = __builtin_bswap128(val); |
| 1598 | zig_mod_int(u128, uint128_t) | 1442 | #else |
| 1599 | zig_mod_int(i128, int128_t) | 1443 | full_res = zig_as_u128(zig_byte_swap_u64(zig_lo_u128(val), zig_as_u8(64)), |
| 1444 | zig_byte_swap_u64(zig_hi_u128(val), zig_as_u8(64))); | ||
| 1445 | #endif | ||
| 1446 | return zig_shr_u128(full_res, zig_as_u8(128) - bits); | ||
| 1447 | } | ||
| 1448 | |||
| 1449 | static inline zig_i128 zig_byte_swap_i128(zig_i128 val, zig_u8 bits) { | ||
| 1450 | return zig_byte_swap_u128(zig_bitcast_u128(val), bits); | ||
| 1451 | } | ||
| 1452 | |||
| 1453 | static inline zig_u128 zig_bit_reverse_u128(zig_u128 val, zig_u8 bits) { | ||
| 1454 | return zig_shr_u128(zig_as_u128(zig_bit_reverse_u64(zig_lo_u128(val), zig_as_u8(64)), | ||
| 1455 | zig_bit_reverse_u64(zig_hi_u128(val), zig_as_u8(64))), | ||
| 1456 | zig_as_u8(128) - bits); | ||
| 1457 | } | ||
| 1458 | |||
| 1459 | static inline zig_i128 zig_bit_reverse_i128(zig_i128 val, zig_u8 bits) { | ||
| 1460 | return zig_bit_reverse_u128(zig_bitcast_u128(val), bits); | ||
| 1461 | } | ||
| 1462 | |||
| 1463 | /* ========================== Float Point Routines ========================== */ | ||
| 1464 | |||
| 1465 | #define zig_float_builtins(Type) \ | ||
| 1466 | zig_extern_c zig_##Type zig_builtin_##Type(sqrt)(zig_##Type); \ | ||
| 1467 | zig_extern_c zig_##Type zig_builtin_##Type(sin)(zig_##Type); \ | ||
| 1468 | zig_extern_c zig_##Type zig_builtin_##Type(cos)(zig_##Type); \ | ||
| 1469 | zig_extern_c zig_##Type zig_builtin_##Type(tan)(zig_##Type); \ | ||
| 1470 | zig_extern_c zig_##Type zig_builtin_##Type(exp)(zig_##Type); \ | ||
| 1471 | zig_extern_c zig_##Type zig_builtin_##Type(exp2)(zig_##Type); \ | ||
| 1472 | zig_extern_c zig_##Type zig_builtin_##Type(log)(zig_##Type); \ | ||
| 1473 | zig_extern_c zig_##Type zig_builtin_##Type(log2)(zig_##Type); \ | ||
| 1474 | zig_extern_c zig_##Type zig_builtin_##Type(log10)(zig_##Type); \ | ||
| 1475 | zig_extern_c zig_##Type zig_builtin_##Type(fabs)(zig_##Type); \ | ||
| 1476 | zig_extern_c zig_##Type zig_builtin_##Type(floor)(zig_##Type); \ | ||
| 1477 | zig_extern_c zig_##Type zig_builtin_##Type(ceil)(zig_##Type); \ | ||
| 1478 | zig_extern_c zig_##Type zig_builtin_##Type(round)(zig_##Type); \ | ||
| 1479 | zig_extern_c zig_##Type zig_builtin_##Type(trunc)(zig_##Type); \ | ||
| 1480 | zig_extern_c zig_##Type zig_builtin_##Type(fmod)(zig_##Type, zig_##Type); \ | ||
| 1481 | zig_extern_c zig_##Type zig_builtin_##Type(fma)(zig_##Type, zig_##Type, zig_##Type); \ | ||
| 1482 | \ | ||
| 1483 | static inline zig_##Type zig_div_trunc_##Type(zig_##Type lhs, zig_##Type rhs) { \ | ||
| 1484 | return zig_builtin_##Type(trunc)(lhs / rhs); \ | ||
| 1485 | } \ | ||
| 1486 | \ | ||
| 1487 | static inline zig_##Type zig_div_floor_##Type(zig_##Type lhs, zig_##Type rhs) { \ | ||
| 1488 | return zig_builtin_##Type(floor)(lhs / rhs); \ | ||
| 1489 | } \ | ||
| 1490 | \ | ||
| 1491 | static inline zig_##Type zig_mod_##Type(zig_##Type lhs, zig_##Type rhs) { \ | ||
| 1492 | return lhs - zig_div_floor_##Type(lhs, rhs) * rhs; \ | ||
| 1493 | } | ||
| 1494 | zig_float_builtins(f16) | ||
| 1495 | zig_float_builtins(f32) | ||
| 1496 | zig_float_builtins(f64) | ||
| 1497 | zig_float_builtins(f80) | ||
| 1498 | zig_float_builtins(f128) | ||
| 1499 | zig_float_builtins(c_longdouble) |
lib/std/debug.zig+7-1| ... | @@ -1222,7 +1222,13 @@ pub const DebugInfo = struct { | ... | @@ -1222,7 +1222,13 @@ pub const DebugInfo = struct { |
| 1222 | } | 1222 | } |
| 1223 | 1223 | ||
| 1224 | pub fn getModuleForAddress(self: *DebugInfo, address: usize) !*ModuleDebugInfo { | 1224 | pub fn getModuleForAddress(self: *DebugInfo, address: usize) !*ModuleDebugInfo { |
| 1225 | if (comptime builtin.target.isDarwin()) { | 1225 | if (builtin.zig_backend == .stage2_c) { |
| 1226 | return @as(error{ | ||
| 1227 | InvalidDebugInfo, | ||
| 1228 | MissingDebugInfo, | ||
| 1229 | UnsupportedBackend, | ||
| 1230 | }, error.UnsupportedBackend); | ||
| 1231 | } else if (comptime builtin.target.isDarwin()) { | ||
| 1226 | return self.lookupModuleDyld(address); | 1232 | return self.lookupModuleDyld(address); |
| 1227 | } else if (native_os == .windows) { | 1233 | } else if (native_os == .windows) { |
| 1228 | return self.lookupModuleWin32(address); | 1234 | return self.lookupModuleWin32(address); |
lib/std/os/linux/arm64.zig+14-5| ... | @@ -106,11 +106,20 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: * | ... | @@ -106,11 +106,20 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: * |
| 106 | pub const restore = restore_rt; | 106 | pub const restore = restore_rt; |
| 107 | 107 | ||
| 108 | pub fn restore_rt() callconv(.Naked) void { | 108 | pub fn restore_rt() callconv(.Naked) void { |
| 109 | return asm volatile ("svc #0" | 109 | switch (@import("builtin").zig_backend) { |
| 110 | : | 110 | .stage2_c => return asm volatile ( |
| 111 | : [number] "{x8}" (@enumToInt(SYS.rt_sigreturn)), | 111 | \\ mov x8, %[number] |
| 112 | : "memory", "cc" | 112 | \\ svc #0 |
| 113 | ); | 113 | : |
| 114 | : [number] "i" (@enumToInt(SYS.rt_sigreturn)), | ||
| 115 | : "memory", "cc" | ||
| 116 | ), | ||
| 117 | else => return asm volatile ("svc #0" | ||
| 118 | : | ||
| 119 | : [number] "{x8}" (@enumToInt(SYS.rt_sigreturn)), | ||
| 120 | : "memory", "cc" | ||
| 121 | ), | ||
| 122 | } | ||
| 114 | } | 123 | } |
| 115 | 124 | ||
| 116 | pub const O = struct { | 125 | pub const O = struct { |
lib/std/os/linux/i386.zig+28-10| ... | @@ -124,19 +124,37 @@ const CloneFn = std.meta.FnPtr(fn (arg: usize) callconv(.C) u8); | ... | @@ -124,19 +124,37 @@ const CloneFn = std.meta.FnPtr(fn (arg: usize) callconv(.C) u8); |
| 124 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; | 124 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; |
| 125 | 125 | ||
| 126 | pub fn restore() callconv(.Naked) void { | 126 | pub fn restore() callconv(.Naked) void { |
| 127 | return asm volatile ("int $0x80" | 127 | switch (@import("builtin").zig_backend) { |
| 128 | : | 128 | .stage2_c => return asm volatile ( |
| 129 | : [number] "{eax}" (@enumToInt(SYS.sigreturn)), | 129 | \\ movl %[number], %%eax |
| 130 | : "memory" | 130 | \\ int $0x80 |
| 131 | ); | 131 | : |
| 132 | : [number] "i" (@enumToInt(SYS.sigreturn)), | ||
| 133 | : "memory" | ||
| 134 | ), | ||
| 135 | else => return asm volatile ("int $0x80" | ||
| 136 | : | ||
| 137 | : [number] "{eax}" (@enumToInt(SYS.sigreturn)), | ||
| 138 | : "memory" | ||
| 139 | ), | ||
| 140 | } | ||
| 132 | } | 141 | } |
| 133 | 142 | ||
| 134 | pub fn restore_rt() callconv(.Naked) void { | 143 | pub fn restore_rt() callconv(.Naked) void { |
| 135 | return asm volatile ("int $0x80" | 144 | switch (@import("builtin").zig_backend) { |
| 136 | : | 145 | .stage2_c => return asm volatile ( |
| 137 | : [number] "{eax}" (@enumToInt(SYS.rt_sigreturn)), | 146 | \\ movl %[number], %%eax |
| 138 | : "memory" | 147 | \\ int $0x80 |
| 139 | ); | 148 | : |
| 149 | : [number] "i" (@enumToInt(SYS.rt_sigreturn)), | ||
| 150 | : "memory" | ||
| 151 | ), | ||
| 152 | else => return asm volatile ("int $0x80" | ||
| 153 | : | ||
| 154 | : [number] "{eax}" (@enumToInt(SYS.rt_sigreturn)), | ||
| 155 | : "memory" | ||
| 156 | ), | ||
| 157 | } | ||
| 140 | } | 158 | } |
| 141 | 159 | ||
| 142 | pub const O = struct { | 160 | pub const O = struct { |
lib/std/os/linux/x86_64.zig+15-5| ... | @@ -108,11 +108,21 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid: | ... | @@ -108,11 +108,21 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: usize, arg: usize, ptid: |
| 108 | pub const restore = restore_rt; | 108 | pub const restore = restore_rt; |
| 109 | 109 | ||
| 110 | pub fn restore_rt() callconv(.Naked) void { | 110 | pub fn restore_rt() callconv(.Naked) void { |
| 111 | return asm volatile ("syscall" | 111 | switch (@import("builtin").zig_backend) { |
| 112 | : | 112 | .stage2_c => return asm volatile ( |
| 113 | : [number] "{rax}" (@enumToInt(SYS.rt_sigreturn)), | 113 | \\ movl %[number], %%eax |
| 114 | : "rcx", "r11", "memory" | 114 | \\ syscall |
| 115 | ); | 115 | \\ retq |
| 116 | : | ||
| 117 | : [number] "i" (@enumToInt(SYS.rt_sigreturn)), | ||
| 118 | : "rcx", "r11", "memory" | ||
| 119 | ), | ||
| 120 | else => return asm volatile ("syscall" | ||
| 121 | : | ||
| 122 | : [number] "{rax}" (@enumToInt(SYS.rt_sigreturn)), | ||
| 123 | : "rcx", "r11", "memory" | ||
| 124 | ), | ||
| 125 | } | ||
| 116 | } | 126 | } |
| 117 | 127 | ||
| 118 | pub const mode_t = usize; | 128 | pub const mode_t = usize; |
lib/std/start.zig+101-73| ... | @@ -23,7 +23,6 @@ comptime { | ... | @@ -23,7 +23,6 @@ comptime { |
| 23 | // Until then, we have simplified logic here for self-hosted. TODO remove this once | 23 | // Until then, we have simplified logic here for self-hosted. TODO remove this once |
| 24 | // self-hosted is capable enough to handle all of the real start.zig logic. | 24 | // self-hosted is capable enough to handle all of the real start.zig logic. |
| 25 | if (builtin.zig_backend == .stage2_wasm or | 25 | if (builtin.zig_backend == .stage2_wasm or |
| 26 | builtin.zig_backend == .stage2_c or | ||
| 27 | builtin.zig_backend == .stage2_x86_64 or | 26 | builtin.zig_backend == .stage2_x86_64 or |
| 28 | builtin.zig_backend == .stage2_x86 or | 27 | builtin.zig_backend == .stage2_x86 or |
| 29 | builtin.zig_backend == .stage2_aarch64 or | 28 | builtin.zig_backend == .stage2_aarch64 or |
| ... | @@ -265,75 +264,104 @@ fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv | ... | @@ -265,75 +264,104 @@ fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv |
| 265 | } | 264 | } |
| 266 | 265 | ||
| 267 | fn _start() callconv(.Naked) noreturn { | 266 | fn _start() callconv(.Naked) noreturn { |
| 268 | switch (native_arch) { | 267 | switch (builtin.zig_backend) { |
| 269 | .x86_64 => { | 268 | .stage2_c => { |
| 270 | argc_argv_ptr = asm volatile ( | 269 | @export(argc_argv_ptr, .{ .name = "argc_argv_ptr" }); |
| 271 | \\ xor %%rbp, %%rbp | 270 | @export(posixCallMainAndExit, .{ .name = "_posixCallMainAndExit" }); |
| 272 | : [argc] "={rsp}" (-> [*]usize), | 271 | switch (native_arch) { |
| 273 | ); | 272 | .x86_64 => asm volatile ( |
| 274 | }, | 273 | \\ xorl %%ebp, %%ebp |
| 275 | .i386 => { | 274 | \\ movq %%rsp, argc_argv_ptr |
| 276 | argc_argv_ptr = asm volatile ( | 275 | \\ andq $-16, %%rsp |
| 277 | \\ xor %%ebp, %%ebp | 276 | \\ call _posixCallMainAndExit |
| 278 | : [argc] "={esp}" (-> [*]usize), | 277 | ), |
| 279 | ); | 278 | .i386 => asm volatile ( |
| 280 | }, | 279 | \\ xorl %%ebp, %%ebp |
| 281 | .aarch64, .aarch64_be, .arm, .armeb, .thumb => { | 280 | \\ movl %%esp, argc_argv_ptr |
| 282 | argc_argv_ptr = asm volatile ( | 281 | \\ andl $-16, %%esp |
| 283 | \\ mov fp, #0 | 282 | \\ jmp _posixCallMainAndExit |
| 284 | \\ mov lr, #0 | 283 | ), |
| 285 | : [argc] "={sp}" (-> [*]usize), | 284 | .aarch64, .aarch64_be, .arm, .armeb, .thumb => asm volatile ( |
| 286 | ); | 285 | \\ mov fp, #0 |
| 287 | }, | 286 | \\ mov lr, #0 |
| 288 | .riscv64 => { | 287 | \\ str sp, argc_argv_ptr |
| 289 | argc_argv_ptr = asm volatile ( | 288 | \\ and sp, #-16 |
| 290 | \\ li s0, 0 | 289 | \\ b _posixCallMainAndExit |
| 291 | \\ li ra, 0 | 290 | ), |
| 292 | : [argc] "={sp}" (-> [*]usize), | 291 | else => @compileError("unsupported arch"), |
| 293 | ); | 292 | } |
| 294 | }, | 293 | unreachable; |
| 295 | .mips, .mipsel => { | ||
| 296 | // The lr is already zeroed on entry, as specified by the ABI. | ||
| 297 | argc_argv_ptr = asm volatile ( | ||
| 298 | \\ move $fp, $0 | ||
| 299 | : [argc] "={sp}" (-> [*]usize), | ||
| 300 | ); | ||
| 301 | }, | ||
| 302 | .powerpc => { | ||
| 303 | // Setup the initial stack frame and clear the back chain pointer. | ||
| 304 | argc_argv_ptr = asm volatile ( | ||
| 305 | \\ mr 4, 1 | ||
| 306 | \\ li 0, 0 | ||
| 307 | \\ stwu 1,-16(1) | ||
| 308 | \\ stw 0, 0(1) | ||
| 309 | \\ mtlr 0 | ||
| 310 | : [argc] "={r4}" (-> [*]usize), | ||
| 311 | : | ||
| 312 | : "r0" | ||
| 313 | ); | ||
| 314 | }, | ||
| 315 | .powerpc64le => { | ||
| 316 | // Setup the initial stack frame and clear the back chain pointer. | ||
| 317 | // TODO: Support powerpc64 (big endian) on ELFv2. | ||
| 318 | argc_argv_ptr = asm volatile ( | ||
| 319 | \\ mr 4, 1 | ||
| 320 | \\ li 0, 0 | ||
| 321 | \\ stdu 0, -32(1) | ||
| 322 | \\ mtlr 0 | ||
| 323 | : [argc] "={r4}" (-> [*]usize), | ||
| 324 | : | ||
| 325 | : "r0" | ||
| 326 | ); | ||
| 327 | }, | 294 | }, |
| 328 | .sparc64 => { | 295 | else => switch (native_arch) { |
| 329 | // argc is stored after a register window (16 registers) plus stack bias | 296 | .x86_64 => { |
| 330 | argc_argv_ptr = asm ( | 297 | argc_argv_ptr = asm volatile ( |
| 331 | \\ mov %%g0, %%i6 | 298 | \\ xor %%ebp, %%ebp |
| 332 | \\ add %%o6, 2175, %[argc] | 299 | : [argc] "={rsp}" (-> [*]usize), |
| 333 | : [argc] "=r" (-> [*]usize), | 300 | ); |
| 334 | ); | 301 | }, |
| 302 | .i386 => { | ||
| 303 | argc_argv_ptr = asm volatile ( | ||
| 304 | \\ xor %%ebp, %%ebp | ||
| 305 | : [argc] "={esp}" (-> [*]usize), | ||
| 306 | ); | ||
| 307 | }, | ||
| 308 | .aarch64, .aarch64_be, .arm, .armeb, .thumb => { | ||
| 309 | argc_argv_ptr = asm volatile ( | ||
| 310 | \\ mov fp, #0 | ||
| 311 | \\ mov lr, #0 | ||
| 312 | : [argc] "={sp}" (-> [*]usize), | ||
| 313 | ); | ||
| 314 | }, | ||
| 315 | .riscv64 => { | ||
| 316 | argc_argv_ptr = asm volatile ( | ||
| 317 | \\ li s0, 0 | ||
| 318 | \\ li ra, 0 | ||
| 319 | : [argc] "={sp}" (-> [*]usize), | ||
| 320 | ); | ||
| 321 | }, | ||
| 322 | .mips, .mipsel => { | ||
| 323 | // The lr is already zeroed on entry, as specified by the ABI. | ||
| 324 | argc_argv_ptr = asm volatile ( | ||
| 325 | \\ move $fp, $0 | ||
| 326 | : [argc] "={sp}" (-> [*]usize), | ||
| 327 | ); | ||
| 328 | }, | ||
| 329 | .powerpc => { | ||
| 330 | // Setup the initial stack frame and clear the back chain pointer. | ||
| 331 | argc_argv_ptr = asm volatile ( | ||
| 332 | \\ mr 4, 1 | ||
| 333 | \\ li 0, 0 | ||
| 334 | \\ stwu 1,-16(1) | ||
| 335 | \\ stw 0, 0(1) | ||
| 336 | \\ mtlr 0 | ||
| 337 | : [argc] "={r4}" (-> [*]usize), | ||
| 338 | : | ||
| 339 | : "r0" | ||
| 340 | ); | ||
| 341 | }, | ||
| 342 | .powerpc64le => { | ||
| 343 | // Setup the initial stack frame and clear the back chain pointer. | ||
| 344 | // TODO: Support powerpc64 (big endian) on ELFv2. | ||
| 345 | argc_argv_ptr = asm volatile ( | ||
| 346 | \\ mr 4, 1 | ||
| 347 | \\ li 0, 0 | ||
| 348 | \\ stdu 0, -32(1) | ||
| 349 | \\ mtlr 0 | ||
| 350 | : [argc] "={r4}" (-> [*]usize), | ||
| 351 | : | ||
| 352 | : "r0" | ||
| 353 | ); | ||
| 354 | }, | ||
| 355 | .sparc64 => { | ||
| 356 | // argc is stored after a register window (16 registers) plus stack bias | ||
| 357 | argc_argv_ptr = asm ( | ||
| 358 | \\ mov %%g0, %%i6 | ||
| 359 | \\ add %%o6, 2175, %[argc] | ||
| 360 | : [argc] "=r" (-> [*]usize), | ||
| 361 | ); | ||
| 362 | }, | ||
| 363 | else => @compileError("unsupported arch"), | ||
| 335 | }, | 364 | }, |
| 336 | else => @compileError("unsupported arch"), | ||
| 337 | } | 365 | } |
| 338 | // If LLVM inlines stack variables into _start, they will overwrite | 366 | // If LLVM inlines stack variables into _start, they will overwrite |
| 339 | // the command line argument data. | 367 | // the command line argument data. |
| ... | @@ -363,7 +391,7 @@ fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn { | ... | @@ -363,7 +391,7 @@ fn wWinMainCRTStartup() callconv(std.os.windows.WINAPI) noreturn { |
| 363 | std.os.windows.kernel32.ExitProcess(@bitCast(std.os.windows.UINT, result)); | 391 | std.os.windows.kernel32.ExitProcess(@bitCast(std.os.windows.UINT, result)); |
| 364 | } | 392 | } |
| 365 | 393 | ||
| 366 | fn posixCallMainAndExit() noreturn { | 394 | fn posixCallMainAndExit() callconv(.C) noreturn { |
| 367 | @setAlignStack(16); | 395 | @setAlignStack(16); |
| 368 | 396 | ||
| 369 | const argc = argc_argv_ptr[0]; | 397 | const argc = argc_argv_ptr[0]; |
| ... | @@ -462,7 +490,7 @@ fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 { | ... | @@ -462,7 +490,7 @@ fn callMainWithArgs(argc: usize, argv: [*][*:0]u8, envp: [][*:0]u8) u8 { |
| 462 | return initEventLoopAndCallMain(); | 490 | return initEventLoopAndCallMain(); |
| 463 | } | 491 | } |
| 464 | 492 | ||
| 465 | fn main(c_argc: i32, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) callconv(.C) i32 { | 493 | fn main(c_argc: c_int, c_argv: [*c][*c]u8, c_envp: [*c][*c]u8) callconv(.C) c_int { |
| 466 | var env_count: usize = 0; | 494 | var env_count: usize = 0; |
| 467 | while (c_envp[env_count] != null) : (env_count += 1) {} | 495 | while (c_envp[env_count] != null) : (env_count += 1) {} |
| 468 | const envp = @ptrCast([*][*:0]u8, c_envp)[0..env_count]; | 496 | const envp = @ptrCast([*][*:0]u8, c_envp)[0..env_count]; |
| ... | @@ -474,11 +502,11 @@ fn main(c_argc: i32, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) callconv(.C) | ... | @@ -474,11 +502,11 @@ fn main(c_argc: i32, c_argv: [*][*:0]u8, c_envp: [*:null]?[*:0]u8) callconv(.C) |
| 474 | expandStackSize(phdrs); | 502 | expandStackSize(phdrs); |
| 475 | } | 503 | } |
| 476 | 504 | ||
| 477 | return @call(.{ .modifier = .always_inline }, callMainWithArgs, .{ @intCast(usize, c_argc), c_argv, envp }); | 505 | return @call(.{ .modifier = .always_inline }, callMainWithArgs, .{ @intCast(usize, c_argc), @ptrCast([*][*:0]u8, c_argv), envp }); |
| 478 | } | 506 | } |
| 479 | 507 | ||
| 480 | fn mainWithoutEnv(c_argc: i32, c_argv: [*][*:0]u8) callconv(.C) usize { | 508 | fn mainWithoutEnv(c_argc: c_int, c_argv: [*c][*c]u8) callconv(.C) c_int { |
| 481 | std.os.argv = c_argv[0..@intCast(usize, c_argc)]; | 509 | std.os.argv = @ptrCast([*][*:0]u8, c_argv)[0..@intCast(usize, c_argc)]; |
| 482 | return @call(.{ .modifier = .always_inline }, callMain, .{}); | 510 | return @call(.{ .modifier = .always_inline }, callMain, .{}); |
| 483 | } | 511 | } |
| 484 | 512 |
lib/test_runner.zig+2-1| ... | @@ -8,7 +8,8 @@ var log_err_count: usize = 0; | ... | @@ -8,7 +8,8 @@ var log_err_count: usize = 0; |
| 8 | 8 | ||
| 9 | pub fn main() void { | 9 | pub fn main() void { |
| 10 | if (builtin.zig_backend != .stage1 and | 10 | if (builtin.zig_backend != .stage1 and |
| 11 | (builtin.zig_backend != .stage2_llvm or builtin.cpu.arch == .wasm32)) | 11 | (builtin.zig_backend != .stage2_llvm or builtin.cpu.arch == .wasm32) and |
| 12 | builtin.zig_backend != .stage2_c) | ||
| 12 | { | 13 | { |
| 13 | return main2() catch @panic("test failure"); | 14 | return main2() catch @panic("test failure"); |
| 14 | } | 15 | } |
src/Compilation.zig+8-5| ... | @@ -3103,13 +3103,16 @@ fn processOneJob(comp: *Compilation, job: Job) !void { | ... | @@ -3103,13 +3103,16 @@ fn processOneJob(comp: *Compilation, job: Job) !void { |
| 3103 | .decl_index = decl_index, | 3103 | .decl_index = decl_index, |
| 3104 | .decl = decl, | 3104 | .decl = decl, |
| 3105 | .fwd_decl = fwd_decl.toManaged(gpa), | 3105 | .fwd_decl = fwd_decl.toManaged(gpa), |
| 3106 | .typedefs = c_codegen.TypedefMap.initContext(gpa, .{ | 3106 | .typedefs = c_codegen.TypedefMap.initContext(gpa, .{ .mod = module }), |
| 3107 | .mod = module, | ||
| 3108 | }), | ||
| 3109 | .typedefs_arena = typedefs_arena.allocator(), | 3107 | .typedefs_arena = typedefs_arena.allocator(), |
| 3110 | }; | 3108 | }; |
| 3111 | defer dg.fwd_decl.deinit(); | 3109 | defer { |
| 3112 | defer dg.typedefs.deinit(); | 3110 | for (dg.typedefs.values()) |typedef| { |
| 3111 | module.gpa.free(typedef.rendered); | ||
| 3112 | } | ||
| 3113 | dg.typedefs.deinit(); | ||
| 3114 | dg.fwd_decl.deinit(); | ||
| 3115 | } | ||
| 3113 | 3116 | ||
| 3114 | c_codegen.genHeader(&dg) catch |err| switch (err) { | 3117 | c_codegen.genHeader(&dg) catch |err| switch (err) { |
| 3115 | error.AnalysisFail => { | 3118 | error.AnalysisFail => { |
src/codegen/c.zig+2694-1470| ... | @@ -18,8 +18,8 @@ const Air = @import("../Air.zig"); | ... | @@ -18,8 +18,8 @@ const Air = @import("../Air.zig"); |
| 18 | const Liveness = @import("../Liveness.zig"); | 18 | const Liveness = @import("../Liveness.zig"); |
| 19 | const CType = @import("../type.zig").CType; | 19 | const CType = @import("../type.zig").CType; |
| 20 | 20 | ||
| 21 | const Mutability = enum { Const, Mut }; | 21 | const Mutability = enum { Const, ConstArgument, Mut }; |
| 22 | const BigIntConst = std.math.big.int.Const; | 22 | const BigInt = std.math.big.int; |
| 23 | 23 | ||
| 24 | pub const CValue = union(enum) { | 24 | pub const CValue = union(enum) { |
| 25 | none: void, | 25 | none: void, |
| ... | @@ -34,8 +34,8 @@ pub const CValue = union(enum) { | ... | @@ -34,8 +34,8 @@ pub const CValue = union(enum) { |
| 34 | /// By-value | 34 | /// By-value |
| 35 | decl: Decl.Index, | 35 | decl: Decl.Index, |
| 36 | decl_ref: Decl.Index, | 36 | decl_ref: Decl.Index, |
| 37 | /// An undefined (void *) pointer (cannot be dereferenced) | 37 | /// An undefined value (cannot be dereferenced) |
| 38 | undefined_ptr: void, | 38 | undef: Type, |
| 39 | /// Render the slice as an identifier (using fmtIdent) | 39 | /// Render the slice as an identifier (using fmtIdent) |
| 40 | identifier: []const u8, | 40 | identifier: []const u8, |
| 41 | /// Render these bytes literally. | 41 | /// Render these bytes literally. |
| ... | @@ -48,6 +48,11 @@ const BlockData = struct { | ... | @@ -48,6 +48,11 @@ const BlockData = struct { |
| 48 | result: CValue, | 48 | result: CValue, |
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | const TypedefKind = enum { | ||
| 52 | Forward, | ||
| 53 | Complete, | ||
| 54 | }; | ||
| 55 | |||
| 51 | pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue); | 56 | pub const CValueMap = std.AutoHashMap(Air.Inst.Ref, CValue); |
| 52 | pub const TypedefMap = std.ArrayHashMap( | 57 | pub const TypedefMap = std.ArrayHashMap( |
| 53 | Type, | 58 | Type, |
| ... | @@ -63,9 +68,16 @@ const FormatTypeAsCIdentContext = struct { | ... | @@ -63,9 +68,16 @@ const FormatTypeAsCIdentContext = struct { |
| 63 | 68 | ||
| 64 | const ValueRenderLocation = enum { | 69 | const ValueRenderLocation = enum { |
| 65 | FunctionArgument, | 70 | FunctionArgument, |
| 71 | Initializer, | ||
| 66 | Other, | 72 | Other, |
| 67 | }; | 73 | }; |
| 68 | 74 | ||
| 75 | const BuiltinInfo = enum { | ||
| 76 | None, | ||
| 77 | Range, | ||
| 78 | Bits, | ||
| 79 | }; | ||
| 80 | |||
| 69 | /// TODO make this not cut off at 128 bytes | 81 | /// TODO make this not cut off at 128 bytes |
| 70 | fn formatTypeAsCIdentifier( | 82 | fn formatTypeAsCIdentifier( |
| 71 | data: FormatTypeAsCIdentContext, | 83 | data: FormatTypeAsCIdentContext, |
| ... | @@ -73,11 +85,11 @@ fn formatTypeAsCIdentifier( | ... | @@ -73,11 +85,11 @@ fn formatTypeAsCIdentifier( |
| 73 | options: std.fmt.FormatOptions, | 85 | options: std.fmt.FormatOptions, |
| 74 | writer: anytype, | 86 | writer: anytype, |
| 75 | ) !void { | 87 | ) !void { |
| 76 | _ = fmt; | 88 | var stack = std.heap.stackFallback(128, data.mod.gpa); |
| 77 | _ = options; | 89 | const allocator = stack.get(); |
| 78 | var buffer = [1]u8{0} ** 128; | 90 | const str = std.fmt.allocPrint(allocator, "{}", .{data.ty.fmt(data.mod)}) catch ""; |
| 79 | var buf = std.fmt.bufPrint(&buffer, "{}", .{data.ty.fmt(data.mod)}) catch &buffer; | 91 | defer allocator.free(str); |
| 80 | return formatIdent(buf, "", .{}, writer); | 92 | return formatIdent(str, fmt, options, writer); |
| 81 | } | 93 | } |
| 82 | 94 | ||
| 83 | pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsCIdentifier) { | 95 | pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsCIdentifier) { |
| ... | @@ -88,23 +100,9 @@ pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsC | ... | @@ -88,23 +100,9 @@ pub fn typeToCIdentifier(ty: Type, mod: *Module) std.fmt.Formatter(formatTypeAsC |
| 88 | } | 100 | } |
| 89 | 101 | ||
| 90 | const reserved_idents = std.ComptimeStringMap(void, .{ | 102 | const reserved_idents = std.ComptimeStringMap(void, .{ |
| 91 | .{ "_Alignas", { | 103 | .{ "alignas", { |
| 92 | @setEvalBranchQuota(4000); | 104 | @setEvalBranchQuota(4000); |
| 93 | } }, | 105 | } }, |
| 94 | .{ "_Alignof", {} }, | ||
| 95 | .{ "_Atomic", {} }, | ||
| 96 | .{ "_Bool", {} }, | ||
| 97 | .{ "_Complex", {} }, | ||
| 98 | .{ "_Decimal128", {} }, | ||
| 99 | .{ "_Decimal32", {} }, | ||
| 100 | .{ "_Decimal64", {} }, | ||
| 101 | .{ "_Generic", {} }, | ||
| 102 | .{ "_Imaginary", {} }, | ||
| 103 | .{ "_Noreturn", {} }, | ||
| 104 | .{ "_Pragma", {} }, | ||
| 105 | .{ "_Static_assert", {} }, | ||
| 106 | .{ "_Thread_local", {} }, | ||
| 107 | .{ "alignas", {} }, | ||
| 108 | .{ "alignof", {} }, | 106 | .{ "alignof", {} }, |
| 109 | .{ "asm", {} }, | 107 | .{ "asm", {} }, |
| 110 | .{ "atomic_bool", {} }, | 108 | .{ "atomic_bool", {} }, |
| ... | @@ -199,6 +197,15 @@ const reserved_idents = std.ComptimeStringMap(void, .{ | ... | @@ -199,6 +197,15 @@ const reserved_idents = std.ComptimeStringMap(void, .{ |
| 199 | .{ "while ", {} }, | 197 | .{ "while ", {} }, |
| 200 | }); | 198 | }); |
| 201 | 199 | ||
| 200 | fn isReservedIdent(ident: []const u8) bool { | ||
| 201 | if (ident.len >= 2 and ident[0] == '_') { | ||
| 202 | switch (ident[1]) { | ||
| 203 | 'A'...'Z', '_' => return true, | ||
| 204 | else => return false, | ||
| 205 | } | ||
| 206 | } else return reserved_idents.has(ident); | ||
| 207 | } | ||
| 208 | |||
| 202 | fn formatIdent( | 209 | fn formatIdent( |
| 203 | ident: []const u8, | 210 | ident: []const u8, |
| 204 | comptime fmt: []const u8, | 211 | comptime fmt: []const u8, |
| ... | @@ -207,7 +214,7 @@ fn formatIdent( | ... | @@ -207,7 +214,7 @@ fn formatIdent( |
| 207 | ) !void { | 214 | ) !void { |
| 208 | _ = options; | 215 | _ = options; |
| 209 | const solo = fmt.len != 0 and fmt[0] == ' '; // space means solo; not part of a bigger ident. | 216 | const solo = fmt.len != 0 and fmt[0] == ' '; // space means solo; not part of a bigger ident. |
| 210 | if (solo and reserved_idents.has(ident)) { | 217 | if (solo and isReservedIdent(ident)) { |
| 211 | try writer.writeAll("zig_e_"); | 218 | try writer.writeAll("zig_e_"); |
| 212 | } | 219 | } |
| 213 | for (ident) |c, i| { | 220 | for (ident) |c, i| { |
| ... | @@ -247,30 +254,27 @@ pub const Function = struct { | ... | @@ -247,30 +254,27 @@ pub const Function = struct { |
| 247 | 254 | ||
| 248 | const val = f.air.value(inst).?; | 255 | const val = f.air.value(inst).?; |
| 249 | const ty = f.air.typeOf(inst); | 256 | const ty = f.air.typeOf(inst); |
| 250 | switch (ty.zigTypeTag()) { | 257 | |
| 251 | .Array => { | 258 | const result = if (lowersToArray(ty, f.object.dg.module.getTarget())) result: { |
| 252 | const writer = f.object.code_header.writer(); | 259 | const writer = f.object.code_header.writer(); |
| 253 | const decl_c_value = f.allocLocalValue(); | 260 | const decl_c_value = f.allocLocalValue(); |
| 254 | gop.value_ptr.* = decl_c_value; | 261 | try writer.writeAll("static "); |
| 255 | try writer.writeAll("static "); | 262 | try f.object.dg.renderTypeAndName(writer, ty, decl_c_value, .Const, 0, .Complete); |
| 256 | try f.object.dg.renderTypeAndName( | 263 | try writer.writeAll(" = "); |
| 257 | writer, | 264 | try f.object.dg.renderValue(writer, ty, val, .Initializer); |
| 258 | ty, | 265 | try writer.writeAll(";\n "); |
| 259 | decl_c_value, | 266 | break :result decl_c_value; |
| 260 | .Const, | 267 | } else CValue{ .constant = inst }; |
| 261 | 0, | 268 | |
| 262 | ); | 269 | gop.value_ptr.* = result; |
| 263 | try writer.writeAll(" = "); | 270 | return result; |
| 264 | try f.object.dg.renderValue(writer, ty, val, .Other); | 271 | } |
| 265 | try writer.writeAll(";\n "); | 272 | |
| 266 | return decl_c_value; | 273 | fn wantSafety(f: *Function) bool { |
| 267 | }, | 274 | return switch (f.object.dg.module.optimizeMode()) { |
| 268 | else => { | 275 | .Debug, .ReleaseSafe => true, |
| 269 | const result = CValue{ .constant = inst }; | 276 | .ReleaseFast, .ReleaseSmall => false, |
| 270 | gop.value_ptr.* = result; | 277 | }; |
| 271 | return result; | ||
| 272 | }, | ||
| 273 | } | ||
| 274 | } | 278 | } |
| 275 | 279 | ||
| 276 | fn allocLocalValue(f: *Function) CValue { | 280 | fn allocLocalValue(f: *Function) CValue { |
| ... | @@ -291,17 +295,19 @@ pub const Function = struct { | ... | @@ -291,17 +295,19 @@ pub const Function = struct { |
| 291 | local_value, | 295 | local_value, |
| 292 | mutability, | 296 | mutability, |
| 293 | alignment, | 297 | alignment, |
| 298 | .Complete, | ||
| 294 | ); | 299 | ); |
| 295 | return local_value; | 300 | return local_value; |
| 296 | } | 301 | } |
| 297 | 302 | ||
| 298 | fn writeCValue(f: *Function, w: anytype, c_value: CValue) !void { | 303 | fn writeCValue(f: *Function, w: anytype, c_value: CValue, location: ValueRenderLocation) !void { |
| 299 | switch (c_value) { | 304 | switch (c_value) { |
| 300 | .constant => |inst| { | 305 | .constant => |inst| { |
| 301 | const ty = f.air.typeOf(inst); | 306 | const ty = f.air.typeOf(inst); |
| 302 | const val = f.air.value(inst).?; | 307 | const val = f.air.value(inst).?; |
| 303 | return f.object.dg.renderValue(w, ty, val, .Other); | 308 | return f.object.dg.renderValue(w, ty, val, location); |
| 304 | }, | 309 | }, |
| 310 | .undef => |ty| return f.object.dg.renderValue(w, ty, Value.undef, location), | ||
| 305 | else => return f.object.dg.writeCValue(w, c_value), | 311 | else => return f.object.dg.writeCValue(w, c_value), |
| 306 | } | 312 | } |
| 307 | } | 313 | } |
| ... | @@ -319,17 +325,48 @@ pub const Function = struct { | ... | @@ -319,17 +325,48 @@ pub const Function = struct { |
| 319 | } | 325 | } |
| 320 | } | 326 | } |
| 321 | 327 | ||
| 328 | fn writeCValueMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void { | ||
| 329 | switch (c_value) { | ||
| 330 | .constant => |inst| { | ||
| 331 | const ty = f.air.typeOf(inst); | ||
| 332 | const val = f.air.value(inst).?; | ||
| 333 | try f.object.dg.renderValue(w, ty, val, .Other); | ||
| 334 | try w.writeByte('.'); | ||
| 335 | return f.writeCValue(w, member, .Other); | ||
| 336 | }, | ||
| 337 | else => return f.object.dg.writeCValueMember(w, c_value, member), | ||
| 338 | } | ||
| 339 | } | ||
| 340 | |||
| 341 | fn writeCValueDerefMember(f: *Function, w: anytype, c_value: CValue, member: CValue) !void { | ||
| 342 | switch (c_value) { | ||
| 343 | .constant => |inst| { | ||
| 344 | const ty = f.air.typeOf(inst); | ||
| 345 | const val = f.air.value(inst).?; | ||
| 346 | try w.writeByte('('); | ||
| 347 | try f.object.dg.renderValue(w, ty, val, .Other); | ||
| 348 | try w.writeAll(")->"); | ||
| 349 | return f.writeCValue(w, member, .Other); | ||
| 350 | }, | ||
| 351 | else => return f.object.dg.writeCValueDerefMember(w, c_value, member), | ||
| 352 | } | ||
| 353 | } | ||
| 354 | |||
| 322 | fn fail(f: *Function, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } { | 355 | fn fail(f: *Function, comptime format: []const u8, args: anytype) error{ AnalysisFail, OutOfMemory } { |
| 323 | return f.object.dg.fail(format, args); | 356 | return f.object.dg.fail(format, args); |
| 324 | } | 357 | } |
| 325 | 358 | ||
| 326 | fn renderType(f: *Function, w: anytype, t: Type) !void { | 359 | fn renderType(f: *Function, w: anytype, t: Type) !void { |
| 327 | return f.object.dg.renderType(w, t); | 360 | return f.object.dg.renderType(w, t, .Complete); |
| 328 | } | 361 | } |
| 329 | 362 | ||
| 330 | fn renderTypecast(f: *Function, w: anytype, t: Type) !void { | 363 | fn renderTypecast(f: *Function, w: anytype, t: Type) !void { |
| 331 | return f.object.dg.renderTypecast(w, t); | 364 | return f.object.dg.renderTypecast(w, t); |
| 332 | } | 365 | } |
| 366 | |||
| 367 | fn fmtIntLiteral(f: *Function, ty: Type, val: Value) !std.fmt.Formatter(formatIntLiteral) { | ||
| 368 | return f.object.dg.fmtIntLiteral(ty, val); | ||
| 369 | } | ||
| 333 | }; | 370 | }; |
| 334 | 371 | ||
| 335 | /// This data is available when outputting .c code for a `Module`. | 372 | /// This data is available when outputting .c code for a `Module`. |
| ... | @@ -362,13 +399,13 @@ pub const DeclGen = struct { | ... | @@ -362,13 +399,13 @@ pub const DeclGen = struct { |
| 362 | @setCold(true); | 399 | @setCold(true); |
| 363 | const src = LazySrcLoc.nodeOffset(0); | 400 | const src = LazySrcLoc.nodeOffset(0); |
| 364 | const src_loc = src.toSrcLoc(dg.decl); | 401 | const src_loc = src.toSrcLoc(dg.decl); |
| 365 | dg.error_msg = try Module.ErrorMsg.create(dg.module.gpa, src_loc, format, args); | 402 | dg.error_msg = try Module.ErrorMsg.create(dg.gpa, src_loc, format, args); |
| 366 | return error.AnalysisFail; | 403 | return error.AnalysisFail; |
| 367 | } | 404 | } |
| 368 | 405 | ||
| 369 | fn getTypedefName(dg: *DeclGen, t: Type) ?[]const u8 { | 406 | fn getTypedefName(dg: *DeclGen, t: Type) ?[]const u8 { |
| 370 | if (dg.typedefs.get(t)) |some| { | 407 | if (dg.typedefs.get(t)) |typedef| { |
| 371 | return some.name; | 408 | return typedef.name; |
| 372 | } else { | 409 | } else { |
| 373 | return null; | 410 | return null; |
| 374 | } | 411 | } |
| ... | @@ -381,86 +418,49 @@ pub const DeclGen = struct { | ... | @@ -381,86 +418,49 @@ pub const DeclGen = struct { |
| 381 | val: Value, | 418 | val: Value, |
| 382 | decl_index: Decl.Index, | 419 | decl_index: Decl.Index, |
| 383 | ) error{ OutOfMemory, AnalysisFail }!void { | 420 | ) error{ OutOfMemory, AnalysisFail }!void { |
| 421 | const decl = dg.module.declPtr(decl_index); | ||
| 422 | assert(decl.has_tv); | ||
| 423 | |||
| 424 | // Render an undefined pointer if we have a pointer to a zero-bit or comptime type. | ||
| 425 | if (ty.isPtrAtRuntime() and !decl.ty.isFnOrHasRuntimeBits()) { | ||
| 426 | return dg.writeCValue(writer, CValue{ .undef = ty }); | ||
| 427 | } | ||
| 428 | |||
| 429 | // Chase function values in order to be able to reference the original function. | ||
| 430 | inline for (.{ .function, .extern_fn }) |tag| | ||
| 431 | if (decl.val.castTag(tag)) |func| | ||
| 432 | if (func.data.owner_decl != decl_index) | ||
| 433 | return dg.renderDeclValue(writer, ty, val, func.data.owner_decl); | ||
| 434 | |||
| 384 | if (ty.isSlice()) { | 435 | if (ty.isSlice()) { |
| 385 | try writer.writeByte('('); | 436 | try writer.writeByte('('); |
| 386 | try dg.renderTypecast(writer, ty); | 437 | try dg.renderTypecast(writer, ty); |
| 387 | try writer.writeAll("){"); | 438 | try writer.writeAll("){ .ptr = "); |
| 439 | |||
| 388 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 440 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 389 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Other); | 441 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Initializer); |
| 390 | try writer.writeAll(", "); | 442 | |
| 391 | try writer.print("{d}", .{val.sliceLen(dg.module)}); | 443 | var len_pl: Value.Payload.U64 = .{ |
| 392 | try writer.writeAll("}"); | 444 | .base = .{ .tag = .int_u64 }, |
| 393 | return; | 445 | .data = val.sliceLen(dg.module), |
| 446 | }; | ||
| 447 | const len_val = Value.initPayload(&len_pl.base); | ||
| 448 | return writer.print(", .len = {} }}", .{try dg.fmtIntLiteral(Type.usize, len_val)}); | ||
| 394 | } | 449 | } |
| 395 | 450 | ||
| 396 | const decl = dg.module.declPtr(decl_index); | ||
| 397 | assert(decl.has_tv); | ||
| 398 | // We shouldn't cast C function pointers as this is UB (when you call | 451 | // We shouldn't cast C function pointers as this is UB (when you call |
| 399 | // them). The analysis until now should ensure that the C function | 452 | // them). The analysis until now should ensure that the C function |
| 400 | // pointers are compatible. If they are not, then there is a bug | 453 | // pointers are compatible. If they are not, then there is a bug |
| 401 | // somewhere and we should let the C compiler tell us about it. | 454 | // somewhere and we should let the C compiler tell us about it. |
| 402 | if (ty.castPtrToFn() == null) { | 455 | const need_typecast = if (ty.castPtrToFn()) |_| false else !ty.eql(decl.ty, dg.module); |
| 403 | // Determine if we must pointer cast. | 456 | if (need_typecast) { |
| 404 | if (ty.eql(decl.ty, dg.module)) { | ||
| 405 | try writer.writeByte('&'); | ||
| 406 | try dg.renderDeclName(writer, decl_index); | ||
| 407 | return; | ||
| 408 | } | ||
| 409 | |||
| 410 | try writer.writeAll("(("); | 457 | try writer.writeAll("(("); |
| 411 | try dg.renderTypecast(writer, ty); | 458 | try dg.renderTypecast(writer, ty); |
| 412 | try writer.writeAll(")&"); | ||
| 413 | try dg.renderDeclName(writer, decl_index); | ||
| 414 | try writer.writeByte(')'); | 459 | try writer.writeByte(')'); |
| 415 | return; | ||
| 416 | } | 460 | } |
| 417 | 461 | try writer.writeByte('&'); | |
| 418 | try dg.renderDeclName(writer, decl_index); | 462 | try dg.renderDeclName(writer, decl_index); |
| 419 | } | 463 | if (need_typecast) try writer.writeByte(')'); |
| 420 | |||
| 421 | fn renderInt128( | ||
| 422 | writer: anytype, | ||
| 423 | int_val: anytype, | ||
| 424 | ) error{ OutOfMemory, AnalysisFail }!void { | ||
| 425 | const int_info = @typeInfo(@TypeOf(int_val)).Int; | ||
| 426 | const is_signed = int_info.signedness == .signed; | ||
| 427 | const is_neg = int_val < 0; | ||
| 428 | comptime assert(int_info.bits > 64 and int_info.bits <= 128); | ||
| 429 | |||
| 430 | // Clang and GCC don't support 128-bit integer constants but will hopefully unfold them | ||
| 431 | // if we construct one manually. | ||
| 432 | const magnitude = std.math.absCast(int_val); | ||
| 433 | |||
| 434 | const high = @truncate(u64, magnitude >> 64); | ||
| 435 | const low = @truncate(u64, magnitude); | ||
| 436 | |||
| 437 | // (int128_t)/<->( ( (uint128_t)( val_high << 64 )u ) + (uint128_t)val_low/u ) | ||
| 438 | if (is_signed) try writer.writeAll("(int128_t)"); | ||
| 439 | if (is_neg) try writer.writeByte('-'); | ||
| 440 | |||
| 441 | try writer.print("(((uint128_t)0x{x}u<<64)", .{high}); | ||
| 442 | |||
| 443 | if (low > 0) | ||
| 444 | try writer.print("+(uint128_t)0x{x}u", .{low}); | ||
| 445 | |||
| 446 | return writer.writeByte(')'); | ||
| 447 | } | ||
| 448 | |||
| 449 | fn renderBigIntConst( | ||
| 450 | dg: *DeclGen, | ||
| 451 | writer: anytype, | ||
| 452 | val: BigIntConst, | ||
| 453 | signed: bool, | ||
| 454 | ) error{ OutOfMemory, AnalysisFail }!void { | ||
| 455 | if (signed) { | ||
| 456 | try renderInt128(writer, val.to(i128) catch { | ||
| 457 | return dg.fail("TODO implement integer constants larger than 128 bits", .{}); | ||
| 458 | }); | ||
| 459 | } else { | ||
| 460 | try renderInt128(writer, val.to(u128) catch { | ||
| 461 | return dg.fail("TODO implement integer constants larger than 128 bits", .{}); | ||
| 462 | }); | ||
| 463 | } | ||
| 464 | } | 464 | } |
| 465 | 465 | ||
| 466 | // Renders a "parent" pointer by recursing to the root decl/variable | 466 | // Renders a "parent" pointer by recursing to the root decl/variable |
| ... | @@ -468,9 +468,11 @@ pub const DeclGen = struct { | ... | @@ -468,9 +468,11 @@ pub const DeclGen = struct { |
| 468 | // | 468 | // |
| 469 | // Used for .elem_ptr, .field_ptr, .opt_payload_ptr, .eu_payload_ptr | 469 | // Used for .elem_ptr, .field_ptr, .opt_payload_ptr, .eu_payload_ptr |
| 470 | fn renderParentPtr(dg: *DeclGen, writer: anytype, ptr_val: Value, ptr_ty: Type) error{ OutOfMemory, AnalysisFail }!void { | 470 | fn renderParentPtr(dg: *DeclGen, writer: anytype, ptr_val: Value, ptr_ty: Type) error{ OutOfMemory, AnalysisFail }!void { |
| 471 | try writer.writeByte('('); | 471 | if (!ptr_ty.isSlice()) { |
| 472 | try dg.renderTypecast(writer, ptr_ty); | 472 | try writer.writeByte('('); |
| 473 | try writer.writeByte(')'); | 473 | try dg.renderTypecast(writer, ptr_ty); |
| 474 | try writer.writeByte(')'); | ||
| 475 | } | ||
| 474 | switch (ptr_val.tag()) { | 476 | switch (ptr_val.tag()) { |
| 475 | .decl_ref_mut, .decl_ref, .variable => { | 477 | .decl_ref_mut, .decl_ref, .variable => { |
| 476 | const decl_index = switch (ptr_val.tag()) { | 478 | const decl_index = switch (ptr_val.tag()) { |
| ... | @@ -482,43 +484,80 @@ pub const DeclGen = struct { | ... | @@ -482,43 +484,80 @@ pub const DeclGen = struct { |
| 482 | try dg.renderDeclValue(writer, ptr_ty, ptr_val, decl_index); | 484 | try dg.renderDeclValue(writer, ptr_ty, ptr_val, decl_index); |
| 483 | }, | 485 | }, |
| 484 | .field_ptr => { | 486 | .field_ptr => { |
| 487 | const ptr_info = ptr_ty.ptrInfo(); | ||
| 485 | const field_ptr = ptr_val.castTag(.field_ptr).?.data; | 488 | const field_ptr = ptr_val.castTag(.field_ptr).?.data; |
| 486 | const container_ty = field_ptr.container_ty; | 489 | const container_ty = field_ptr.container_ty; |
| 487 | const index = field_ptr.field_index; | 490 | const index = field_ptr.field_index; |
| 491 | |||
| 492 | var container_ptr_ty_pl: Type.Payload.ElemType = .{ | ||
| 493 | .base = .{ .tag = .c_mut_pointer }, | ||
| 494 | .data = field_ptr.container_ty, | ||
| 495 | }; | ||
| 496 | const container_ptr_ty = Type.initPayload(&container_ptr_ty_pl.base); | ||
| 497 | |||
| 488 | const FieldInfo = struct { name: []const u8, ty: Type }; | 498 | const FieldInfo = struct { name: []const u8, ty: Type }; |
| 489 | const field_info: FieldInfo = switch (container_ty.zigTypeTag()) { | 499 | const field_info: FieldInfo = switch (container_ty.zigTypeTag()) { |
| 490 | .Struct => .{ | 500 | .Struct => switch (container_ty.containerLayout()) { |
| 491 | .name = container_ty.structFields().keys()[index], | 501 | .Auto, .Extern => FieldInfo{ |
| 492 | .ty = container_ty.structFields().values()[index].ty, | 502 | .name = container_ty.structFields().keys()[index], |
| 503 | .ty = container_ty.structFields().values()[index].ty, | ||
| 504 | }, | ||
| 505 | .Packed => if (ptr_info.data.host_size == 0) { | ||
| 506 | const target = dg.module.getTarget(); | ||
| 507 | |||
| 508 | const byte_offset = container_ty.packedStructFieldByteOffset(index, target); | ||
| 509 | var byte_offset_pl = Value.Payload.U64{ | ||
| 510 | .base = .{ .tag = .int_u64 }, | ||
| 511 | .data = byte_offset, | ||
| 512 | }; | ||
| 513 | const byte_offset_val = Value.initPayload(&byte_offset_pl.base); | ||
| 514 | |||
| 515 | var u8_ptr_pl = ptr_info; | ||
| 516 | u8_ptr_pl.data.pointee_type = Type.u8; | ||
| 517 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); | ||
| 518 | |||
| 519 | try writer.writeAll("&(("); | ||
| 520 | try dg.renderTypecast(writer, u8_ptr_ty); | ||
| 521 | try writer.writeByte(')'); | ||
| 522 | try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty); | ||
| 523 | return writer.print(")[{}]", .{try dg.fmtIntLiteral(Type.usize, byte_offset_val)}); | ||
| 524 | } else { | ||
| 525 | var host_pl = Type.Payload.Bits{ | ||
| 526 | .base = .{ .tag = .int_unsigned }, | ||
| 527 | .data = ptr_info.data.host_size * 8, | ||
| 528 | }; | ||
| 529 | const host_ty = Type.initPayload(&host_pl.base); | ||
| 530 | |||
| 531 | try writer.writeByte('('); | ||
| 532 | try dg.renderTypecast(writer, ptr_ty); | ||
| 533 | try writer.writeByte(')'); | ||
| 534 | return dg.renderParentPtr(writer, field_ptr.container_ptr, host_ty); | ||
| 535 | }, | ||
| 493 | }, | 536 | }, |
| 494 | .Union => .{ | 537 | .Union => FieldInfo{ |
| 495 | .name = container_ty.unionFields().keys()[index], | 538 | .name = container_ty.unionFields().keys()[index], |
| 496 | .ty = container_ty.unionFields().values()[index].ty, | 539 | .ty = container_ty.unionFields().values()[index].ty, |
| 497 | }, | 540 | }, |
| 498 | .Pointer => switch (container_ty.ptrSize()) { | 541 | .Pointer => field_info: { |
| 499 | .Slice => switch (index) { | 542 | assert(container_ty.isSlice()); |
| 543 | break :field_info switch (index) { | ||
| 500 | 0 => FieldInfo{ .name = "ptr", .ty = container_ty.childType() }, | 544 | 0 => FieldInfo{ .name = "ptr", .ty = container_ty.childType() }, |
| 501 | 1 => FieldInfo{ .name = "len", .ty = Type.usize }, | 545 | 1 => FieldInfo{ .name = "len", .ty = Type.usize }, |
| 502 | else => unreachable, | 546 | else => unreachable, |
| 503 | }, | 547 | }; |
| 504 | else => unreachable, | ||
| 505 | }, | 548 | }, |
| 506 | else => unreachable, | 549 | else => unreachable, |
| 507 | }; | 550 | }; |
| 508 | var container_ptr_ty_pl: Type.Payload.ElemType = .{ | ||
| 509 | .base = .{ .tag = .c_mut_pointer }, | ||
| 510 | .data = field_ptr.container_ty, | ||
| 511 | }; | ||
| 512 | const container_ptr_ty = Type.initPayload(&container_ptr_ty_pl.base); | ||
| 513 | 551 | ||
| 514 | if (field_info.ty.hasRuntimeBitsIgnoreComptime()) { | 552 | if (field_info.ty.hasRuntimeBitsIgnoreComptime()) { |
| 515 | try writer.writeAll("&("); | 553 | try writer.writeAll("&("); |
| 516 | try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty); | 554 | try dg.renderParentPtr(writer, field_ptr.container_ptr, container_ptr_ty); |
| 517 | if (field_ptr.container_ty.tag() == .union_tagged or field_ptr.container_ty.tag() == .union_safety_tagged) { | 555 | try writer.writeAll(")->"); |
| 518 | try writer.print(")->payload.{ }", .{fmtIdent(field_info.name)}); | 556 | switch (field_ptr.container_ty.tag()) { |
| 519 | } else { | 557 | .union_tagged, .union_safety_tagged => try writer.writeAll("payload."), |
| 520 | try writer.print(")->{ }", .{fmtIdent(field_info.name)}); | 558 | else => {}, |
| 521 | } | 559 | } |
| 560 | try writer.print("{ }", .{fmtIdent(field_info.name)}); | ||
| 522 | } else { | 561 | } else { |
| 523 | try dg.renderParentPtr(writer, field_ptr.container_ptr, field_info.ty); | 562 | try dg.renderParentPtr(writer, field_ptr.container_ptr, field_info.ty); |
| 524 | } | 563 | } |
| ... | @@ -565,49 +604,162 @@ pub const DeclGen = struct { | ... | @@ -565,49 +604,162 @@ pub const DeclGen = struct { |
| 565 | const target = dg.module.getTarget(); | 604 | const target = dg.module.getTarget(); |
| 566 | if (val.isUndefDeep()) { | 605 | if (val.isUndefDeep()) { |
| 567 | switch (ty.zigTypeTag()) { | 606 | switch (ty.zigTypeTag()) { |
| 568 | // Using '{}' for integer and floats seemed to error C compilers (both GCC and Clang) | 607 | // bool b = 0xaa; evals to true, but memcpy(&b, 0xaa, 1); evals to false. |
| 569 | // with 'error: expected expression' (including when built with 'zig cc') | 608 | .Bool => return dg.renderValue(writer, ty, Value.@"false", location), |
| 570 | .Int => { | 609 | .Int, .Enum, .ErrorSet => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, val)}), |
| 571 | const c_bits = toCIntBits(ty.intInfo(dg.module.getTarget()).bits) orelse | 610 | .Float => { |
| 572 | return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); | 611 | try writer.writeByte('('); |
| 573 | switch (c_bits) { | 612 | try dg.renderTypecast(writer, ty); |
| 574 | 8 => return writer.writeAll("0xaau"), | 613 | try writer.writeAll(")zig_suffix_"); |
| 575 | 16 => return writer.writeAll("0xaaaau"), | 614 | try dg.renderTypeForBuiltinFnName(writer, ty); |
| 576 | 32 => return writer.writeAll("0xaaaaaaaau"), | 615 | try writer.writeByte('('); |
| 577 | 64 => return writer.writeAll("0xaaaaaaaaaaaaaaaau"), | 616 | switch (ty.floatBits(target)) { |
| 578 | 128 => return renderInt128(writer, @as(u128, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)), | 617 | 16 => try writer.print("{x}", .{@bitCast(f16, undefPattern(u16))}), |
| 618 | 32 => try writer.print("{x}", .{@bitCast(f32, undefPattern(u32))}), | ||
| 619 | 64 => try writer.print("{x}", .{@bitCast(f64, undefPattern(u64))}), | ||
| 620 | 80 => try writer.print("{x}", .{@bitCast(f80, undefPattern(u80))}), | ||
| 621 | 128 => try writer.print("{x}", .{@bitCast(f128, undefPattern(u128))}), | ||
| 579 | else => unreachable, | 622 | else => unreachable, |
| 580 | } | 623 | } |
| 624 | return writer.writeByte(')'); | ||
| 581 | }, | 625 | }, |
| 582 | .Float => { | 626 | .Pointer => if (ty.isSlice()) { |
| 583 | switch (ty.floatBits(dg.module.getTarget())) { | 627 | if (location != .Initializer) { |
| 584 | 32 => return writer.writeAll("zig_bitcast_f32_u32(0xaaaaaaaau)"), | 628 | try writer.writeByte('('); |
| 585 | 64 => return writer.writeAll("zig_bitcast_f64_u64(0xaaaaaaaaaaaaaaaau)"), | 629 | try dg.renderTypecast(writer, ty); |
| 586 | else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}), | 630 | try writer.writeByte(')'); |
| 587 | } | 631 | } |
| 632 | |||
| 633 | try writer.writeAll("{("); | ||
| 634 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | ||
| 635 | const ptr_ty = ty.slicePtrFieldType(&buf); | ||
| 636 | try dg.renderTypecast(writer, ptr_ty); | ||
| 637 | return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val)}); | ||
| 638 | } else { | ||
| 639 | try writer.writeAll("(("); | ||
| 640 | try dg.renderTypecast(writer, ty); | ||
| 641 | return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)}); | ||
| 588 | }, | 642 | }, |
| 589 | .Pointer => switch (dg.module.getTarget().cpu.arch.ptrBitWidth()) { | 643 | .Optional => { |
| 590 | 32 => return writer.writeAll("(void *)0xaaaaaaaa"), | 644 | var opt_buf: Type.Payload.ElemType = undefined; |
| 591 | 64 => return writer.writeAll("(void *)0xaaaaaaaaaaaaaaaa"), | 645 | const payload_ty = ty.optionalChild(&opt_buf); |
| 592 | else => unreachable, | 646 | |
| 647 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | ||
| 648 | return dg.renderValue(writer, Type.bool, val, location); | ||
| 649 | } | ||
| 650 | |||
| 651 | if (ty.optionalReprIsPayload()) { | ||
| 652 | return dg.renderValue(writer, payload_ty, val, location); | ||
| 653 | } | ||
| 654 | |||
| 655 | if (location != .Initializer) { | ||
| 656 | try writer.writeByte('('); | ||
| 657 | try dg.renderTypecast(writer, ty); | ||
| 658 | try writer.writeByte(')'); | ||
| 659 | } | ||
| 660 | |||
| 661 | try writer.writeAll("{ .payload = "); | ||
| 662 | try dg.renderValue(writer, payload_ty, val, .Initializer); | ||
| 663 | try writer.writeAll(", .is_null = "); | ||
| 664 | try dg.renderValue(writer, Type.bool, val, .Initializer); | ||
| 665 | return writer.writeAll(" }"); | ||
| 593 | }, | 666 | }, |
| 594 | .Struct, .ErrorUnion => { | 667 | .Struct => switch (ty.containerLayout()) { |
| 595 | try writer.writeByte('('); | 668 | .Auto, .Extern => { |
| 596 | try dg.renderTypecast(writer, ty); | 669 | if (location != .Initializer) { |
| 597 | return writer.writeAll("){0xaa}"); | 670 | try writer.writeByte('('); |
| 671 | try dg.renderTypecast(writer, ty); | ||
| 672 | try writer.writeByte(')'); | ||
| 673 | } | ||
| 674 | |||
| 675 | try writer.writeByte('{'); | ||
| 676 | var empty = true; | ||
| 677 | for (ty.structFields().values()) |field| { | ||
| 678 | if (!field.ty.hasRuntimeBits()) continue; | ||
| 679 | |||
| 680 | if (!empty) try writer.writeByte(','); | ||
| 681 | try dg.renderValue(writer, field.ty, val, .Initializer); | ||
| 682 | |||
| 683 | empty = false; | ||
| 684 | } | ||
| 685 | if (empty) try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)}); | ||
| 686 | return writer.writeByte('}'); | ||
| 687 | }, | ||
| 688 | .Packed => return writer.print("{x}", .{try dg.fmtIntLiteral(ty, Value.undef)}), | ||
| 689 | }, | ||
| 690 | .Union => { | ||
| 691 | if (location != .Initializer) { | ||
| 692 | try writer.writeByte('('); | ||
| 693 | try dg.renderTypecast(writer, ty); | ||
| 694 | try writer.writeByte(')'); | ||
| 695 | } | ||
| 696 | |||
| 697 | try writer.writeByte('{'); | ||
| 698 | if (ty.unionTagTypeSafety()) |tag_ty| { | ||
| 699 | try writer.writeAll(" .tag = "); | ||
| 700 | try dg.renderValue(writer, tag_ty, val, .Initializer); | ||
| 701 | try writer.writeAll(", .payload = {"); | ||
| 702 | } | ||
| 703 | for (ty.unionFields().values()) |field| { | ||
| 704 | if (!field.ty.hasRuntimeBits()) continue; | ||
| 705 | try dg.renderValue(writer, field.ty, val, .Initializer); | ||
| 706 | break; | ||
| 707 | } else try writer.print("{x}", .{try dg.fmtIntLiteral(Type.u8, Value.undef)}); | ||
| 708 | if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}'); | ||
| 709 | return writer.writeByte('}'); | ||
| 710 | }, | ||
| 711 | .ErrorUnion => { | ||
| 712 | if (location != .Initializer) { | ||
| 713 | try writer.writeByte('('); | ||
| 714 | try dg.renderTypecast(writer, ty); | ||
| 715 | try writer.writeByte(')'); | ||
| 716 | } | ||
| 717 | |||
| 718 | try writer.writeAll("{ .payload = "); | ||
| 719 | try dg.renderValue(writer, ty.errorUnionPayload(), val, .Initializer); | ||
| 720 | return writer.print(", .error = {x} }}", .{ | ||
| 721 | try dg.fmtIntLiteral(ty.errorUnionSet(), val), | ||
| 722 | }); | ||
| 598 | }, | 723 | }, |
| 599 | else => { | 724 | .Array => { |
| 600 | // This should lower to 0xaa bytes in safe modes, and for unsafe modes should | 725 | if (location != .Initializer) { |
| 601 | // lower to leaving variables uninitialized (that might need to be implemented | 726 | try writer.writeByte('('); |
| 602 | // outside of this function). | 727 | try dg.renderTypecast(writer, ty); |
| 603 | return writer.writeAll("{}"); | 728 | try writer.writeByte(')'); |
| 729 | } | ||
| 730 | |||
| 731 | try writer.writeByte('{'); | ||
| 732 | const c_len = ty.arrayLenIncludingSentinel(); | ||
| 733 | var index: usize = 0; | ||
| 734 | while (index < c_len) : (index += 1) { | ||
| 735 | if (index > 0) try writer.writeAll(", "); | ||
| 736 | try dg.renderValue(writer, ty.childType(), val, .Initializer); | ||
| 737 | } | ||
| 738 | return writer.writeByte('}'); | ||
| 604 | }, | 739 | }, |
| 740 | .ComptimeInt, | ||
| 741 | .ComptimeFloat, | ||
| 742 | .Type, | ||
| 743 | .EnumLiteral, | ||
| 744 | .Void, | ||
| 745 | .NoReturn, | ||
| 746 | .Undefined, | ||
| 747 | .Null, | ||
| 748 | .BoundFn, | ||
| 749 | .Opaque, | ||
| 750 | => unreachable, | ||
| 751 | .Fn, | ||
| 752 | .Frame, | ||
| 753 | .AnyFrame, | ||
| 754 | .Vector, | ||
| 755 | => |tag| return dg.fail("TODO: C backend: implement value of type {s}", .{ | ||
| 756 | @tagName(tag), | ||
| 757 | }), | ||
| 605 | } | 758 | } |
| 759 | unreachable; | ||
| 606 | } | 760 | } |
| 607 | switch (ty.zigTypeTag()) { | 761 | switch (ty.zigTypeTag()) { |
| 608 | .Int => switch (val.tag()) { | 762 | .Int => switch (val.tag()) { |
| 609 | .int_big_positive => try dg.renderBigIntConst(writer, val.castTag(.int_big_positive).?.asBigInt(), ty.isSignedInt()), | ||
| 610 | .int_big_negative => try dg.renderBigIntConst(writer, val.castTag(.int_big_negative).?.asBigInt(), true), | ||
| 611 | .field_ptr, | 763 | .field_ptr, |
| 612 | .elem_ptr, | 764 | .elem_ptr, |
| 613 | .opt_payload_ptr, | 765 | .opt_payload_ptr, |
| ... | @@ -615,48 +767,86 @@ pub const DeclGen = struct { | ... | @@ -615,48 +767,86 @@ pub const DeclGen = struct { |
| 615 | .decl_ref_mut, | 767 | .decl_ref_mut, |
| 616 | .decl_ref, | 768 | .decl_ref, |
| 617 | => try dg.renderParentPtr(writer, val, ty), | 769 | => try dg.renderParentPtr(writer, val, ty), |
| 618 | else => { | 770 | else => try writer.print("{}", .{try dg.fmtIntLiteral(ty, val)}), |
| 619 | if (ty.isSignedInt()) | ||
| 620 | return writer.print("{d}", .{val.toSignedInt()}); | ||
| 621 | return writer.print("{d}u", .{val.toUnsignedInt(target)}); | ||
| 622 | }, | ||
| 623 | }, | 771 | }, |
| 624 | .Float => { | 772 | .Float => { |
| 625 | if (ty.floatBits(dg.module.getTarget()) <= 64) { | 773 | try writer.writeByte('('); |
| 626 | if (std.math.isNan(val.toFloat(f64)) or std.math.isInf(val.toFloat(f64))) { | 774 | try dg.renderTypecast(writer, ty); |
| 627 | // just generate a bit cast (exactly like we do in airBitcast) | 775 | try writer.writeByte(')'); |
| 628 | switch (ty.tag()) { | 776 | const f128_val = val.toFloat(f128); |
| 629 | .f32 => return writer.print("zig_bitcast_f32_u32(0x{x})", .{@bitCast(u32, val.toFloat(f32))}), | 777 | if (std.math.signbit(f128_val)) try writer.writeByte('-'); |
| 630 | .f64 => return writer.print("zig_bitcast_f64_u64(0x{x})", .{@bitCast(u64, val.toFloat(f64))}), | 778 | if (std.math.isFinite(f128_val)) { |
| 631 | else => return dg.fail("TODO float types > 64 bits are not support in renderValue() as of now", .{}), | 779 | try writer.writeAll("zig_suffix_"); |
| 632 | } | 780 | try dg.renderTypeForBuiltinFnName(writer, ty); |
| 633 | } else { | 781 | try writer.writeByte('('); |
| 634 | return writer.print("{x}", .{val.toFloat(f64)}); | 782 | switch (ty.floatBits(target)) { |
| 783 | 16 => try writer.print("{x}", .{@fabs(val.toFloat(f16))}), | ||
| 784 | 32 => try writer.print("{x}", .{@fabs(val.toFloat(f32))}), | ||
| 785 | 64 => try writer.print("{x}", .{@fabs(val.toFloat(f64))}), | ||
| 786 | 80 => try writer.print("{x}", .{@fabs(val.toFloat(f80))}), | ||
| 787 | 128 => try writer.print("{x}", .{@fabs(f128_val)}), | ||
| 788 | else => unreachable, | ||
| 635 | } | 789 | } |
| 790 | } else { | ||
| 791 | const operation = if (std.math.isSignalNan(f128_val)) | ||
| 792 | "nans" | ||
| 793 | else if (std.math.isNan(f128_val)) | ||
| 794 | "nan" | ||
| 795 | else if (std.math.isInf(f128_val)) | ||
| 796 | "inf" | ||
| 797 | else | ||
| 798 | unreachable; | ||
| 799 | try writer.writeAll("zig_builtin_constant_"); | ||
| 800 | try dg.renderTypeForBuiltinFnName(writer, ty); | ||
| 801 | try writer.writeByte('('); | ||
| 802 | try writer.writeAll(operation); | ||
| 803 | try writer.writeAll(")("); | ||
| 804 | if (std.math.isNan(f128_val)) switch (ty.floatBits(target)) { | ||
| 805 | // We only actually need to pass the significand, but it will get | ||
| 806 | // properly masked anyway, so just pass the whole value. | ||
| 807 | 16 => try writer.print("\"0x{x}\"", .{@bitCast(u16, @fabs(val.toFloat(f16)))}), | ||
| 808 | 32 => try writer.print("\"0x{x}\"", .{@bitCast(u32, @fabs(val.toFloat(f32)))}), | ||
| 809 | 64 => try writer.print("\"0x{x}\"", .{@bitCast(u64, @fabs(val.toFloat(f64)))}), | ||
| 810 | 80 => try writer.print("\"0x{x}\"", .{@bitCast(u80, @fabs(val.toFloat(f80)))}), | ||
| 811 | 128 => try writer.print("\"0x{x}\"", .{@bitCast(u128, @fabs(f128_val))}), | ||
| 812 | else => unreachable, | ||
| 813 | }; | ||
| 636 | } | 814 | } |
| 637 | return dg.fail("TODO: C backend: implement lowering large float values", .{}); | 815 | return writer.writeByte(')'); |
| 638 | }, | 816 | }, |
| 639 | .Pointer => switch (val.tag()) { | 817 | .Pointer => switch (val.tag()) { |
| 640 | .null_value => try writer.writeAll("NULL"), | 818 | .null_value, .zero => if (ty.isSlice()) { |
| 641 | // Technically this should produce NULL but the integer literal 0 will always coerce | 819 | var slice_pl = Value.Payload.Slice{ |
| 642 | // to the assigned pointer type. Note this is just a hack to fix warnings from ordered comparisons (<, >, etc) | 820 | .base = .{ .tag = .slice }, |
| 643 | // between pointers and 0, which is an extension to begin with. | 821 | .data = .{ .ptr = val, .len = Value.undef }, |
| 644 | .zero => try writer.writeByte('0'), | 822 | }; |
| 823 | const slice_val = Value.initPayload(&slice_pl.base); | ||
| 824 | |||
| 825 | return dg.renderValue(writer, ty, slice_val, location); | ||
| 826 | } else { | ||
| 827 | try writer.writeAll("(("); | ||
| 828 | try dg.renderTypecast(writer, ty); | ||
| 829 | try writer.writeAll(")NULL)"); | ||
| 830 | }, | ||
| 645 | .variable => { | 831 | .variable => { |
| 646 | const decl = val.castTag(.variable).?.data.owner_decl; | 832 | const decl = val.castTag(.variable).?.data.owner_decl; |
| 647 | return dg.renderDeclValue(writer, ty, val, decl); | 833 | return dg.renderDeclValue(writer, ty, val, decl); |
| 648 | }, | 834 | }, |
| 649 | .slice => { | 835 | .slice => { |
| 836 | if (location != .Initializer) { | ||
| 837 | try writer.writeByte('('); | ||
| 838 | try dg.renderTypecast(writer, ty); | ||
| 839 | try writer.writeByte(')'); | ||
| 840 | } | ||
| 841 | |||
| 650 | const slice = val.castTag(.slice).?.data; | 842 | const slice = val.castTag(.slice).?.data; |
| 651 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 843 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 652 | 844 | ||
| 653 | try writer.writeByte('('); | 845 | try writer.writeByte('{'); |
| 654 | try dg.renderTypecast(writer, ty); | 846 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, .Initializer); |
| 655 | try writer.writeAll("){"); | ||
| 656 | try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, location); | ||
| 657 | try writer.writeAll(", "); | 847 | try writer.writeAll(", "); |
| 658 | try dg.renderValue(writer, Type.usize, slice.len, location); | 848 | try dg.renderValue(writer, Type.usize, slice.len, .Initializer); |
| 659 | try writer.writeAll("}"); | 849 | try writer.writeByte('}'); |
| 660 | }, | 850 | }, |
| 661 | .function => { | 851 | .function => { |
| 662 | const func = val.castTag(.function).?.data; | 852 | const func = val.castTag(.function).?.data; |
| ... | @@ -669,7 +859,7 @@ pub const DeclGen = struct { | ... | @@ -669,7 +859,7 @@ pub const DeclGen = struct { |
| 669 | .int_u64, .one => { | 859 | .int_u64, .one => { |
| 670 | try writer.writeAll("(("); | 860 | try writer.writeAll("(("); |
| 671 | try dg.renderTypecast(writer, ty); | 861 | try dg.renderTypecast(writer, ty); |
| 672 | try writer.print(")0x{x}u)", .{val.toUnsignedInt(target)}); | 862 | return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val)}); |
| 673 | }, | 863 | }, |
| 674 | .field_ptr, | 864 | .field_ptr, |
| 675 | .elem_ptr, | 865 | .elem_ptr, |
| ... | @@ -681,111 +871,106 @@ pub const DeclGen = struct { | ... | @@ -681,111 +871,106 @@ pub const DeclGen = struct { |
| 681 | else => unreachable, | 871 | else => unreachable, |
| 682 | }, | 872 | }, |
| 683 | .Array => { | 873 | .Array => { |
| 874 | if (location == .FunctionArgument) { | ||
| 875 | try writer.writeByte('('); | ||
| 876 | try dg.renderTypecast(writer, ty); | ||
| 877 | try writer.writeByte(')'); | ||
| 878 | } | ||
| 879 | |||
| 684 | // First try specific tag representations for more efficiency. | 880 | // First try specific tag representations for more efficiency. |
| 685 | switch (val.tag()) { | 881 | switch (val.tag()) { |
| 686 | .undef, .empty_struct_value, .empty_array => { | 882 | .undef, .empty_struct_value, .empty_array => { |
| 687 | try writer.writeByte('{'); | 883 | try writer.writeByte('{'); |
| 688 | const ai = ty.arrayInfo(); | 884 | const ai = ty.arrayInfo(); |
| 689 | if (ai.sentinel) |s| { | 885 | if (ai.sentinel) |s| { |
| 690 | try dg.renderValue(writer, ai.elem_type, s, location); | 886 | try dg.renderValue(writer, ai.elem_type, s, .Initializer); |
| 887 | } else { | ||
| 888 | try writer.writeByte('0'); | ||
| 691 | } | 889 | } |
| 692 | try writer.writeByte('}'); | 890 | try writer.writeByte('}'); |
| 693 | }, | 891 | }, |
| 694 | else => { | 892 | else => { |
| 695 | // Fall back to generic implementation. | 893 | // Fall back to generic implementation. |
| 696 | var arena = std.heap.ArenaAllocator.init(dg.module.gpa); | 894 | var arena = std.heap.ArenaAllocator.init(dg.gpa); |
| 697 | defer arena.deinit(); | 895 | defer arena.deinit(); |
| 698 | const arena_allocator = arena.allocator(); | 896 | const arena_allocator = arena.allocator(); |
| 699 | 897 | ||
| 700 | if (location == .FunctionArgument) { | ||
| 701 | try writer.writeByte('('); | ||
| 702 | try dg.renderTypecast(writer, ty); | ||
| 703 | try writer.writeByte(')'); | ||
| 704 | } | ||
| 705 | |||
| 706 | try writer.writeByte('{'); | 898 | try writer.writeByte('{'); |
| 707 | const ai = ty.arrayInfo(); | 899 | const ai = ty.arrayInfo(); |
| 708 | var index: usize = 0; | 900 | var index: usize = 0; |
| 709 | while (index < ai.len) : (index += 1) { | 901 | while (index < ai.len) : (index += 1) { |
| 710 | if (index != 0) try writer.writeAll(","); | 902 | if (index != 0) try writer.writeByte(','); |
| 711 | const elem_val = try val.elemValue(dg.module, arena_allocator, index); | 903 | const elem_val = try val.elemValue(dg.module, arena_allocator, index); |
| 712 | try dg.renderValue(writer, ai.elem_type, elem_val, .Other); | 904 | try dg.renderValue(writer, ai.elem_type, elem_val, .Initializer); |
| 713 | } | 905 | } |
| 714 | if (ai.sentinel) |s| { | 906 | if (ai.sentinel) |s| { |
| 715 | if (index != 0) try writer.writeAll(","); | 907 | if (index != 0) try writer.writeByte(','); |
| 716 | try dg.renderValue(writer, ai.elem_type, s, .Other); | 908 | try dg.renderValue(writer, ai.elem_type, s, .Initializer); |
| 717 | } | 909 | } |
| 718 | try writer.writeByte('}'); | 910 | try writer.writeByte('}'); |
| 719 | }, | 911 | }, |
| 720 | } | 912 | } |
| 721 | }, | 913 | }, |
| 722 | .Bool => return writer.print("{}", .{val.toBool()}), | 914 | .Bool => return writer.print("zig_{}", .{val.toBool()}), |
| 723 | .Optional => { | 915 | .Optional => { |
| 724 | var opt_buf: Type.Payload.ElemType = undefined; | 916 | var opt_buf: Type.Payload.ElemType = undefined; |
| 725 | const payload_ty = ty.optionalChild(&opt_buf); | 917 | const payload_ty = ty.optionalChild(&opt_buf); |
| 726 | 918 | ||
| 727 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 919 | const is_null_val = Value.makeBool(val.tag() == .null_value); |
| 728 | const is_null = val.castTag(.opt_payload) == null; | 920 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) |
| 729 | return writer.print("{}", .{is_null}); | 921 | return dg.renderValue(writer, Type.bool, is_null_val, location); |
| 730 | } | ||
| 731 | 922 | ||
| 732 | if (ty.optionalReprIsPayload()) { | 923 | if (ty.optionalReprIsPayload()) { |
| 733 | if (val.castTag(.opt_payload)) |payload| { | 924 | const payload_val = if (val.castTag(.opt_payload)) |pl| pl.data else val; |
| 734 | return dg.renderValue(writer, payload_ty, payload.data, location); | 925 | return dg.renderValue(writer, payload_ty, payload_val, location); |
| 735 | } else { | ||
| 736 | return dg.renderValue(writer, payload_ty, val, location); | ||
| 737 | } | ||
| 738 | } | 926 | } |
| 739 | 927 | ||
| 740 | try writer.writeByte('('); | 928 | if (location != .Initializer) { |
| 741 | try dg.renderTypecast(writer, ty); | 929 | try writer.writeByte('('); |
| 742 | try writer.writeAll("){"); | 930 | try dg.renderTypecast(writer, ty); |
| 743 | if (val.castTag(.opt_payload)) |pl| { | 931 | try writer.writeByte(')'); |
| 744 | const payload_val = pl.data; | ||
| 745 | try writer.writeAll(" .is_null = false, .payload = "); | ||
| 746 | try dg.renderValue(writer, payload_ty, payload_val, location); | ||
| 747 | try writer.writeAll(" }"); | ||
| 748 | } else { | ||
| 749 | try writer.writeAll(" .is_null = true }"); | ||
| 750 | } | 932 | } |
| 933 | |||
| 934 | const payload_val = if (val.castTag(.opt_payload)) |pl| pl.data else Value.undef; | ||
| 935 | |||
| 936 | try writer.writeAll("{ .payload = "); | ||
| 937 | try dg.renderValue(writer, payload_ty, payload_val, .Initializer); | ||
| 938 | try writer.writeAll(", .is_null = "); | ||
| 939 | try dg.renderValue(writer, Type.bool, is_null_val, .Initializer); | ||
| 940 | try writer.writeAll(" }"); | ||
| 751 | }, | 941 | }, |
| 752 | .ErrorSet => { | 942 | .ErrorSet => { |
| 753 | switch (val.tag()) { | 943 | const error_name = if (val.castTag(.@"error")) |error_pl| |
| 754 | .@"error" => { | 944 | error_pl.data.name |
| 755 | const payload = val.castTag(.@"error").?; | 945 | else |
| 756 | // error values will be #defined at the top of the file | 946 | dg.module.error_name_list.items[0]; |
| 757 | return writer.print("zig_error_{s}", .{payload.data.name}); | 947 | // Error values are already defined by genErrDecls. |
| 758 | }, | 948 | try writer.print("zig_error_{}", .{fmtIdent(error_name)}); |
| 759 | else => { | ||
| 760 | // In this case we are rendering an error union which has a | ||
| 761 | // 0 bits payload. | ||
| 762 | return writer.writeAll("0"); | ||
| 763 | }, | ||
| 764 | } | ||
| 765 | }, | 949 | }, |
| 766 | .ErrorUnion => { | 950 | .ErrorUnion => { |
| 767 | const error_type = ty.errorUnionSet(); | 951 | const error_ty = ty.errorUnionSet(); |
| 768 | const payload_type = ty.errorUnionPayload(); | 952 | const payload_ty = ty.errorUnionPayload(); |
| 769 | 953 | ||
| 770 | if (!payload_type.hasRuntimeBits()) { | 954 | if (!payload_ty.hasRuntimeBits()) { |
| 771 | // We use the error type directly as the type. | 955 | // We use the error type directly as the type. |
| 772 | const err_val = if (val.errorUnionIsPayload()) Value.initTag(.zero) else val; | 956 | const err_val = if (val.errorUnionIsPayload()) Value.initTag(.zero) else val; |
| 773 | return dg.renderValue(writer, error_type, err_val, location); | 957 | return dg.renderValue(writer, error_ty, err_val, location); |
| 774 | } | 958 | } |
| 775 | 959 | ||
| 776 | try writer.writeByte('('); | 960 | if (location != .Initializer) { |
| 777 | try dg.renderTypecast(writer, ty); | 961 | try writer.writeByte('('); |
| 778 | try writer.writeAll("){"); | 962 | try dg.renderTypecast(writer, ty); |
| 779 | if (val.castTag(.eu_payload)) |pl| { | 963 | try writer.writeByte(')'); |
| 780 | const payload_val = pl.data; | ||
| 781 | try writer.writeAll(" .payload = "); | ||
| 782 | try dg.renderValue(writer, payload_type, payload_val, location); | ||
| 783 | try writer.writeAll(", .error = 0 }"); | ||
| 784 | } else { | ||
| 785 | try writer.writeAll(" .error = "); | ||
| 786 | try dg.renderValue(writer, error_type, val, location); | ||
| 787 | try writer.writeAll(" }"); | ||
| 788 | } | 964 | } |
| 965 | |||
| 966 | const payload_val = if (val.castTag(.eu_payload)) |pl| pl.data else Value.undef; | ||
| 967 | const error_val = if (val.errorUnionIsPayload()) Value.zero else val; | ||
| 968 | |||
| 969 | try writer.writeAll("{ .payload = "); | ||
| 970 | try dg.renderValue(writer, payload_ty, payload_val, .Initializer); | ||
| 971 | try writer.writeAll(", .error = "); | ||
| 972 | try dg.renderValue(writer, error_ty, error_val, .Initializer); | ||
| 973 | try writer.writeAll(" }"); | ||
| 789 | }, | 974 | }, |
| 790 | .Enum => { | 975 | .Enum => { |
| 791 | switch (val.tag()) { | 976 | switch (val.tag()) { |
| ... | @@ -832,37 +1017,79 @@ pub const DeclGen = struct { | ... | @@ -832,37 +1017,79 @@ pub const DeclGen = struct { |
| 832 | }, | 1017 | }, |
| 833 | else => unreachable, | 1018 | else => unreachable, |
| 834 | }, | 1019 | }, |
| 835 | .Struct => { | 1020 | .Struct => switch (ty.containerLayout()) { |
| 836 | const field_vals = val.castTag(.aggregate).?.data; | 1021 | .Auto, .Extern => { |
| 1022 | const field_vals = val.castTag(.aggregate).?.data; | ||
| 1023 | |||
| 1024 | if (location != .Initializer) { | ||
| 1025 | try writer.writeByte('('); | ||
| 1026 | try dg.renderTypecast(writer, ty); | ||
| 1027 | try writer.writeByte(')'); | ||
| 1028 | } | ||
| 837 | 1029 | ||
| 838 | try writer.writeAll("("); | 1030 | try writer.writeByte('{'); |
| 839 | try dg.renderTypecast(writer, ty); | 1031 | var empty = true; |
| 840 | try writer.writeAll("){"); | 1032 | for (field_vals) |field_val, field_index| { |
| 1033 | const field_ty = ty.structFieldType(field_index); | ||
| 1034 | if (!field_ty.hasRuntimeBits()) continue; | ||
| 841 | 1035 | ||
| 842 | var i: usize = 0; | 1036 | if (!empty) try writer.writeByte(','); |
| 843 | for (field_vals) |field_val, field_index| { | 1037 | try dg.renderValue(writer, field_ty, field_val, .Initializer); |
| 844 | const field_ty = ty.structFieldType(field_index); | ||
| 845 | if (!field_ty.hasRuntimeBits()) continue; | ||
| 846 | 1038 | ||
| 847 | if (i != 0) try writer.writeAll(","); | 1039 | empty = false; |
| 848 | try dg.renderValue(writer, field_ty, field_val, location); | 1040 | } |
| 849 | i += 1; | 1041 | if (empty) try writer.print("{}", .{try dg.fmtIntLiteral(Type.u8, Value.zero)}); |
| 850 | } | 1042 | try writer.writeByte('}'); |
| 1043 | }, | ||
| 1044 | .Packed => { | ||
| 1045 | const field_vals = val.castTag(.aggregate).?.data; | ||
| 1046 | const int_info = ty.intInfo(target); | ||
| 1047 | |||
| 1048 | var bit_offset_ty_pl = Type.Payload.Bits{ | ||
| 1049 | .base = .{ .tag = .int_unsigned }, | ||
| 1050 | .data = Type.smallestUnsignedBits(int_info.bits - 1), | ||
| 1051 | }; | ||
| 1052 | const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base); | ||
| 851 | 1053 | ||
| 852 | try writer.writeAll("}"); | 1054 | var bit_offset_val_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = 0 }; |
| 1055 | const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base); | ||
| 1056 | |||
| 1057 | try writer.writeByte('('); | ||
| 1058 | var empty = true; | ||
| 1059 | for (field_vals) |field_val, index| { | ||
| 1060 | const field_ty = ty.structFieldType(index); | ||
| 1061 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; | ||
| 1062 | |||
| 1063 | if (!empty) try writer.writeAll(" | "); | ||
| 1064 | try writer.writeByte('('); | ||
| 1065 | try dg.renderTypecast(writer, ty); | ||
| 1066 | try writer.writeByte(')'); | ||
| 1067 | try dg.renderValue(writer, field_ty, field_val, .Other); | ||
| 1068 | try writer.writeAll(" << "); | ||
| 1069 | try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument); | ||
| 1070 | |||
| 1071 | bit_offset_val_pl.data += field_ty.bitSize(target); | ||
| 1072 | empty = false; | ||
| 1073 | } | ||
| 1074 | if (empty) try dg.renderValue(writer, ty, Value.undef, .Initializer); | ||
| 1075 | try writer.writeByte(')'); | ||
| 1076 | }, | ||
| 853 | }, | 1077 | }, |
| 854 | .Union => { | 1078 | .Union => { |
| 855 | const union_obj = val.castTag(.@"union").?.data; | 1079 | const union_obj = val.castTag(.@"union").?.data; |
| 856 | const layout = ty.unionGetLayout(target); | 1080 | const layout = ty.unionGetLayout(target); |
| 857 | 1081 | ||
| 858 | try writer.writeAll("("); | 1082 | if (location != .Initializer) { |
| 859 | try dg.renderTypecast(writer, ty); | 1083 | try writer.writeByte('('); |
| 860 | try writer.writeAll("){"); | 1084 | try dg.renderTypecast(writer, ty); |
| 1085 | try writer.writeByte(')'); | ||
| 1086 | } | ||
| 861 | 1087 | ||
| 1088 | try writer.writeByte('{'); | ||
| 862 | if (ty.unionTagTypeSafety()) |tag_ty| { | 1089 | if (ty.unionTagTypeSafety()) |tag_ty| { |
| 863 | if (layout.tag_size != 0) { | 1090 | if (layout.tag_size != 0) { |
| 864 | try writer.writeAll(".tag = "); | 1091 | try writer.writeAll(".tag = "); |
| 865 | try dg.renderValue(writer, tag_ty, union_obj.tag, location); | 1092 | try dg.renderValue(writer, tag_ty, union_obj.tag, .Initializer); |
| 866 | try writer.writeAll(", "); | 1093 | try writer.writeAll(", "); |
| 867 | } | 1094 | } |
| 868 | try writer.writeAll(".payload = {"); | 1095 | try writer.writeAll(".payload = {"); |
| ... | @@ -873,12 +1100,10 @@ pub const DeclGen = struct { | ... | @@ -873,12 +1100,10 @@ pub const DeclGen = struct { |
| 873 | const field_name = ty.unionFields().keys()[index]; | 1100 | const field_name = ty.unionFields().keys()[index]; |
| 874 | if (field_ty.hasRuntimeBits()) { | 1101 | if (field_ty.hasRuntimeBits()) { |
| 875 | try writer.print(".{ } = ", .{fmtIdent(field_name)}); | 1102 | try writer.print(".{ } = ", .{fmtIdent(field_name)}); |
| 876 | try dg.renderValue(writer, field_ty, union_obj.val, location); | 1103 | try dg.renderValue(writer, field_ty, union_obj.val, .Initializer); |
| 877 | } | 1104 | } else try writer.writeByte('0'); |
| 878 | if (ty.unionTagTypeSafety()) |_| { | 1105 | if (ty.unionTagTypeSafety()) |_| try writer.writeByte('}'); |
| 879 | try writer.writeAll("}"); | 1106 | try writer.writeByte('}'); |
| 880 | } | ||
| 881 | try writer.writeAll("}"); | ||
| 882 | }, | 1107 | }, |
| 883 | 1108 | ||
| 884 | .ComptimeInt => unreachable, | 1109 | .ComptimeInt => unreachable, |
| ... | @@ -901,75 +1126,69 @@ pub const DeclGen = struct { | ... | @@ -901,75 +1126,69 @@ pub const DeclGen = struct { |
| 901 | } | 1126 | } |
| 902 | } | 1127 | } |
| 903 | 1128 | ||
| 904 | fn renderFunctionSignature(dg: *DeclGen, w: anytype, is_global: bool) !void { | 1129 | fn renderFunctionSignature(dg: *DeclGen, w: anytype, kind: TypedefKind) !void { |
| 905 | if (!is_global) { | ||
| 906 | try w.writeAll("static "); | ||
| 907 | } | ||
| 908 | if (dg.decl.val.castTag(.function)) |func_payload| { | ||
| 909 | const func: *Module.Fn = func_payload.data; | ||
| 910 | if (func.is_cold) { | ||
| 911 | try w.writeAll("ZIG_COLD "); | ||
| 912 | } | ||
| 913 | } | ||
| 914 | const fn_info = dg.decl.ty.fnInfo(); | 1130 | const fn_info = dg.decl.ty.fnInfo(); |
| 915 | if (fn_info.return_type.hasRuntimeBits()) { | 1131 | if (fn_info.cc == .Naked) try w.writeAll("zig_naked "); |
| 916 | try dg.renderType(w, fn_info.return_type); | 1132 | if (dg.decl.val.castTag(.function)) |func_payload| |
| 917 | } else if (fn_info.return_type.isError()) { | 1133 | if (func_payload.data.is_cold) try w.writeAll("zig_cold "); |
| 918 | try dg.renderType(w, Type.anyerror); | 1134 | |
| 919 | } else if (fn_info.return_type.zigTypeTag() == .NoReturn) { | 1135 | const target = dg.module.getTarget(); |
| 920 | try w.writeAll("zig_noreturn void"); | 1136 | var ret_buf: LowerFnRetTyBuffer = undefined; |
| 921 | } else { | 1137 | const ret_ty = lowerFnRetTy(fn_info.return_type, &ret_buf, target); |
| 922 | try w.writeAll("void"); | 1138 | |
| 923 | } | 1139 | try dg.renderType(w, ret_ty, kind); |
| 924 | try w.writeAll(" "); | 1140 | try w.writeByte(' '); |
| 925 | try dg.renderDeclName(w, dg.decl_index); | 1141 | try dg.renderDeclName(w, dg.decl_index); |
| 926 | try w.writeAll("("); | 1142 | try w.writeByte('('); |
| 927 | 1143 | ||
| 928 | var params_written: usize = 0; | 1144 | var index: usize = 0; |
| 929 | for (fn_info.param_types) |param_type, index| { | 1145 | for (fn_info.param_types) |param_type| { |
| 930 | if (!param_type.hasRuntimeBitsIgnoreComptime()) continue; | 1146 | if (!param_type.hasRuntimeBitsIgnoreComptime()) continue; |
| 931 | if (params_written > 0) { | 1147 | if (index > 0) try w.writeAll(", "); |
| 932 | try w.writeAll(", "); | ||
| 933 | } | ||
| 934 | const name = CValue{ .arg = index }; | 1148 | const name = CValue{ .arg = index }; |
| 935 | try dg.renderTypeAndName(w, param_type, name, .Mut, 0); | 1149 | try dg.renderTypeAndName(w, param_type, name, .ConstArgument, 0, kind); |
| 936 | params_written += 1; | 1150 | index += 1; |
| 937 | } | 1151 | } |
| 938 | 1152 | ||
| 939 | if (fn_info.is_var_args) { | 1153 | if (fn_info.is_var_args) { |
| 940 | if (params_written != 0) try w.writeAll(", "); | 1154 | if (index > 0) try w.writeAll(", "); |
| 941 | try w.writeAll("..."); | 1155 | try w.writeAll("..."); |
| 942 | } else if (params_written == 0) { | 1156 | } else if (index == 0) { |
| 943 | try w.writeAll("void"); | 1157 | try dg.renderType(w, Type.void, kind); |
| 944 | } | 1158 | } |
| 945 | try w.writeByte(')'); | 1159 | try w.writeByte(')'); |
| 946 | } | 1160 | } |
| 947 | 1161 | ||
| 948 | fn renderPtrToFnTypedef(dg: *DeclGen, t: Type, fn_ty: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { | 1162 | fn renderPtrToFnTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 949 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); | 1163 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 950 | defer buffer.deinit(); | 1164 | defer buffer.deinit(); |
| 951 | const bw = buffer.writer(); | 1165 | const bw = buffer.writer(); |
| 952 | 1166 | ||
| 953 | const fn_info = fn_ty.fnInfo(); | 1167 | const fn_info = t.fnInfo(); |
| 1168 | |||
| 1169 | const target = dg.module.getTarget(); | ||
| 1170 | var ret_buf: LowerFnRetTyBuffer = undefined; | ||
| 1171 | const ret_ty = lowerFnRetTy(fn_info.return_type, &ret_buf, target); | ||
| 954 | 1172 | ||
| 955 | try bw.writeAll("typedef "); | 1173 | try bw.writeAll("typedef "); |
| 956 | try dg.renderType(bw, fn_info.return_type); | 1174 | try dg.renderType(bw, ret_ty, .Forward); |
| 957 | try bw.writeAll(" (*"); | 1175 | try bw.writeAll(" (*"); |
| 958 | 1176 | const name_begin = buffer.items.len; | |
| 959 | const name_start = buffer.items.len; | 1177 | try bw.print("zig_F_{}", .{typeToCIdentifier(t, dg.module)}); |
| 960 | try bw.print("zig_F_{s})(", .{typeToCIdentifier(t, dg.module)}); | 1178 | const name_end = buffer.items.len; |
| 961 | const name_end = buffer.items.len - 2; | 1179 | try bw.writeAll(")("); |
| 962 | 1180 | ||
| 963 | const param_len = fn_info.param_types.len; | 1181 | const param_len = fn_info.param_types.len; |
| 964 | 1182 | ||
| 965 | var params_written: usize = 0; | 1183 | var params_written: usize = 0; |
| 966 | var index: usize = 0; | 1184 | var index: usize = 0; |
| 967 | while (index < param_len) : (index += 1) { | 1185 | while (index < param_len) : (index += 1) { |
| 968 | if (!fn_info.param_types[index].hasRuntimeBitsIgnoreComptime()) continue; | 1186 | const param_ty = fn_info.param_types[index]; |
| 1187 | if (!param_ty.hasRuntimeBitsIgnoreComptime()) continue; | ||
| 969 | if (params_written > 0) { | 1188 | if (params_written > 0) { |
| 970 | try bw.writeAll(", "); | 1189 | try bw.writeAll(", "); |
| 971 | } | 1190 | } |
| 972 | try dg.renderTypecast(bw, fn_info.param_types[index]); | 1191 | try dg.renderTypeAndName(bw, param_ty, .{ .bytes = "" }, .Mut, 0, .Forward); |
| 973 | params_written += 1; | 1192 | params_written += 1; |
| 974 | } | 1193 | } |
| 975 | 1194 | ||
| ... | @@ -977,13 +1196,13 @@ pub const DeclGen = struct { | ... | @@ -977,13 +1196,13 @@ pub const DeclGen = struct { |
| 977 | if (params_written != 0) try bw.writeAll(", "); | 1196 | if (params_written != 0) try bw.writeAll(", "); |
| 978 | try bw.writeAll("..."); | 1197 | try bw.writeAll("..."); |
| 979 | } else if (params_written == 0) { | 1198 | } else if (params_written == 0) { |
| 980 | try bw.writeAll("void"); | 1199 | try dg.renderType(bw, Type.void, .Forward); |
| 981 | } | 1200 | } |
| 982 | try bw.writeAll(");\n"); | 1201 | try bw.writeAll(");\n"); |
| 983 | 1202 | ||
| 984 | const rendered = buffer.toOwnedSlice(); | 1203 | const rendered = buffer.toOwnedSlice(); |
| 985 | errdefer dg.typedefs.allocator.free(rendered); | 1204 | errdefer dg.typedefs.allocator.free(rendered); |
| 986 | const name = rendered[name_start..name_end]; | 1205 | const name = rendered[name_begin..name_end]; |
| 987 | 1206 | ||
| 988 | try dg.typedefs.ensureUnusedCapacity(1); | 1207 | try dg.typedefs.ensureUnusedCapacity(1); |
| 989 | dg.typedefs.putAssumeCapacityNoClobber( | 1208 | dg.typedefs.putAssumeCapacityNoClobber( |
| ... | @@ -995,36 +1214,35 @@ pub const DeclGen = struct { | ... | @@ -995,36 +1214,35 @@ pub const DeclGen = struct { |
| 995 | } | 1214 | } |
| 996 | 1215 | ||
| 997 | fn renderSliceTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { | 1216 | fn renderSliceTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1217 | std.debug.assert(t.sentinel() == null); // expected canonical type | ||
| 1218 | |||
| 998 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); | 1219 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 999 | defer buffer.deinit(); | 1220 | defer buffer.deinit(); |
| 1000 | const bw = buffer.writer(); | 1221 | const bw = buffer.writer(); |
| 1001 | 1222 | ||
| 1002 | try bw.writeAll("typedef struct { "); | 1223 | var ptr_ty_buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 1003 | 1224 | const ptr_ty = t.slicePtrFieldType(&ptr_ty_buf); | |
| 1004 | var ptr_type_buf: Type.SlicePtrFieldTypeBuffer = undefined; | 1225 | const ptr_name = CValue{ .identifier = "ptr" }; |
| 1005 | const ptr_type = t.slicePtrFieldType(&ptr_type_buf); | 1226 | const len_ty = Type.usize; |
| 1006 | const ptr_name = CValue{ .bytes = "ptr" }; | 1227 | const len_name = CValue{ .identifier = "len" }; |
| 1007 | try dg.renderTypeAndName(bw, ptr_type, ptr_name, .Mut, 0); | 1228 | |
| 1008 | 1229 | try bw.writeAll("typedef struct {\n "); | |
| 1009 | const ptr_sentinel = ptr_type.ptrInfo().data.sentinel; | 1230 | try dg.renderTypeAndName(bw, ptr_ty, ptr_name, .Mut, 0, .Complete); |
| 1010 | const child_type = t.childType(); | 1231 | try bw.writeAll(";\n "); |
| 1011 | 1232 | try dg.renderTypeAndName(bw, len_ty, len_name, .Mut, 0, .Complete); | |
| 1012 | try bw.writeAll("; size_t len; } "); | 1233 | |
| 1013 | const name_index = buffer.items.len; | 1234 | try bw.writeAll(";\n} "); |
| 1014 | if (t.isConstPtr()) { | 1235 | const name_begin = buffer.items.len; |
| 1015 | try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type, dg.module)}); | 1236 | try bw.print("zig_{c}_{}", .{ |
| 1016 | } else { | 1237 | @as(u8, if (t.isConstPtr()) 'L' else 'M'), |
| 1017 | try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type, dg.module)}); | 1238 | typeToCIdentifier(t.childType(), dg.module), |
| 1018 | } | 1239 | }); |
| 1019 | if (ptr_sentinel) |s| { | 1240 | const name_end = buffer.items.len; |
| 1020 | try bw.writeAll("_s_"); | ||
| 1021 | try dg.renderValue(bw, child_type, s, .Other); | ||
| 1022 | } | ||
| 1023 | try bw.writeAll(";\n"); | 1241 | try bw.writeAll(";\n"); |
| 1024 | 1242 | ||
| 1025 | const rendered = buffer.toOwnedSlice(); | 1243 | const rendered = buffer.toOwnedSlice(); |
| 1026 | errdefer dg.typedefs.allocator.free(rendered); | 1244 | errdefer dg.typedefs.allocator.free(rendered); |
| 1027 | const name = rendered[name_index .. rendered.len - 2]; | 1245 | const name = rendered[name_begin..name_end]; |
| 1028 | 1246 | ||
| 1029 | try dg.typedefs.ensureUnusedCapacity(1); | 1247 | try dg.typedefs.ensureUnusedCapacity(1); |
| 1030 | dg.typedefs.putAssumeCapacityNoClobber( | 1248 | dg.typedefs.putAssumeCapacityNoClobber( |
| ... | @@ -1035,36 +1253,34 @@ pub const DeclGen = struct { | ... | @@ -1035,36 +1253,34 @@ pub const DeclGen = struct { |
| 1035 | return name; | 1253 | return name; |
| 1036 | } | 1254 | } |
| 1037 | 1255 | ||
| 1038 | fn renderStructTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { | 1256 | fn renderFwdTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1039 | const struct_obj = t.castTag(.@"struct").?.data; // Handle 0 bit types elsewhere. | 1257 | // The forward declaration for T is stored with a key of *const T. |
| 1040 | const fqn = try struct_obj.getFullyQualifiedName(dg.module); | 1258 | const child_ty = t.childType(); |
| 1041 | defer dg.typedefs.allocator.free(fqn); | ||
| 1042 | 1259 | ||
| 1043 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); | 1260 | var fqn_buf = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1044 | defer buffer.deinit(); | 1261 | defer fqn_buf.deinit(); |
| 1045 | 1262 | ||
| 1046 | try buffer.appendSlice("typedef struct {\n"); | 1263 | const owner_decl = dg.module.declPtr(child_ty.getOwnerDecl()); |
| 1047 | { | 1264 | try owner_decl.renderFullyQualifiedName(dg.module, fqn_buf.writer()); |
| 1048 | var it = struct_obj.fields.iterator(); | ||
| 1049 | while (it.next()) |entry| { | ||
| 1050 | const field_ty = entry.value_ptr.ty; | ||
| 1051 | if (!field_ty.hasRuntimeBits()) continue; | ||
| 1052 | 1265 | ||
| 1053 | const alignment = entry.value_ptr.abi_align; | 1266 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1054 | const name: CValue = .{ .identifier = entry.key_ptr.* }; | 1267 | defer buffer.deinit(); |
| 1055 | try buffer.append(' '); | ||
| 1056 | try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment); | ||
| 1057 | try buffer.appendSlice(";\n"); | ||
| 1058 | } | ||
| 1059 | } | ||
| 1060 | try buffer.appendSlice("} "); | ||
| 1061 | 1268 | ||
| 1062 | const name_start = buffer.items.len; | 1269 | const tag = switch (child_ty.zigTypeTag()) { |
| 1063 | try buffer.writer().print("zig_S_{};\n", .{fmtIdent(fqn)}); | 1270 | .Struct => "struct ", |
| 1271 | .Union => if (child_ty.unionTagTypeSafety()) |_| "struct " else "union ", | ||
| 1272 | else => unreachable, | ||
| 1273 | }; | ||
| 1274 | const name_begin = buffer.items.len + "typedef ".len + tag.len; | ||
| 1275 | try buffer.writer().print("typedef {s}zig_S_{} ", .{ tag, fmtIdent(fqn_buf.items) }); | ||
| 1276 | const name_end = buffer.items.len - " ".len; | ||
| 1277 | try buffer.ensureUnusedCapacity((name_end - name_begin) + ";\n".len); | ||
| 1278 | buffer.appendSliceAssumeCapacity(buffer.items[name_begin..name_end]); | ||
| 1279 | buffer.appendSliceAssumeCapacity(";\n"); | ||
| 1064 | 1280 | ||
| 1065 | const rendered = buffer.toOwnedSlice(); | 1281 | const rendered = buffer.toOwnedSlice(); |
| 1066 | errdefer dg.typedefs.allocator.free(rendered); | 1282 | errdefer dg.typedefs.allocator.free(rendered); |
| 1067 | const name = rendered[name_start .. rendered.len - 2]; | 1283 | const name = rendered[name_begin..name_end]; |
| 1068 | 1284 | ||
| 1069 | try dg.typedefs.ensureUnusedCapacity(1); | 1285 | try dg.typedefs.ensureUnusedCapacity(1); |
| 1070 | dg.typedefs.putAssumeCapacityNoClobber( | 1286 | dg.typedefs.putAssumeCapacityNoClobber( |
| ... | @@ -1075,36 +1291,84 @@ pub const DeclGen = struct { | ... | @@ -1075,36 +1291,84 @@ pub const DeclGen = struct { |
| 1075 | return name; | 1291 | return name; |
| 1076 | } | 1292 | } |
| 1077 | 1293 | ||
| 1078 | fn renderTupleTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { | 1294 | fn renderStructTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1079 | const tuple = t.tupleFields(); | 1295 | var ptr_pl = Type.Payload.ElemType{ .base = .{ .tag = .single_const_pointer }, .data = t }; |
| 1296 | const ptr_ty = Type.initPayload(&ptr_pl.base); | ||
| 1297 | const name = dg.getTypedefName(ptr_ty) orelse | ||
| 1298 | try dg.renderFwdTypedef(ptr_ty); | ||
| 1080 | 1299 | ||
| 1081 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); | 1300 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1082 | defer buffer.deinit(); | 1301 | defer buffer.deinit(); |
| 1083 | const writer = buffer.writer(); | ||
| 1084 | 1302 | ||
| 1085 | try buffer.appendSlice("typedef struct {\n"); | 1303 | try buffer.appendSlice("struct "); |
| 1304 | try buffer.appendSlice(name); | ||
| 1305 | try buffer.appendSlice(" {\n"); | ||
| 1086 | { | 1306 | { |
| 1087 | for (tuple.types) |field_ty, i| { | 1307 | var it = t.structFields().iterator(); |
| 1088 | const val = tuple.values[i]; | 1308 | var empty = true; |
| 1089 | if (val.tag() != .unreachable_value) continue; | 1309 | while (it.next()) |field| { |
| 1090 | 1310 | const field_ty = field.value_ptr.ty; | |
| 1091 | var name = std.ArrayList(u8).init(dg.gpa); | 1311 | if (!field_ty.hasRuntimeBits()) continue; |
| 1092 | defer name.deinit(); | ||
| 1093 | try name.writer().print("field_{d}", .{i}); | ||
| 1094 | 1312 | ||
| 1313 | const alignment = field.value_ptr.abi_align; | ||
| 1314 | const field_name = CValue{ .identifier = field.key_ptr.* }; | ||
| 1095 | try buffer.append(' '); | 1315 | try buffer.append(' '); |
| 1096 | try dg.renderTypeAndName(writer, field_ty, .{ .bytes = name.items }, .Mut, 0); | 1316 | try dg.renderTypeAndName(buffer.writer(), field_ty, field_name, .Mut, alignment, .Complete); |
| 1097 | try buffer.appendSlice(";\n"); | 1317 | try buffer.appendSlice(";\n"); |
| 1318 | |||
| 1319 | empty = false; | ||
| 1098 | } | 1320 | } |
| 1321 | if (empty) try buffer.appendSlice(" char empty_struct;\n"); | ||
| 1099 | } | 1322 | } |
| 1100 | try buffer.appendSlice("} "); | 1323 | try buffer.appendSlice("};\n"); |
| 1324 | |||
| 1325 | const rendered = buffer.toOwnedSlice(); | ||
| 1326 | errdefer dg.typedefs.allocator.free(rendered); | ||
| 1327 | |||
| 1328 | try dg.typedefs.ensureUnusedCapacity(1); | ||
| 1329 | dg.typedefs.putAssumeCapacityNoClobber( | ||
| 1330 | try t.copy(dg.typedefs_arena), | ||
| 1331 | .{ .name = name, .rendered = rendered }, | ||
| 1332 | ); | ||
| 1333 | |||
| 1334 | return name; | ||
| 1335 | } | ||
| 1336 | |||
| 1337 | fn renderTupleTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { | ||
| 1338 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); | ||
| 1339 | defer buffer.deinit(); | ||
| 1340 | |||
| 1341 | try buffer.appendSlice("typedef struct {\n"); | ||
| 1342 | { | ||
| 1343 | const fields = t.tupleFields(); | ||
| 1344 | var empty = true; | ||
| 1345 | for (fields.types) |field_ty, i| { | ||
| 1346 | if (!field_ty.hasRuntimeBits()) continue; | ||
| 1347 | const val = fields.values[i]; | ||
| 1348 | if (val.tag() != .unreachable_value) continue; | ||
| 1349 | |||
| 1350 | var field_name_buf: []const u8 = &.{}; | ||
| 1351 | defer dg.typedefs.allocator.free(field_name_buf); | ||
| 1352 | const field_name = if (t.isTuple()) field_name: { | ||
| 1353 | field_name_buf = try std.fmt.allocPrint(dg.typedefs.allocator, "field_{d}", .{i}); | ||
| 1354 | break :field_name field_name_buf; | ||
| 1355 | } else t.structFieldName(i); | ||
| 1101 | 1356 | ||
| 1102 | const name_start = buffer.items.len; | 1357 | try buffer.append(' '); |
| 1103 | try writer.print("zig_T_{};\n", .{typeToCIdentifier(t, dg.module)}); | 1358 | try dg.renderTypeAndName(buffer.writer(), field_ty, .{ .identifier = field_name }, .Mut, 0, .Complete); |
| 1359 | try buffer.appendSlice(";\n"); | ||
| 1360 | |||
| 1361 | empty = false; | ||
| 1362 | } | ||
| 1363 | if (empty) try buffer.appendSlice(" char empty_tuple;\n"); | ||
| 1364 | } | ||
| 1365 | const name_begin = buffer.items.len + "} ".len; | ||
| 1366 | try buffer.writer().print("}} zig_T_{};\n", .{typeToCIdentifier(t, dg.module)}); | ||
| 1367 | const name_end = buffer.items.len - ";\n".len; | ||
| 1104 | 1368 | ||
| 1105 | const rendered = buffer.toOwnedSlice(); | 1369 | const rendered = buffer.toOwnedSlice(); |
| 1106 | errdefer dg.typedefs.allocator.free(rendered); | 1370 | errdefer dg.typedefs.allocator.free(rendered); |
| 1107 | const name = rendered[name_start .. rendered.len - 2]; | 1371 | const name = rendered[name_begin..name_end]; |
| 1108 | 1372 | ||
| 1109 | try dg.typedefs.ensureUnusedCapacity(1); | 1373 | try dg.typedefs.ensureUnusedCapacity(1); |
| 1110 | dg.typedefs.putAssumeCapacityNoClobber( | 1374 | dg.typedefs.putAssumeCapacityNoClobber( |
| ... | @@ -1116,51 +1380,56 @@ pub const DeclGen = struct { | ... | @@ -1116,51 +1380,56 @@ pub const DeclGen = struct { |
| 1116 | } | 1380 | } |
| 1117 | 1381 | ||
| 1118 | fn renderUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { | 1382 | fn renderUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1119 | const union_ty = t.cast(Type.Payload.Union).?.data; | 1383 | var ptr_pl = Type.Payload.ElemType{ .base = .{ .tag = .single_const_pointer }, .data = t }; |
| 1120 | const fqn = try union_ty.getFullyQualifiedName(dg.module); | 1384 | const ptr_ty = Type.initPayload(&ptr_pl.base); |
| 1121 | defer dg.typedefs.allocator.free(fqn); | 1385 | const name = dg.getTypedefName(ptr_ty) orelse |
| 1122 | 1386 | try dg.renderFwdTypedef(ptr_ty); | |
| 1123 | const target = dg.module.getTarget(); | ||
| 1124 | const layout = t.unionGetLayout(target); | ||
| 1125 | 1387 | ||
| 1126 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); | 1388 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1127 | defer buffer.deinit(); | 1389 | defer buffer.deinit(); |
| 1128 | 1390 | ||
| 1129 | try buffer.appendSlice("typedef "); | 1391 | try buffer.appendSlice(if (t.unionTagTypeSafety()) |_| "struct " else "union "); |
| 1130 | if (t.unionTagTypeSafety()) |tag_ty| { | 1392 | try buffer.appendSlice(name); |
| 1131 | const name: CValue = .{ .bytes = "tag" }; | 1393 | try buffer.appendSlice(" {\n"); |
| 1132 | try buffer.appendSlice("struct {\n "); | 1394 | |
| 1395 | const indent = if (t.unionTagTypeSafety()) |tag_ty| indent: { | ||
| 1396 | const target = dg.module.getTarget(); | ||
| 1397 | const layout = t.unionGetLayout(target); | ||
| 1133 | if (layout.tag_size != 0) { | 1398 | if (layout.tag_size != 0) { |
| 1134 | try dg.renderTypeAndName(buffer.writer(), tag_ty, name, .Mut, 0); | 1399 | try buffer.append(' '); |
| 1400 | try dg.renderTypeAndName(buffer.writer(), tag_ty, .{ .identifier = "tag" }, .Mut, 0, .Complete); | ||
| 1135 | try buffer.appendSlice(";\n"); | 1401 | try buffer.appendSlice(";\n"); |
| 1136 | } | 1402 | } |
| 1137 | } | 1403 | try buffer.appendSlice(" union {\n"); |
| 1404 | break :indent " "; | ||
| 1405 | } else " "; | ||
| 1138 | 1406 | ||
| 1139 | try buffer.appendSlice("union {\n"); | ||
| 1140 | { | 1407 | { |
| 1141 | var it = t.unionFields().iterator(); | 1408 | var it = t.unionFields().iterator(); |
| 1142 | while (it.next()) |entry| { | 1409 | var empty = true; |
| 1143 | const field_ty = entry.value_ptr.ty; | 1410 | while (it.next()) |field| { |
| 1411 | const field_ty = field.value_ptr.ty; | ||
| 1144 | if (!field_ty.hasRuntimeBits()) continue; | 1412 | if (!field_ty.hasRuntimeBits()) continue; |
| 1145 | const alignment = entry.value_ptr.abi_align; | 1413 | |
| 1146 | const name: CValue = .{ .identifier = entry.key_ptr.* }; | 1414 | const alignment = field.value_ptr.abi_align; |
| 1147 | try buffer.append(' '); | 1415 | const field_name = CValue{ .identifier = field.key_ptr.* }; |
| 1148 | try dg.renderTypeAndName(buffer.writer(), field_ty, name, .Mut, alignment); | 1416 | try buffer.appendSlice(indent); |
| 1417 | try dg.renderTypeAndName(buffer.writer(), field_ty, field_name, .Mut, alignment, .Complete); | ||
| 1149 | try buffer.appendSlice(";\n"); | 1418 | try buffer.appendSlice(";\n"); |
| 1150 | } | ||
| 1151 | } | ||
| 1152 | try buffer.appendSlice("} "); | ||
| 1153 | 1419 | ||
| 1154 | if (t.unionTagTypeSafety()) |_| { | 1420 | empty = false; |
| 1155 | try buffer.appendSlice("payload;\n} "); | 1421 | } |
| 1422 | if (empty) { | ||
| 1423 | try buffer.appendSlice(indent); | ||
| 1424 | try buffer.appendSlice("char empty_union;\n"); | ||
| 1425 | } | ||
| 1156 | } | 1426 | } |
| 1157 | 1427 | ||
| 1158 | const name_start = buffer.items.len; | 1428 | if (t.unionTagTypeSafety()) |_| try buffer.appendSlice(" } payload;\n"); |
| 1159 | try buffer.writer().print("zig_U_{};\n", .{fmtIdent(fqn)}); | 1429 | try buffer.appendSlice("};\n"); |
| 1160 | 1430 | ||
| 1161 | const rendered = buffer.toOwnedSlice(); | 1431 | const rendered = buffer.toOwnedSlice(); |
| 1162 | errdefer dg.typedefs.allocator.free(rendered); | 1432 | errdefer dg.typedefs.allocator.free(rendered); |
| 1163 | const name = rendered[name_start .. rendered.len - 2]; | ||
| 1164 | 1433 | ||
| 1165 | try dg.typedefs.ensureUnusedCapacity(1); | 1434 | try dg.typedefs.ensureUnusedCapacity(1); |
| 1166 | dg.typedefs.putAssumeCapacityNoClobber( | 1435 | dg.typedefs.putAssumeCapacityNoClobber( |
| ... | @@ -1172,42 +1441,39 @@ pub const DeclGen = struct { | ... | @@ -1172,42 +1441,39 @@ pub const DeclGen = struct { |
| 1172 | } | 1441 | } |
| 1173 | 1442 | ||
| 1174 | fn renderErrorUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { | 1443 | fn renderErrorUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1175 | const payload_ty = t.errorUnionPayload(); | 1444 | assert(t.errorUnionSet().tag() == .anyerror); |
| 1176 | const error_ty = t.errorUnionSet(); | ||
| 1177 | 1445 | ||
| 1178 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); | 1446 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1179 | defer buffer.deinit(); | 1447 | defer buffer.deinit(); |
| 1180 | const bw = buffer.writer(); | 1448 | const bw = buffer.writer(); |
| 1181 | 1449 | ||
| 1182 | const payload_name = CValue{ .bytes = "payload" }; | 1450 | const payload_ty = t.errorUnionPayload(); |
| 1451 | const payload_name = CValue{ .identifier = "payload" }; | ||
| 1452 | const error_ty = t.errorUnionSet(); | ||
| 1453 | const error_name = CValue{ .identifier = "error" }; | ||
| 1454 | |||
| 1183 | const target = dg.module.getTarget(); | 1455 | const target = dg.module.getTarget(); |
| 1184 | const payload_align = payload_ty.abiAlignment(target); | 1456 | const payload_align = payload_ty.abiAlignment(target); |
| 1185 | const error_align = Type.anyerror.abiAlignment(target); | 1457 | const error_align = error_ty.abiAlignment(target); |
| 1458 | try bw.writeAll("typedef struct {\n "); | ||
| 1186 | if (error_align > payload_align) { | 1459 | if (error_align > payload_align) { |
| 1187 | try bw.writeAll("typedef struct { "); | 1460 | try dg.renderTypeAndName(bw, payload_ty, payload_name, .Mut, 0, .Complete); |
| 1188 | try dg.renderTypeAndName(bw, payload_ty, payload_name, .Mut, 0); | 1461 | try bw.writeAll(";\n "); |
| 1189 | try bw.writeAll("; uint16_t error; } "); | 1462 | try dg.renderTypeAndName(bw, error_ty, error_name, .Mut, 0, .Complete); |
| 1190 | } else { | ||
| 1191 | try bw.writeAll("typedef struct { uint16_t error; "); | ||
| 1192 | try dg.renderTypeAndName(bw, payload_ty, payload_name, .Mut, 0); | ||
| 1193 | try bw.writeAll("; } "); | ||
| 1194 | } | ||
| 1195 | |||
| 1196 | const name_index = buffer.items.len; | ||
| 1197 | if (error_ty.castTag(.error_set_inferred)) |inf_err_set_payload| { | ||
| 1198 | const func = inf_err_set_payload.data.func; | ||
| 1199 | try bw.writeAll("zig_E_"); | ||
| 1200 | try dg.renderDeclName(bw, func.owner_decl); | ||
| 1201 | try bw.writeAll(";\n"); | ||
| 1202 | } else { | 1463 | } else { |
| 1203 | try bw.print("zig_E_{s}_{s};\n", .{ | 1464 | try dg.renderTypeAndName(bw, error_ty, error_name, .Mut, 0, .Complete); |
| 1204 | typeToCIdentifier(error_ty, dg.module), typeToCIdentifier(payload_ty, dg.module), | 1465 | try bw.writeAll(";\n "); |
| 1205 | }); | 1466 | try dg.renderTypeAndName(bw, payload_ty, payload_name, .Mut, 0, .Complete); |
| 1206 | } | 1467 | } |
| 1468 | try bw.writeAll(";\n} "); | ||
| 1469 | const name_begin = buffer.items.len; | ||
| 1470 | try bw.print("zig_E_{}", .{typeToCIdentifier(payload_ty, dg.module)}); | ||
| 1471 | const name_end = buffer.items.len; | ||
| 1472 | try bw.writeAll(";\n"); | ||
| 1207 | 1473 | ||
| 1208 | const rendered = buffer.toOwnedSlice(); | 1474 | const rendered = buffer.toOwnedSlice(); |
| 1209 | errdefer dg.typedefs.allocator.free(rendered); | 1475 | errdefer dg.typedefs.allocator.free(rendered); |
| 1210 | const name = rendered[name_index .. rendered.len - 2]; | 1476 | const name = rendered[name_begin..name_end]; |
| 1211 | 1477 | ||
| 1212 | try dg.typedefs.ensureUnusedCapacity(1); | 1478 | try dg.typedefs.ensureUnusedCapacity(1); |
| 1213 | dg.typedefs.putAssumeCapacityNoClobber( | 1479 | dg.typedefs.putAssumeCapacityNoClobber( |
| ... | @@ -1219,26 +1485,28 @@ pub const DeclGen = struct { | ... | @@ -1219,26 +1485,28 @@ pub const DeclGen = struct { |
| 1219 | } | 1485 | } |
| 1220 | 1486 | ||
| 1221 | fn renderArrayTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { | 1487 | fn renderArrayTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { |
| 1488 | const info = t.arrayInfo(); | ||
| 1489 | std.debug.assert(info.sentinel == null); // expected canonical type | ||
| 1490 | |||
| 1222 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); | 1491 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); |
| 1223 | defer buffer.deinit(); | 1492 | defer buffer.deinit(); |
| 1224 | const bw = buffer.writer(); | 1493 | const bw = buffer.writer(); |
| 1225 | 1494 | ||
| 1226 | const elem_type = t.elemType(); | ||
| 1227 | const sentinel_bit = @boolToInt(t.sentinel() != null); | ||
| 1228 | const c_len = t.arrayLen() + sentinel_bit; | ||
| 1229 | |||
| 1230 | try bw.writeAll("typedef "); | 1495 | try bw.writeAll("typedef "); |
| 1231 | try dg.renderType(bw, elem_type); | 1496 | try dg.renderType(bw, info.elem_type, .Complete); |
| 1232 | 1497 | ||
| 1233 | const name_start = buffer.items.len + 1; | 1498 | const name_begin = buffer.items.len + " ".len; |
| 1234 | try bw.print(" zig_A_{s}_{d}", .{ typeToCIdentifier(elem_type, dg.module), c_len }); | 1499 | try bw.print(" zig_A_{}_{d}", .{ typeToCIdentifier(info.elem_type, dg.module), info.len }); |
| 1235 | const name_end = buffer.items.len; | 1500 | const name_end = buffer.items.len; |
| 1236 | 1501 | ||
| 1237 | try bw.print("[{d}];\n", .{c_len}); | 1502 | const c_len = if (info.len > 0) info.len else 1; |
| 1503 | var c_len_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = c_len }; | ||
| 1504 | const c_len_val = Value.initPayload(&c_len_pl.base); | ||
| 1505 | try bw.print("[{}];\n", .{try dg.fmtIntLiteral(Type.usize, c_len_val)}); | ||
| 1238 | 1506 | ||
| 1239 | const rendered = buffer.toOwnedSlice(); | 1507 | const rendered = buffer.toOwnedSlice(); |
| 1240 | errdefer dg.typedefs.allocator.free(rendered); | 1508 | errdefer dg.typedefs.allocator.free(rendered); |
| 1241 | const name = rendered[name_start..name_end]; | 1509 | const name = rendered[name_begin..name_end]; |
| 1242 | 1510 | ||
| 1243 | try dg.typedefs.ensureUnusedCapacity(1); | 1511 | try dg.typedefs.ensureUnusedCapacity(1); |
| 1244 | dg.typedefs.putAssumeCapacityNoClobber( | 1512 | dg.typedefs.putAssumeCapacityNoClobber( |
| ... | @@ -1254,16 +1522,48 @@ pub const DeclGen = struct { | ... | @@ -1254,16 +1522,48 @@ pub const DeclGen = struct { |
| 1254 | defer buffer.deinit(); | 1522 | defer buffer.deinit(); |
| 1255 | const bw = buffer.writer(); | 1523 | const bw = buffer.writer(); |
| 1256 | 1524 | ||
| 1257 | try bw.writeAll("typedef struct { "); | 1525 | try bw.writeAll("typedef struct {\n "); |
| 1258 | const payload_name = CValue{ .bytes = "payload" }; | 1526 | try dg.renderTypeAndName(bw, child_type, .{ .identifier = "payload" }, .Mut, 0, .Complete); |
| 1259 | try dg.renderTypeAndName(bw, child_type, payload_name, .Mut, 0); | 1527 | try bw.writeAll(";\n "); |
| 1260 | try bw.writeAll("; bool is_null; } "); | 1528 | try dg.renderTypeAndName(bw, Type.bool, .{ .identifier = "is_null" }, .Mut, 0, .Complete); |
| 1261 | const name_index = buffer.items.len; | 1529 | try bw.writeAll(";\n} "); |
| 1262 | try bw.print("zig_Q_{s};\n", .{typeToCIdentifier(child_type, dg.module)}); | 1530 | const name_begin = buffer.items.len; |
| 1531 | try bw.print("zig_Q_{}", .{typeToCIdentifier(child_type, dg.module)}); | ||
| 1532 | const name_end = buffer.items.len; | ||
| 1533 | try bw.writeAll(";\n"); | ||
| 1534 | |||
| 1535 | const rendered = buffer.toOwnedSlice(); | ||
| 1536 | errdefer dg.typedefs.allocator.free(rendered); | ||
| 1537 | const name = rendered[name_begin..name_end]; | ||
| 1538 | |||
| 1539 | try dg.typedefs.ensureUnusedCapacity(1); | ||
| 1540 | dg.typedefs.putAssumeCapacityNoClobber( | ||
| 1541 | try t.copy(dg.typedefs_arena), | ||
| 1542 | .{ .name = name, .rendered = rendered }, | ||
| 1543 | ); | ||
| 1544 | |||
| 1545 | return name; | ||
| 1546 | } | ||
| 1547 | |||
| 1548 | fn renderOpaqueTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { | ||
| 1549 | const opaque_ty = t.cast(Type.Payload.Opaque).?.data; | ||
| 1550 | const unqualified_name = dg.module.declPtr(opaque_ty.owner_decl).name; | ||
| 1551 | const fqn = try opaque_ty.getFullyQualifiedName(dg.module); | ||
| 1552 | defer dg.typedefs.allocator.free(fqn); | ||
| 1553 | |||
| 1554 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); | ||
| 1555 | defer buffer.deinit(); | ||
| 1556 | |||
| 1557 | try buffer.writer().print("typedef struct { } ", .{fmtIdent(std.mem.span(unqualified_name))}); | ||
| 1558 | |||
| 1559 | const name_begin = buffer.items.len; | ||
| 1560 | try buffer.writer().print("zig_O_{}", .{fmtIdent(fqn)}); | ||
| 1561 | const name_end = buffer.items.len; | ||
| 1562 | try buffer.appendSlice(";\n"); | ||
| 1263 | 1563 | ||
| 1264 | const rendered = buffer.toOwnedSlice(); | 1564 | const rendered = buffer.toOwnedSlice(); |
| 1265 | errdefer dg.typedefs.allocator.free(rendered); | 1565 | errdefer dg.typedefs.allocator.free(rendered); |
| 1266 | const name = rendered[name_index .. rendered.len - 2]; | 1566 | const name = rendered[name_begin..name_end]; |
| 1267 | 1567 | ||
| 1268 | try dg.typedefs.ensureUnusedCapacity(1); | 1568 | try dg.typedefs.ensureUnusedCapacity(1); |
| 1269 | dg.typedefs.putAssumeCapacityNoClobber( | 1569 | dg.typedefs.putAssumeCapacityNoClobber( |
| ... | @@ -1286,84 +1586,98 @@ pub const DeclGen = struct { | ... | @@ -1286,84 +1586,98 @@ pub const DeclGen = struct { |
| 1286 | /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" | | 1586 | /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" | |
| 1287 | /// | `renderType` | "uint8_t *" | "zig_A_uint8_t_10" | | 1587 | /// | `renderType` | "uint8_t *" | "zig_A_uint8_t_10" | |
| 1288 | /// | 1588 | /// |
| 1289 | fn renderType(dg: *DeclGen, w: anytype, t: Type) error{ OutOfMemory, AnalysisFail }!void { | 1589 | fn renderType( |
| 1590 | dg: *DeclGen, | ||
| 1591 | w: anytype, | ||
| 1592 | t: Type, | ||
| 1593 | kind: TypedefKind, | ||
| 1594 | ) error{ OutOfMemory, AnalysisFail }!void { | ||
| 1290 | const target = dg.module.getTarget(); | 1595 | const target = dg.module.getTarget(); |
| 1291 | 1596 | ||
| 1292 | switch (t.zigTypeTag()) { | 1597 | switch (t.zigTypeTag()) { |
| 1293 | .NoReturn, .Void => try w.writeAll("void"), | 1598 | .NoReturn, .Void, .Bool, .Int, .Float, .ErrorSet => |tag| { |
| 1294 | .Bool => try w.writeAll("bool"), | 1599 | const is_named = switch (tag) { |
| 1295 | .Int => { | 1600 | .Int => t.isNamedInt(), |
| 1296 | switch (t.tag()) { | 1601 | .ErrorSet => false, |
| 1297 | .u1, .u8 => try w.writeAll("uint8_t"), | 1602 | else => true, |
| 1298 | .i8 => try w.writeAll("int8_t"), | 1603 | }; |
| 1299 | .u16 => try w.writeAll("uint16_t"), | 1604 | if (is_named) { |
| 1300 | .i16 => try w.writeAll("int16_t"), | 1605 | try w.writeAll("zig_"); |
| 1301 | .u32 => try w.writeAll("uint32_t"), | 1606 | try t.print(w, dg.module); |
| 1302 | .i32 => try w.writeAll("int32_t"), | 1607 | } else { |
| 1303 | .u64 => try w.writeAll("uint64_t"), | 1608 | const int_info = t.intInfo(target); |
| 1304 | .i64 => try w.writeAll("int64_t"), | 1609 | if (toCIntBits(int_info.bits)) |c_bits| |
| 1305 | .u128 => try w.writeAll("uint128_t"), | 1610 | return w.print("zig_{c}{d}", .{ signAbbrev(int_info.signedness), c_bits }) |
| 1306 | .i128 => try w.writeAll("int128_t"), | 1611 | else if (loweredArrayInfo(t, target)) |array_info| { |
| 1307 | .usize => try w.writeAll("uintptr_t"), | 1612 | assert(array_info.sentinel == null); |
| 1308 | .isize => try w.writeAll("intptr_t"), | 1613 | var array_pl = Type.Payload.Array{ |
| 1309 | .c_short => try w.writeAll("short"), | 1614 | .base = .{ .tag = .array }, |
| 1310 | .c_ushort => try w.writeAll("unsigned short"), | 1615 | .data = .{ .len = array_info.len, .elem_type = array_info.elem_type }, |
| 1311 | .c_int => try w.writeAll("int"), | ||
| 1312 | .c_uint => try w.writeAll("unsigned int"), | ||
| 1313 | .c_long => try w.writeAll("long"), | ||
| 1314 | .c_ulong => try w.writeAll("unsigned long"), | ||
| 1315 | .c_longlong => try w.writeAll("long long"), | ||
| 1316 | .c_ulonglong => try w.writeAll("unsigned long long"), | ||
| 1317 | .int_signed, .int_unsigned => { | ||
| 1318 | const info = t.intInfo(target); | ||
| 1319 | const sign_prefix = switch (info.signedness) { | ||
| 1320 | .signed => "", | ||
| 1321 | .unsigned => "u", | ||
| 1322 | }; | 1616 | }; |
| 1323 | const c_bits = toCIntBits(info.bits) orelse | 1617 | const array_ty = Type.initPayload(&array_pl.base); |
| 1324 | return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); | 1618 | |
| 1325 | try w.print("{s}int{d}_t", .{ sign_prefix, c_bits }); | 1619 | return dg.renderType(w, array_ty, kind); |
| 1326 | }, | 1620 | } else return dg.fail("C backend: Unable to lower unnamed integer type {}", .{ |
| 1327 | else => unreachable, | 1621 | t.fmt(dg.module), |
| 1328 | } | 1622 | }); |
| 1329 | }, | ||
| 1330 | .Float => { | ||
| 1331 | switch (t.tag()) { | ||
| 1332 | .f32 => try w.writeAll("float"), | ||
| 1333 | .f64 => try w.writeAll("double"), | ||
| 1334 | .c_longdouble => try w.writeAll("long double"), | ||
| 1335 | .f16 => return dg.fail("TODO: C backend: implement float type f16", .{}), | ||
| 1336 | .f128 => return dg.fail("TODO: C backend: implement float type f128", .{}), | ||
| 1337 | else => unreachable, | ||
| 1338 | } | 1623 | } |
| 1339 | }, | 1624 | }, |
| 1340 | .Pointer => { | 1625 | .Pointer => { |
| 1341 | if (t.isSlice()) { | 1626 | const ptr_info = t.ptrInfo().data; |
| 1342 | const name = dg.getTypedefName(t) orelse | 1627 | if (ptr_info.size == .Slice) { |
| 1343 | try dg.renderSliceTypedef(t); | 1628 | var slice_pl = Type.Payload.ElemType{ |
| 1629 | .base = .{ .tag = if (t.ptrIsMutable()) .mut_slice else .const_slice }, | ||
| 1630 | .data = ptr_info.pointee_type, | ||
| 1631 | }; | ||
| 1632 | const slice_ty = Type.initPayload(&slice_pl.base); | ||
| 1633 | |||
| 1634 | const name = dg.getTypedefName(slice_ty) orelse | ||
| 1635 | try dg.renderSliceTypedef(slice_ty); | ||
| 1344 | 1636 | ||
| 1345 | return w.writeAll(name); | 1637 | return w.writeAll(name); |
| 1346 | } | 1638 | } |
| 1347 | 1639 | ||
| 1348 | if (t.castPtrToFn()) |fn_ty| { | 1640 | if (ptr_info.pointee_type.zigTypeTag() == .Fn) { |
| 1349 | const name = dg.getTypedefName(t) orelse | 1641 | const name = dg.getTypedefName(ptr_info.pointee_type) orelse |
| 1350 | try dg.renderPtrToFnTypedef(t, fn_ty); | 1642 | try dg.renderPtrToFnTypedef(ptr_info.pointee_type); |
| 1351 | 1643 | ||
| 1352 | return w.writeAll(name); | 1644 | return w.writeAll(name); |
| 1353 | } | 1645 | } |
| 1354 | 1646 | ||
| 1355 | try dg.renderType(w, t.elemType()); | 1647 | if (ptr_info.host_size != 0) { |
| 1356 | if (t.isConstPtr()) { | 1648 | var host_pl = Type.Payload.Bits{ |
| 1357 | try w.writeAll(" const"); | 1649 | .base = .{ .tag = .int_unsigned }, |
| 1358 | } | 1650 | .data = ptr_info.host_size * 8, |
| 1359 | if (t.isVolatilePtr()) { | 1651 | }; |
| 1360 | try w.writeAll(" volatile"); | 1652 | const host_ty = Type.initPayload(&host_pl.base); |
| 1361 | } | 1653 | |
| 1654 | try dg.renderType(w, host_ty, .Forward); | ||
| 1655 | } else if (t.isCPtr() and ptr_info.pointee_type.eql(Type.u8, dg.module) and | ||
| 1656 | (dg.decl.val.tag() == .extern_fn or | ||
| 1657 | std.mem.eql(u8, std.mem.span(dg.decl.name), "main"))) | ||
| 1658 | { | ||
| 1659 | // This is a hack, since the c compiler expects a lot of external | ||
| 1660 | // library functions to have char pointers in their signatures, but | ||
| 1661 | // u8 and i8 produce unsigned char and signed char respectively, | ||
| 1662 | // which in C are (not very usefully) different than char. | ||
| 1663 | try w.writeAll("char"); | ||
| 1664 | } else try dg.renderType(w, switch (ptr_info.pointee_type.tag()) { | ||
| 1665 | .anyopaque => Type.void, | ||
| 1666 | else => ptr_info.pointee_type, | ||
| 1667 | }, .Forward); | ||
| 1668 | if (t.isConstPtr()) try w.writeAll(" const"); | ||
| 1669 | if (t.isVolatilePtr()) try w.writeAll(" volatile"); | ||
| 1362 | return w.writeAll(" *"); | 1670 | return w.writeAll(" *"); |
| 1363 | }, | 1671 | }, |
| 1364 | .Array => { | 1672 | .Array => { |
| 1365 | const name = dg.getTypedefName(t) orelse | 1673 | var array_pl = Type.Payload.Array{ .base = .{ .tag = .array }, .data = .{ |
| 1366 | try dg.renderArrayTypedef(t); | 1674 | .len = t.arrayLenIncludingSentinel(), |
| 1675 | .elem_type = t.childType(), | ||
| 1676 | } }; | ||
| 1677 | const array_ty = Type.initPayload(&array_pl.base); | ||
| 1678 | |||
| 1679 | const name = dg.getTypedefName(array_ty) orelse | ||
| 1680 | try dg.renderArrayTypedef(array_ty); | ||
| 1367 | 1681 | ||
| 1368 | return w.writeAll(name); | 1682 | return w.writeAll(name); |
| 1369 | }, | 1683 | }, |
| ... | @@ -1371,57 +1685,74 @@ pub const DeclGen = struct { | ... | @@ -1371,57 +1685,74 @@ pub const DeclGen = struct { |
| 1371 | var opt_buf: Type.Payload.ElemType = undefined; | 1685 | var opt_buf: Type.Payload.ElemType = undefined; |
| 1372 | const child_type = t.optionalChild(&opt_buf); | 1686 | const child_type = t.optionalChild(&opt_buf); |
| 1373 | 1687 | ||
| 1374 | if (!child_type.hasRuntimeBitsIgnoreComptime()) { | 1688 | if (!child_type.hasRuntimeBitsIgnoreComptime()) |
| 1375 | return w.writeAll("bool"); | 1689 | return dg.renderType(w, Type.bool, kind); |
| 1376 | } | ||
| 1377 | 1690 | ||
| 1378 | if (t.optionalReprIsPayload()) { | 1691 | if (t.optionalReprIsPayload()) |
| 1379 | return dg.renderType(w, child_type); | 1692 | return dg.renderType(w, child_type, kind); |
| 1380 | } | ||
| 1381 | 1693 | ||
| 1382 | const name = dg.getTypedefName(t) orelse | 1694 | const name = dg.getTypedefName(t) orelse |
| 1383 | try dg.renderOptionalTypedef(t, child_type); | 1695 | try dg.renderOptionalTypedef(t, child_type); |
| 1384 | 1696 | ||
| 1385 | return w.writeAll(name); | 1697 | return w.writeAll(name); |
| 1386 | }, | 1698 | }, |
| 1387 | .ErrorSet => { | ||
| 1388 | comptime assert(Type.anyerror.abiSize(builtin.target) == 2); | ||
| 1389 | return w.writeAll("uint16_t"); | ||
| 1390 | }, | ||
| 1391 | .ErrorUnion => { | 1699 | .ErrorUnion => { |
| 1392 | const payload_ty = t.errorUnionPayload(); | 1700 | const payload_ty = t.errorUnionPayload(); |
| 1393 | 1701 | ||
| 1394 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 1702 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) |
| 1395 | return dg.renderType(w, Type.anyerror); | 1703 | return dg.renderType(w, Type.anyerror, kind); |
| 1396 | } | ||
| 1397 | 1704 | ||
| 1398 | const name = dg.getTypedefName(t) orelse | 1705 | var error_union_pl = Type.Payload.ErrorUnion{ |
| 1399 | try dg.renderErrorUnionTypedef(t); | 1706 | .data = .{ .error_set = Type.anyerror, .payload = payload_ty }, |
| 1707 | }; | ||
| 1708 | const error_union_ty = Type.initPayload(&error_union_pl.base); | ||
| 1400 | 1709 | ||
| 1401 | return w.writeAll(name); | 1710 | const name = dg.getTypedefName(error_union_ty) orelse |
| 1402 | }, | 1711 | try dg.renderErrorUnionTypedef(error_union_ty); |
| 1403 | .Struct => { | ||
| 1404 | const name = dg.getTypedefName(t) orelse if (t.isTuple() or t.tag() == .anon_struct) | ||
| 1405 | try dg.renderTupleTypedef(t) | ||
| 1406 | else | ||
| 1407 | try dg.renderStructTypedef(t); | ||
| 1408 | 1712 | ||
| 1409 | return w.writeAll(name); | 1713 | return w.writeAll(name); |
| 1410 | }, | 1714 | }, |
| 1411 | .Union => { | 1715 | .Struct, .Union => |tag| if (tag == .Struct and t.containerLayout() == .Packed) |
| 1412 | const name = dg.getTypedefName(t) orelse | 1716 | try dg.renderType(w, t.castTag(.@"struct").?.data.backing_int_ty, kind) |
| 1413 | try dg.renderUnionTypedef(t); | 1717 | else if (kind == .Complete or t.isTupleOrAnonStruct()) { |
| 1718 | const name = dg.getTypedefName(t) orelse switch (tag) { | ||
| 1719 | .Struct => if (t.isTupleOrAnonStruct()) | ||
| 1720 | try dg.renderTupleTypedef(t) | ||
| 1721 | else | ||
| 1722 | try dg.renderStructTypedef(t), | ||
| 1723 | .Union => try dg.renderUnionTypedef(t), | ||
| 1724 | else => unreachable, | ||
| 1725 | }; | ||
| 1414 | 1726 | ||
| 1415 | return w.writeAll(name); | 1727 | try w.writeAll(name); |
| 1728 | } else { | ||
| 1729 | var ptr_pl = Type.Payload.ElemType{ | ||
| 1730 | .base = .{ .tag = .single_const_pointer }, | ||
| 1731 | .data = t, | ||
| 1732 | }; | ||
| 1733 | const ptr_ty = Type.initPayload(&ptr_pl.base); | ||
| 1734 | |||
| 1735 | const name = dg.getTypedefName(ptr_ty) orelse | ||
| 1736 | try dg.renderFwdTypedef(ptr_ty); | ||
| 1737 | |||
| 1738 | try w.writeAll(name); | ||
| 1416 | }, | 1739 | }, |
| 1417 | .Enum => { | 1740 | .Enum => { |
| 1418 | // For enums, we simply use the integer tag type. | 1741 | // For enums, we simply use the integer tag type. |
| 1419 | var int_tag_ty_buffer: Type.Payload.Bits = undefined; | 1742 | var int_tag_buf: Type.Payload.Bits = undefined; |
| 1420 | const int_tag_ty = t.intTagType(&int_tag_ty_buffer); | 1743 | const int_tag_ty = t.intTagType(&int_tag_buf); |
| 1744 | |||
| 1745 | try dg.renderType(w, int_tag_ty, kind); | ||
| 1746 | }, | ||
| 1747 | .Opaque => switch (t.tag()) { | ||
| 1748 | .@"opaque" => { | ||
| 1749 | const name = dg.getTypedefName(t) orelse | ||
| 1750 | try dg.renderOpaqueTypedef(t); | ||
| 1421 | 1751 | ||
| 1422 | try dg.renderType(w, int_tag_ty); | 1752 | try w.writeAll(name); |
| 1753 | }, | ||
| 1754 | else => unreachable, | ||
| 1423 | }, | 1755 | }, |
| 1424 | .Opaque => return w.writeAll("void"), | ||
| 1425 | 1756 | ||
| 1426 | .Frame, | 1757 | .Frame, |
| 1427 | .AnyFrame, | 1758 | .AnyFrame, |
| ... | @@ -1456,13 +1787,8 @@ pub const DeclGen = struct { | ... | @@ -1456,13 +1787,8 @@ pub const DeclGen = struct { |
| 1456 | /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" | | 1787 | /// | `renderTypeAndName` | "uint8_t *name" | "uint8_t *name[10]" | |
| 1457 | /// | `renderType` | "uint8_t *" | "zig_A_uint8_t_10" | | 1788 | /// | `renderType` | "uint8_t *" | "zig_A_uint8_t_10" | |
| 1458 | /// | 1789 | /// |
| 1459 | fn renderTypecast( | 1790 | fn renderTypecast(dg: *DeclGen, w: anytype, ty: Type) error{ OutOfMemory, AnalysisFail }!void { |
| 1460 | dg: *DeclGen, | 1791 | return renderTypeAndName(dg, w, ty, .{ .bytes = "" }, .Mut, 0, .Complete); |
| 1461 | w: anytype, | ||
| 1462 | ty: Type, | ||
| 1463 | ) error{ OutOfMemory, AnalysisFail }!void { | ||
| 1464 | const name = CValue{ .bytes = "" }; | ||
| 1465 | return renderTypeAndName(dg, w, ty, name, .Mut, 0); | ||
| 1466 | } | 1792 | } |
| 1467 | 1793 | ||
| 1468 | /// Renders a type and name in field declaration/definition format. | 1794 | /// Renders a type and name in field declaration/definition format. |
| ... | @@ -1481,26 +1807,36 @@ pub const DeclGen = struct { | ... | @@ -1481,26 +1807,36 @@ pub const DeclGen = struct { |
| 1481 | name: CValue, | 1807 | name: CValue, |
| 1482 | mutability: Mutability, | 1808 | mutability: Mutability, |
| 1483 | alignment: u32, | 1809 | alignment: u32, |
| 1810 | kind: TypedefKind, | ||
| 1484 | ) error{ OutOfMemory, AnalysisFail }!void { | 1811 | ) error{ OutOfMemory, AnalysisFail }!void { |
| 1485 | var suffix = std.ArrayList(u8).init(dg.gpa); | 1812 | var suffix = std.ArrayList(u8).init(dg.gpa); |
| 1486 | defer suffix.deinit(); | 1813 | defer suffix.deinit(); |
| 1814 | const suffix_writer = suffix.writer(); | ||
| 1487 | 1815 | ||
| 1488 | // Any top-level array types are rendered here as a suffix, which | 1816 | // Any top-level array types are rendered here as a suffix, which |
| 1489 | // avoids creating typedefs for every array type | 1817 | // avoids creating typedefs for every array type |
| 1818 | const target = dg.module.getTarget(); | ||
| 1490 | var render_ty = ty; | 1819 | var render_ty = ty; |
| 1491 | while (render_ty.zigTypeTag() == .Array) { | 1820 | var depth: u32 = 0; |
| 1492 | const sentinel_bit = @boolToInt(render_ty.sentinel() != null); | 1821 | while (loweredArrayInfo(render_ty, target)) |array_info| { |
| 1493 | const c_len = render_ty.arrayLen() + sentinel_bit; | 1822 | const c_len = array_info.len + @boolToInt(array_info.sentinel != null); |
| 1494 | try suffix.writer().print("[{d}]", .{c_len}); | 1823 | var c_len_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = c_len }; |
| 1495 | render_ty = render_ty.elemType(); | 1824 | const c_len_val = Value.initPayload(&c_len_pl.base); |
| 1825 | |||
| 1826 | try suffix_writer.writeByte('['); | ||
| 1827 | if (mutability == .ConstArgument and depth == 0) try suffix_writer.writeAll("static const "); | ||
| 1828 | try suffix.writer().print("{}]", .{try dg.fmtIntLiteral(Type.usize, c_len_val)}); | ||
| 1829 | render_ty = array_info.elem_type; | ||
| 1830 | depth += 1; | ||
| 1496 | } | 1831 | } |
| 1497 | 1832 | ||
| 1498 | if (alignment != 0) | 1833 | if (alignment != 0 and alignment > ty.abiAlignment(target)) { |
| 1499 | try w.print("ZIG_ALIGN({}) ", .{alignment}); | 1834 | try w.print("zig_align({}) ", .{alignment}); |
| 1500 | try dg.renderType(w, render_ty); | 1835 | } |
| 1836 | try dg.renderType(w, render_ty, kind); | ||
| 1501 | 1837 | ||
| 1502 | const const_prefix = switch (mutability) { | 1838 | const const_prefix = switch (mutability) { |
| 1503 | .Const => "const ", | 1839 | .Const, .ConstArgument => "const ", |
| 1504 | .Mut => "", | 1840 | .Mut => "", |
| 1505 | }; | 1841 | }; |
| 1506 | try w.print(" {s}", .{const_prefix}); | 1842 | try w.print(" {s}", .{const_prefix}); |
| ... | @@ -1508,6 +1844,79 @@ pub const DeclGen = struct { | ... | @@ -1508,6 +1844,79 @@ pub const DeclGen = struct { |
| 1508 | try w.writeAll(suffix.items); | 1844 | try w.writeAll(suffix.items); |
| 1509 | } | 1845 | } |
| 1510 | 1846 | ||
| 1847 | fn renderTagNameFn(dg: *DeclGen, enum_ty: Type) error{ OutOfMemory, AnalysisFail }![]const u8 { | ||
| 1848 | var buffer = std.ArrayList(u8).init(dg.typedefs.allocator); | ||
| 1849 | defer buffer.deinit(); | ||
| 1850 | const bw = buffer.writer(); | ||
| 1851 | |||
| 1852 | const name_slice_ty = Type.initTag(.const_slice_u8_sentinel_0); | ||
| 1853 | |||
| 1854 | try buffer.appendSlice("static "); | ||
| 1855 | try dg.renderType(bw, name_slice_ty, .Complete); | ||
| 1856 | const name_begin = buffer.items.len + " ".len; | ||
| 1857 | try bw.print(" zig_tagName_{}(", .{typeToCIdentifier(enum_ty, dg.module)}); | ||
| 1858 | const name_end = buffer.items.len - "(".len; | ||
| 1859 | try dg.renderTypeAndName(bw, enum_ty, .{ .identifier = "tag" }, .Const, 0, .Complete); | ||
| 1860 | try buffer.appendSlice(") {\n switch (tag) {\n"); | ||
| 1861 | for (enum_ty.enumFields().keys()) |name, index| { | ||
| 1862 | const name_z = try dg.typedefs.allocator.dupeZ(u8, name); | ||
| 1863 | defer dg.typedefs.allocator.free(name_z); | ||
| 1864 | const name_bytes = name_z[0 .. name_z.len + 1]; | ||
| 1865 | |||
| 1866 | var tag_pl: Value.Payload.U32 = .{ | ||
| 1867 | .base = .{ .tag = .enum_field_index }, | ||
| 1868 | .data = @intCast(u32, index), | ||
| 1869 | }; | ||
| 1870 | const tag_val = Value.initPayload(&tag_pl.base); | ||
| 1871 | |||
| 1872 | var int_pl: Value.Payload.U64 = undefined; | ||
| 1873 | const int_val = tag_val.enumToInt(enum_ty, &int_pl); | ||
| 1874 | |||
| 1875 | var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len }; | ||
| 1876 | const name_ty = Type.initPayload(&name_ty_pl.base); | ||
| 1877 | |||
| 1878 | var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_bytes }; | ||
| 1879 | const name_val = Value.initPayload(&name_pl.base); | ||
| 1880 | |||
| 1881 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len }; | ||
| 1882 | const len_val = Value.initPayload(&len_pl.base); | ||
| 1883 | |||
| 1884 | try bw.print(" case {}: {{\n static ", .{try dg.fmtIntLiteral(enum_ty, int_val)}); | ||
| 1885 | try dg.renderTypeAndName(bw, name_ty, .{ .identifier = "name" }, .Const, 0, .Complete); | ||
| 1886 | try buffer.appendSlice(" = "); | ||
| 1887 | try dg.renderValue(bw, name_ty, name_val, .Initializer); | ||
| 1888 | try buffer.appendSlice(";\n return ("); | ||
| 1889 | try dg.renderTypecast(bw, name_slice_ty); | ||
| 1890 | try bw.print("){{{}, {}}};\n", .{ | ||
| 1891 | fmtIdent("name"), try dg.fmtIntLiteral(Type.usize, len_val), | ||
| 1892 | }); | ||
| 1893 | |||
| 1894 | try buffer.appendSlice(" }\n"); | ||
| 1895 | } | ||
| 1896 | try buffer.appendSlice(" }\n while ("); | ||
| 1897 | try dg.renderValue(bw, Type.bool, Value.@"true", .Other); | ||
| 1898 | try buffer.appendSlice(") "); | ||
| 1899 | _ = try airBreakpoint(bw); | ||
| 1900 | try buffer.appendSlice("}\n"); | ||
| 1901 | |||
| 1902 | const rendered = buffer.toOwnedSlice(); | ||
| 1903 | errdefer dg.typedefs.allocator.free(rendered); | ||
| 1904 | const name = rendered[name_begin..name_end]; | ||
| 1905 | |||
| 1906 | try dg.typedefs.ensureUnusedCapacity(1); | ||
| 1907 | dg.typedefs.putAssumeCapacityNoClobber( | ||
| 1908 | try enum_ty.copy(dg.typedefs_arena), | ||
| 1909 | .{ .name = name, .rendered = rendered }, | ||
| 1910 | ); | ||
| 1911 | |||
| 1912 | return name; | ||
| 1913 | } | ||
| 1914 | |||
| 1915 | fn getTagNameFn(dg: *DeclGen, enum_ty: Type) ![]const u8 { | ||
| 1916 | return dg.getTypedefName(enum_ty) orelse | ||
| 1917 | try dg.renderTagNameFn(enum_ty); | ||
| 1918 | } | ||
| 1919 | |||
| 1511 | fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool { | 1920 | fn declIsGlobal(dg: *DeclGen, tv: TypedValue) bool { |
| 1512 | switch (tv.val.tag()) { | 1921 | switch (tv.val.tag()) { |
| 1513 | .extern_fn => return true, | 1922 | .extern_fn => return true, |
| ... | @@ -1523,7 +1932,7 @@ pub const DeclGen = struct { | ... | @@ -1523,7 +1932,7 @@ pub const DeclGen = struct { |
| 1523 | } | 1932 | } |
| 1524 | } | 1933 | } |
| 1525 | 1934 | ||
| 1526 | fn writeCValue(dg: DeclGen, w: anytype, c_value: CValue) !void { | 1935 | fn writeCValue(dg: *DeclGen, w: anytype, c_value: CValue) !void { |
| 1527 | switch (c_value) { | 1936 | switch (c_value) { |
| 1528 | .none => unreachable, | 1937 | .none => unreachable, |
| 1529 | .local => |i| return w.print("t{d}", .{i}), | 1938 | .local => |i| return w.print("t{d}", .{i}), |
| ... | @@ -1535,20 +1944,13 @@ pub const DeclGen = struct { | ... | @@ -1535,20 +1944,13 @@ pub const DeclGen = struct { |
| 1535 | try w.writeByte('&'); | 1944 | try w.writeByte('&'); |
| 1536 | return dg.renderDeclName(w, decl); | 1945 | return dg.renderDeclName(w, decl); |
| 1537 | }, | 1946 | }, |
| 1538 | .undefined_ptr => { | 1947 | .undef => |ty| return dg.renderValue(w, ty, Value.undef, .Other), |
| 1539 | const target = dg.module.getTarget(); | ||
| 1540 | switch (target.cpu.arch.ptrBitWidth()) { | ||
| 1541 | 32 => try w.writeAll("(void *)0xaaaaaaaa"), | ||
| 1542 | 64 => try w.writeAll("(void *)0xaaaaaaaaaaaaaaaa"), | ||
| 1543 | else => unreachable, | ||
| 1544 | } | ||
| 1545 | }, | ||
| 1546 | .identifier => |ident| return w.print("{ }", .{fmtIdent(ident)}), | 1948 | .identifier => |ident| return w.print("{ }", .{fmtIdent(ident)}), |
| 1547 | .bytes => |bytes| return w.writeAll(bytes), | 1949 | .bytes => |bytes| return w.writeAll(bytes), |
| 1548 | } | 1950 | } |
| 1549 | } | 1951 | } |
| 1550 | 1952 | ||
| 1551 | fn writeCValueDeref(dg: DeclGen, w: anytype, c_value: CValue) !void { | 1953 | fn writeCValueDeref(dg: *DeclGen, w: anytype, c_value: CValue) !void { |
| 1552 | switch (c_value) { | 1954 | switch (c_value) { |
| 1553 | .none => unreachable, | 1955 | .none => unreachable, |
| 1554 | .local => |i| return w.print("(*t{d})", .{i}), | 1956 | .local => |i| return w.print("(*t{d})", .{i}), |
| ... | @@ -1561,7 +1963,7 @@ pub const DeclGen = struct { | ... | @@ -1561,7 +1963,7 @@ pub const DeclGen = struct { |
| 1561 | return w.writeByte(')'); | 1963 | return w.writeByte(')'); |
| 1562 | }, | 1964 | }, |
| 1563 | .decl_ref => |decl| return dg.renderDeclName(w, decl), | 1965 | .decl_ref => |decl| return dg.renderDeclName(w, decl), |
| 1564 | .undefined_ptr => unreachable, | 1966 | .undef => unreachable, |
| 1565 | .identifier => |ident| return w.print("(*{ })", .{fmtIdent(ident)}), | 1967 | .identifier => |ident| return w.print("(*{ })", .{fmtIdent(ident)}), |
| 1566 | .bytes => |bytes| { | 1968 | .bytes => |bytes| { |
| 1567 | try w.writeAll("(*"); | 1969 | try w.writeAll("(*"); |
| ... | @@ -1571,23 +1973,175 @@ pub const DeclGen = struct { | ... | @@ -1571,23 +1973,175 @@ pub const DeclGen = struct { |
| 1571 | } | 1973 | } |
| 1572 | } | 1974 | } |
| 1573 | 1975 | ||
| 1574 | fn renderDeclName(dg: DeclGen, writer: anytype, decl_index: Decl.Index) !void { | 1976 | fn writeCValueMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void { |
| 1977 | try dg.writeCValue(writer, c_value); | ||
| 1978 | try writer.writeByte('.'); | ||
| 1979 | try dg.writeCValue(writer, member); | ||
| 1980 | } | ||
| 1981 | |||
| 1982 | fn writeCValueDerefMember(dg: *DeclGen, writer: anytype, c_value: CValue, member: CValue) !void { | ||
| 1983 | switch (c_value) { | ||
| 1984 | .none, .constant, .undef => unreachable, | ||
| 1985 | .local, .arg, .decl, .identifier, .bytes => { | ||
| 1986 | try dg.writeCValue(writer, c_value); | ||
| 1987 | try writer.writeAll("->"); | ||
| 1988 | }, | ||
| 1989 | .local_ref, .decl_ref => { | ||
| 1990 | try dg.writeCValueDeref(writer, c_value); | ||
| 1991 | try writer.writeByte('.'); | ||
| 1992 | }, | ||
| 1993 | } | ||
| 1994 | try dg.writeCValue(writer, member); | ||
| 1995 | } | ||
| 1996 | |||
| 1997 | fn renderDeclName(dg: *DeclGen, writer: anytype, decl_index: Decl.Index) !void { | ||
| 1575 | const decl = dg.module.declPtr(decl_index); | 1998 | const decl = dg.module.declPtr(decl_index); |
| 1576 | dg.module.markDeclAlive(decl); | 1999 | dg.module.markDeclAlive(decl); |
| 1577 | 2000 | ||
| 1578 | if (dg.module.decl_exports.get(decl_index)) |exports| { | 2001 | if (dg.module.decl_exports.get(decl_index)) |exports| { |
| 1579 | return writer.writeAll(exports[0].options.name); | 2002 | return writer.writeAll(exports[0].options.name); |
| 1580 | } else if (decl.val.tag() == .extern_fn) { | 2003 | } else if (decl.isExtern()) { |
| 1581 | return writer.writeAll(mem.sliceTo(decl.name, 0)); | 2004 | return writer.writeAll(mem.sliceTo(decl.name, 0)); |
| 1582 | } else { | 2005 | } else { |
| 1583 | const gpa = dg.module.gpa; | 2006 | const gpa = dg.gpa; |
| 1584 | const name = try decl.getFullyQualifiedName(dg.module); | 2007 | const name = try decl.getFullyQualifiedName(dg.module); |
| 1585 | defer gpa.free(name); | 2008 | defer gpa.free(name); |
| 1586 | return writer.print("{ }", .{fmtIdent(name)}); | 2009 | return writer.print("{ }", .{fmtIdent(name)}); |
| 1587 | } | 2010 | } |
| 1588 | } | 2011 | } |
| 2012 | |||
| 2013 | fn renderTypeForBuiltinFnName(dg: *DeclGen, writer: anytype, ty: Type) !void { | ||
| 2014 | const target = dg.module.getTarget(); | ||
| 2015 | if (ty.isAbiInt()) { | ||
| 2016 | const int_info = ty.intInfo(target); | ||
| 2017 | const c_bits = toCIntBits(int_info.bits) orelse | ||
| 2018 | return dg.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); | ||
| 2019 | try writer.print("{c}{d}", .{ signAbbrev(int_info.signedness), c_bits }); | ||
| 2020 | } else if (ty.isRuntimeFloat()) { | ||
| 2021 | try ty.print(writer, dg.module); | ||
| 2022 | } else return dg.fail("TODO: CBE: implement renderTypeForBuiltinFnName for type {}", .{ | ||
| 2023 | ty.fmt(dg.module), | ||
| 2024 | }); | ||
| 2025 | } | ||
| 2026 | |||
| 2027 | fn renderBuiltinInfo(dg: *DeclGen, writer: anytype, ty: Type, info: BuiltinInfo) !void { | ||
| 2028 | const target = dg.module.getTarget(); | ||
| 2029 | switch (info) { | ||
| 2030 | .None => {}, | ||
| 2031 | .Range => { | ||
| 2032 | var arena = std.heap.ArenaAllocator.init(dg.gpa); | ||
| 2033 | defer arena.deinit(); | ||
| 2034 | |||
| 2035 | const ExpectedContents = union { u: Value.Payload.U64, i: Value.Payload.I64 }; | ||
| 2036 | var stack align(@alignOf(ExpectedContents)) = | ||
| 2037 | std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator()); | ||
| 2038 | |||
| 2039 | const int_info = ty.intInfo(target); | ||
| 2040 | if (int_info.signedness == .signed) { | ||
| 2041 | const min_val = try ty.minInt(stack.get(), target); | ||
| 2042 | try writer.print(", {x}", .{try dg.fmtIntLiteral(ty, min_val)}); | ||
| 2043 | } | ||
| 2044 | |||
| 2045 | const max_val = try ty.maxInt(stack.get(), target); | ||
| 2046 | try writer.print(", {x}", .{try dg.fmtIntLiteral(ty, max_val)}); | ||
| 2047 | }, | ||
| 2048 | .Bits => { | ||
| 2049 | var bits_pl = Value.Payload.U64{ | ||
| 2050 | .base = .{ .tag = .int_u64 }, | ||
| 2051 | .data = ty.bitSize(target), | ||
| 2052 | }; | ||
| 2053 | const bits_val = Value.initPayload(&bits_pl.base); | ||
| 2054 | try writer.print(", {}", .{try dg.fmtIntLiteral(Type.u8, bits_val)}); | ||
| 2055 | }, | ||
| 2056 | } | ||
| 2057 | } | ||
| 2058 | |||
| 2059 | fn fmtIntLiteral( | ||
| 2060 | dg: *DeclGen, | ||
| 2061 | ty: Type, | ||
| 2062 | val: Value, | ||
| 2063 | ) !std.fmt.Formatter(formatIntLiteral) { | ||
| 2064 | const int_info = ty.intInfo(dg.module.getTarget()); | ||
| 2065 | const c_bits = toCIntBits(int_info.bits); | ||
| 2066 | if (c_bits == null or c_bits.? > 128) | ||
| 2067 | return dg.fail("TODO implement integer constants larger than 128 bits", .{}); | ||
| 2068 | return std.fmt.Formatter(formatIntLiteral){ .data = .{ | ||
| 2069 | .ty = ty, | ||
| 2070 | .val = val, | ||
| 2071 | .mod = dg.module, | ||
| 2072 | } }; | ||
| 2073 | } | ||
| 1589 | }; | 2074 | }; |
| 1590 | 2075 | ||
| 2076 | pub fn genGlobalAsm(mod: *Module, code: *std.ArrayList(u8)) !void { | ||
| 2077 | var it = mod.global_assembly.valueIterator(); | ||
| 2078 | while (it.next()) |asm_source| { | ||
| 2079 | try code.writer().print("__asm({s});\n", .{fmtStringLiteral(asm_source.*)}); | ||
| 2080 | } | ||
| 2081 | } | ||
| 2082 | |||
| 2083 | pub fn genErrDecls(o: *Object) !void { | ||
| 2084 | const writer = o.writer(); | ||
| 2085 | |||
| 2086 | try writer.writeAll("enum {\n"); | ||
| 2087 | o.indent_writer.pushIndent(); | ||
| 2088 | var max_name_len: usize = 0; | ||
| 2089 | for (o.dg.module.error_name_list.items) |name, value| { | ||
| 2090 | max_name_len = std.math.max(name.len, max_name_len); | ||
| 2091 | var err_pl = Value.Payload.Error{ .data = .{ .name = name } }; | ||
| 2092 | try o.dg.renderValue(writer, Type.anyerror, Value.initPayload(&err_pl.base), .Other); | ||
| 2093 | try writer.print(" = {d}u,\n", .{value}); | ||
| 2094 | } | ||
| 2095 | o.indent_writer.popIndent(); | ||
| 2096 | try writer.writeAll("};\n"); | ||
| 2097 | |||
| 2098 | const name_prefix = "zig_errorName"; | ||
| 2099 | const name_buf = try o.dg.gpa.alloc(u8, name_prefix.len + "_".len + max_name_len + 1); | ||
| 2100 | defer o.dg.gpa.free(name_buf); | ||
| 2101 | |||
| 2102 | std.mem.copy(u8, name_buf, name_prefix ++ "_"); | ||
| 2103 | for (o.dg.module.error_name_list.items) |name| { | ||
| 2104 | std.mem.copy(u8, name_buf[name_prefix.len + "_".len ..], name); | ||
| 2105 | name_buf[name_prefix.len + "_".len + name.len] = 0; | ||
| 2106 | |||
| 2107 | const identifier = name_buf[0 .. name_prefix.len + "_".len + name.len :0]; | ||
| 2108 | const name_z = identifier[name_prefix.len + "_".len ..]; | ||
| 2109 | |||
| 2110 | var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len }; | ||
| 2111 | const name_ty = Type.initPayload(&name_ty_pl.base); | ||
| 2112 | |||
| 2113 | var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name_z }; | ||
| 2114 | const name_val = Value.initPayload(&name_pl.base); | ||
| 2115 | |||
| 2116 | try writer.writeAll("static "); | ||
| 2117 | try o.dg.renderTypeAndName(writer, name_ty, .{ .identifier = identifier }, .Const, 0, .Complete); | ||
| 2118 | try writer.writeAll(" = "); | ||
| 2119 | try o.dg.renderValue(writer, name_ty, name_val, .Initializer); | ||
| 2120 | try writer.writeAll(";\n"); | ||
| 2121 | } | ||
| 2122 | |||
| 2123 | var name_array_ty_pl = Type.Payload.Array{ .base = .{ .tag = .array }, .data = .{ | ||
| 2124 | .len = o.dg.module.error_name_list.items.len, | ||
| 2125 | .elem_type = Type.initTag(.const_slice_u8_sentinel_0), | ||
| 2126 | } }; | ||
| 2127 | const name_array_ty = Type.initPayload(&name_array_ty_pl.base); | ||
| 2128 | |||
| 2129 | try writer.writeAll("static "); | ||
| 2130 | try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = name_prefix }, .Const, 0, .Complete); | ||
| 2131 | try writer.writeAll(" = {"); | ||
| 2132 | for (o.dg.module.error_name_list.items) |name, value| { | ||
| 2133 | if (value != 0) try writer.writeByte(','); | ||
| 2134 | |||
| 2135 | var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len }; | ||
| 2136 | const len_val = Value.initPayload(&len_pl.base); | ||
| 2137 | |||
| 2138 | try writer.print("{{" ++ name_prefix ++ "_{}, {}}}", .{ | ||
| 2139 | fmtIdent(name), try o.dg.fmtIntLiteral(Type.usize, len_val), | ||
| 2140 | }); | ||
| 2141 | } | ||
| 2142 | try writer.writeAll("};\n"); | ||
| 2143 | } | ||
| 2144 | |||
| 1591 | pub fn genFunc(f: *Function) !void { | 2145 | pub fn genFunc(f: *Function) !void { |
| 1592 | const tracy = trace(@src()); | 2146 | const tracy = trace(@src()); |
| 1593 | defer tracy.end(); | 2147 | defer tracy.end(); |
| ... | @@ -1599,14 +2153,13 @@ pub fn genFunc(f: *Function) !void { | ... | @@ -1599,14 +2153,13 @@ pub fn genFunc(f: *Function) !void { |
| 1599 | 2153 | ||
| 1600 | const is_global = o.dg.module.decl_exports.contains(f.func.owner_decl); | 2154 | const is_global = o.dg.module.decl_exports.contains(f.func.owner_decl); |
| 1601 | const fwd_decl_writer = o.dg.fwd_decl.writer(); | 2155 | const fwd_decl_writer = o.dg.fwd_decl.writer(); |
| 1602 | if (is_global) { | 2156 | try fwd_decl_writer.writeAll(if (is_global) "zig_extern_c " else "static "); |
| 1603 | try fwd_decl_writer.writeAll("ZIG_EXTERN_C "); | 2157 | try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward); |
| 1604 | } | ||
| 1605 | try o.dg.renderFunctionSignature(fwd_decl_writer, is_global); | ||
| 1606 | try fwd_decl_writer.writeAll(";\n"); | 2158 | try fwd_decl_writer.writeAll(";\n"); |
| 1607 | 2159 | ||
| 1608 | try o.indent_writer.insertNewline(); | 2160 | try o.indent_writer.insertNewline(); |
| 1609 | try o.dg.renderFunctionSignature(o.writer(), is_global); | 2161 | if (!is_global) try o.writer().writeAll("static "); |
| 2162 | try o.dg.renderFunctionSignature(o.writer(), .Complete); | ||
| 1610 | try o.writer().writeByte(' '); | 2163 | try o.writer().writeByte(' '); |
| 1611 | 2164 | ||
| 1612 | // In case we need to use the header, populate it with a copy of the function | 2165 | // In case we need to use the header, populate it with a copy of the function |
| ... | @@ -1638,16 +2191,16 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -1638,16 +2191,16 @@ pub fn genDecl(o: *Object) !void { |
| 1638 | .val = o.dg.decl.val, | 2191 | .val = o.dg.decl.val, |
| 1639 | }; | 2192 | }; |
| 1640 | if (tv.val.tag() == .extern_fn) { | 2193 | if (tv.val.tag() == .extern_fn) { |
| 1641 | const writer = o.writer(); | 2194 | const fwd_decl_writer = o.dg.fwd_decl.writer(); |
| 1642 | try writer.writeAll("ZIG_EXTERN_C "); | 2195 | try fwd_decl_writer.writeAll("zig_extern_c "); |
| 1643 | try o.dg.renderFunctionSignature(writer, true); | 2196 | try o.dg.renderFunctionSignature(fwd_decl_writer, .Forward); |
| 1644 | try writer.writeAll(";\n"); | 2197 | try fwd_decl_writer.writeAll(";\n"); |
| 1645 | } else if (tv.val.castTag(.variable)) |var_payload| { | 2198 | } else if (tv.val.castTag(.variable)) |var_payload| { |
| 1646 | const variable: *Module.Var = var_payload.data; | 2199 | const variable: *Module.Var = var_payload.data; |
| 1647 | const is_global = o.dg.declIsGlobal(tv) or variable.is_extern; | 2200 | const is_global = o.dg.declIsGlobal(tv) or variable.is_extern; |
| 1648 | const fwd_decl_writer = o.dg.fwd_decl.writer(); | 2201 | const fwd_decl_writer = o.dg.fwd_decl.writer(); |
| 1649 | if (is_global) { | 2202 | if (is_global) { |
| 1650 | try fwd_decl_writer.writeAll("ZIG_EXTERN_C "); | 2203 | try fwd_decl_writer.writeAll("zig_extern_c "); |
| 1651 | } | 2204 | } |
| 1652 | if (variable.is_threadlocal) { | 2205 | if (variable.is_threadlocal) { |
| 1653 | try fwd_decl_writer.writeAll("zig_threadlocal "); | 2206 | try fwd_decl_writer.writeAll("zig_threadlocal "); |
| ... | @@ -1659,34 +2212,36 @@ pub fn genDecl(o: *Object) !void { | ... | @@ -1659,34 +2212,36 @@ pub fn genDecl(o: *Object) !void { |
| 1659 | .decl = o.dg.decl_index, | 2212 | .decl = o.dg.decl_index, |
| 1660 | }; | 2213 | }; |
| 1661 | 2214 | ||
| 1662 | try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align"); | 2215 | try o.dg.renderTypeAndName(fwd_decl_writer, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); |
| 1663 | try fwd_decl_writer.writeAll(";\n"); | 2216 | try fwd_decl_writer.writeAll(";\n"); |
| 1664 | 2217 | ||
| 1665 | if (variable.init.isUndefDeep()) { | 2218 | if (variable.is_extern or variable.init.isUndefDeep()) { |
| 1666 | return; | 2219 | return; |
| 1667 | } | 2220 | } |
| 1668 | 2221 | ||
| 1669 | try o.indent_writer.insertNewline(); | ||
| 1670 | const w = o.writer(); | 2222 | const w = o.writer(); |
| 1671 | try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align"); | 2223 | try o.dg.renderTypeAndName(w, o.dg.decl.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); |
| 1672 | try w.writeAll(" = "); | 2224 | try w.writeAll(" = "); |
| 1673 | if (variable.init.tag() != .unreachable_value) { | 2225 | if (variable.init.tag() != .unreachable_value) { |
| 1674 | try o.dg.renderValue(w, tv.ty, variable.init, .Other); | 2226 | try o.dg.renderValue(w, tv.ty, variable.init, .Initializer); |
| 1675 | } | 2227 | } |
| 1676 | try w.writeAll(";"); | 2228 | try w.writeByte(';'); |
| 1677 | try o.indent_writer.insertNewline(); | 2229 | try o.indent_writer.insertNewline(); |
| 1678 | } else { | 2230 | } else { |
| 2231 | const decl_c_value: CValue = .{ .decl = o.dg.decl_index }; | ||
| 2232 | |||
| 2233 | const fwd_decl_writer = o.dg.fwd_decl.writer(); | ||
| 2234 | try fwd_decl_writer.writeAll("static "); | ||
| 2235 | try o.dg.renderTypeAndName(fwd_decl_writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); | ||
| 2236 | try fwd_decl_writer.writeAll(";\n"); | ||
| 2237 | |||
| 1679 | const writer = o.writer(); | 2238 | const writer = o.writer(); |
| 1680 | try writer.writeAll("static "); | 2239 | try writer.writeAll("static "); |
| 1681 | |||
| 1682 | // TODO ask the Decl if it is const | 2240 | // TODO ask the Decl if it is const |
| 1683 | // https://github.com/ziglang/zig/issues/7582 | 2241 | // https://github.com/ziglang/zig/issues/7582 |
| 1684 | 2242 | try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align", .Complete); | |
| 1685 | const decl_c_value: CValue = .{ .decl = o.dg.decl_index }; | ||
| 1686 | try o.dg.renderTypeAndName(writer, tv.ty, decl_c_value, .Mut, o.dg.decl.@"align"); | ||
| 1687 | |||
| 1688 | try writer.writeAll(" = "); | 2243 | try writer.writeAll(" = "); |
| 1689 | try o.dg.renderValue(writer, tv.ty, tv.val, .Other); | 2244 | try o.dg.renderValue(writer, tv.ty, tv.val, .Initializer); |
| 1690 | try writer.writeAll(";\n"); | 2245 | try writer.writeAll(";\n"); |
| 1691 | } | 2246 | } |
| 1692 | } | 2247 | } |
| ... | @@ -1705,8 +2260,8 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void { | ... | @@ -1705,8 +2260,8 @@ pub fn genHeader(dg: *DeclGen) error{ AnalysisFail, OutOfMemory }!void { |
| 1705 | .Fn => { | 2260 | .Fn => { |
| 1706 | const is_global = dg.declIsGlobal(tv); | 2261 | const is_global = dg.declIsGlobal(tv); |
| 1707 | if (is_global) { | 2262 | if (is_global) { |
| 1708 | try writer.writeAll("ZIG_EXTERN_C "); | 2263 | try writer.writeAll("zig_extern_c "); |
| 1709 | try dg.renderFunctionSignature(writer, is_global); | 2264 | try dg.renderFunctionSignature(writer, .Complete); |
| 1710 | try dg.fwd_decl.appendSlice(";\n"); | 2265 | try dg.fwd_decl.appendSlice(";\n"); |
| 1711 | } | 2266 | } |
| 1712 | }, | 2267 | }, |
| ... | @@ -1733,44 +2288,53 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1733,44 +2288,53 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1733 | .const_ty => unreachable, // excluded from function bodies | 2288 | .const_ty => unreachable, // excluded from function bodies |
| 1734 | .arg => airArg(f), | 2289 | .arg => airArg(f), |
| 1735 | 2290 | ||
| 1736 | .breakpoint => try airBreakpoint(f), | 2291 | .breakpoint => try airBreakpoint(f.object.writer()), |
| 1737 | .ret_addr => try airRetAddr(f, inst), | 2292 | .ret_addr => try airRetAddr(f, inst), |
| 1738 | .frame_addr => try airFrameAddress(f, inst), | 2293 | .frame_addr => try airFrameAddress(f, inst), |
| 1739 | .unreach => try airUnreach(f), | 2294 | .unreach => try airUnreach(f), |
| 1740 | .fence => try airFence(f, inst), | 2295 | .fence => try airFence(f, inst), |
| 1741 | 2296 | ||
| 1742 | .ptr_add => try airPtrAddSub(f, inst, " + "), | 2297 | .ptr_add => try airPtrAddSub(f, inst, '+'), |
| 1743 | .ptr_sub => try airPtrAddSub(f, inst, " - "), | 2298 | .ptr_sub => try airPtrAddSub(f, inst, '-'), |
| 1744 | 2299 | ||
| 1745 | // TODO use a different strategy for add, sub, mul, div | 2300 | // TODO use a different strategy for add, sub, mul, div |
| 1746 | // that communicates to the optimizer that wrapping is UB. | 2301 | // that communicates to the optimizer that wrapping is UB. |
| 1747 | .add => try airBinOp (f, inst, " + "), | 2302 | .add => try airBinOp(f, inst, "+", "add", .None), |
| 1748 | .sub => try airBinOp (f, inst, " - "), | 2303 | .sub => try airBinOp(f, inst, "-", "sub", .None), |
| 1749 | .mul => try airBinOp (f, inst, " * "), | 2304 | .mul => try airBinOp(f, inst, "*", "mul", .None), |
| 1750 | .div_float, .div_exact => try airBinOp( f, inst, " / "), | 2305 | .div_float, .div_exact => try airBinOp(f, inst, "/", "div_trunc", .None), |
| 1751 | .rem => try airBinOp( f, inst, " % "), | ||
| 1752 | 2306 | ||
| 2307 | .rem => blk: { | ||
| 2308 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | ||
| 2309 | const lhs_ty = f.air.typeOf(bin_op.lhs); | ||
| 2310 | // For binary operations @TypeOf(lhs)==@TypeOf(rhs), | ||
| 2311 | // so we only check one. | ||
| 2312 | break :blk if (lhs_ty.isInt()) | ||
| 2313 | try airBinOp(f, inst, "%", "rem", .None) | ||
| 2314 | else | ||
| 2315 | try airBinFloatOp(f, inst, "fmod"); | ||
| 2316 | }, | ||
| 1753 | .div_trunc => blk: { | 2317 | .div_trunc => blk: { |
| 1754 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | 2318 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 1755 | const lhs_ty = f.air.typeOf(bin_op.lhs); | 2319 | const lhs_ty = f.air.typeOf(bin_op.lhs); |
| 1756 | // For binary operations @TypeOf(lhs)==@TypeOf(rhs), | 2320 | // For binary operations @TypeOf(lhs)==@TypeOf(rhs), |
| 1757 | // so we only check one. | 2321 | // so we only check one. |
| 1758 | break :blk if (lhs_ty.isInt()) | 2322 | break :blk if (lhs_ty.isInt()) |
| 1759 | try airBinOp(f, inst, " / ") | 2323 | try airBinOp(f, inst, "/", "div_trunc", .None) |
| 1760 | else | 2324 | else |
| 1761 | try airBinOpBuiltinCall(f, inst, "div_trunc"); | 2325 | try airBinBuiltinCall(f, inst, "div_trunc", .None); |
| 1762 | }, | 2326 | }, |
| 1763 | .div_floor => try airBinOpBuiltinCall(f, inst, "div_floor"), | 2327 | .div_floor => try airBinBuiltinCall(f, inst, "div_floor", .None), |
| 1764 | .mod => try airBinOpBuiltinCall(f, inst, "mod"), | 2328 | .mod => try airBinBuiltinCall(f, inst, "mod", .None), |
| 1765 | 2329 | ||
| 1766 | .addwrap => try airWrapOp(f, inst, " + ", "addw_"), | 2330 | .addwrap => try airBinBuiltinCall(f, inst, "addw", .Bits), |
| 1767 | .subwrap => try airWrapOp(f, inst, " - ", "subw_"), | 2331 | .subwrap => try airBinBuiltinCall(f, inst, "subw", .Bits), |
| 1768 | .mulwrap => try airWrapOp(f, inst, " * ", "mulw_"), | 2332 | .mulwrap => try airBinBuiltinCall(f, inst, "mulw", .Bits), |
| 1769 | 2333 | ||
| 1770 | .add_sat => try airSatOp(f, inst, "adds_"), | 2334 | .add_sat => try airBinBuiltinCall(f, inst, "adds", .Bits), |
| 1771 | .sub_sat => try airSatOp(f, inst, "subs_"), | 2335 | .sub_sat => try airBinBuiltinCall(f, inst, "subs", .Bits), |
| 1772 | .mul_sat => try airSatOp(f, inst, "muls_"), | 2336 | .mul_sat => try airBinBuiltinCall(f, inst, "muls", .Bits), |
| 1773 | .shl_sat => try airSatOp(f, inst, "shls_"), | 2337 | .shl_sat => try airBinBuiltinCall(f, inst, "shls", .Bits), |
| 1774 | 2338 | ||
| 1775 | .neg => try airNeg(f, inst), | 2339 | .neg => try airNeg(f, inst), |
| 1776 | 2340 | ||
| ... | @@ -1787,41 +2351,40 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1787,41 +2351,40 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1787 | .floor, | 2351 | .floor, |
| 1788 | .ceil, | 2352 | .ceil, |
| 1789 | .round, | 2353 | .round, |
| 1790 | .trunc_float, | 2354 | => |tag| try airUnFloatOp(f, inst, @tagName(tag)), |
| 1791 | => |tag| return f.fail("TODO: C backend: implement unary op for tag '{s}'", .{@tagName(tag)}), | 2355 | .trunc_float => try airUnFloatOp(f, inst, "trunc"), |
| 1792 | 2356 | ||
| 1793 | .mul_add => try airMulAdd(f, inst), | 2357 | .mul_add => try airMulAdd(f, inst), |
| 1794 | 2358 | ||
| 1795 | .add_with_overflow => try airOverflow(f, inst, "addo_"), | 2359 | .add_with_overflow => try airOverflow(f, inst, "add", .Bits), |
| 1796 | .sub_with_overflow => try airOverflow(f, inst, "subo_"), | 2360 | .sub_with_overflow => try airOverflow(f, inst, "sub", .Bits), |
| 1797 | .mul_with_overflow => try airOverflow(f, inst, "mulo_"), | 2361 | .mul_with_overflow => try airOverflow(f, inst, "mul", .Bits), |
| 1798 | .shl_with_overflow => try airOverflow(f, inst, "shlo_"), | 2362 | .shl_with_overflow => try airOverflow(f, inst, "shl", .Bits), |
| 1799 | 2363 | ||
| 1800 | .min => try airMinMax(f, inst, "<"), | 2364 | .min => try airMinMax(f, inst, '<'), |
| 1801 | .max => try airMinMax(f, inst, ">"), | 2365 | .max => try airMinMax(f, inst, '>'), |
| 1802 | 2366 | ||
| 1803 | .slice => try airSlice(f, inst), | 2367 | .slice => try airSlice(f, inst), |
| 1804 | 2368 | ||
| 1805 | .cmp_gt => try airBinOp(f, inst, " > "), | 2369 | .cmp_gt => try airCmpOp(f, inst, ">"), |
| 1806 | .cmp_gte => try airBinOp(f, inst, " >= "), | 2370 | .cmp_gte => try airCmpOp(f, inst, ">="), |
| 1807 | .cmp_lt => try airBinOp(f, inst, " < "), | 2371 | .cmp_lt => try airCmpOp(f, inst, "<"), |
| 1808 | .cmp_lte => try airBinOp(f, inst, " <= "), | 2372 | .cmp_lte => try airCmpOp(f, inst, "<="), |
| 1809 | 2373 | ||
| 1810 | .cmp_eq => try airEquality(f, inst, "((", "=="), | 2374 | .cmp_eq => try airEquality(f, inst, "((", "=="), |
| 1811 | .cmp_neq => try airEquality(f, inst, "!((", "!="), | 2375 | .cmp_neq => try airEquality(f, inst, "!((", "!="), |
| 1812 | 2376 | ||
| 1813 | .cmp_vector => return f.fail("TODO: C backend: implement cmp_vector", .{}), | 2377 | .cmp_vector => return f.fail("TODO: C backend: implement cmp_vector", .{}), |
| 1814 | .cmp_lt_errors_len => return f.fail("TODO: C backend: implement cmp_lt_errors_len", .{}), | 2378 | .cmp_lt_errors_len => try airCmpLtErrorsLen(f, inst), |
| 1815 | 2379 | ||
| 1816 | // bool_and and bool_or are non-short-circuit operations | 2380 | // bool_and and bool_or are non-short-circuit operations |
| 1817 | .bool_and => try airBinOp(f, inst, " & "), | 2381 | .bool_and, .bit_and => try airBinOp(f, inst, "&", "and", .None), |
| 1818 | .bool_or => try airBinOp(f, inst, " | "), | 2382 | .bool_or, .bit_or => try airBinOp(f, inst, "|", "or", .None), |
| 1819 | .bit_and => try airBinOp(f, inst, " & "), | 2383 | .xor => try airBinOp(f, inst, "^", "xor", .None), |
| 1820 | .bit_or => try airBinOp(f, inst, " | "), | 2384 | .shr, .shr_exact => try airBinBuiltinCall(f, inst, "shr", .None), |
| 1821 | .xor => try airBinOp(f, inst, " ^ "), | 2385 | .shl, => try airBinBuiltinCall(f, inst, "shl", .None), |
| 1822 | .shr, .shr_exact => try airBinOp(f, inst, " >> "), | 2386 | .shl_exact => try airBinOp(f, inst, "<<", "shl", .None), |
| 1823 | .shl, .shl_exact => try airBinOp(f, inst, " << "), | 2387 | .not => try airNot (f, inst), |
| 1824 | .not => try airNot (f, inst), | ||
| 1825 | 2388 | ||
| 1826 | .optional_payload => try airOptionalPayload(f, inst), | 2389 | .optional_payload => try airOptionalPayload(f, inst), |
| 1827 | .optional_payload_ptr => try airOptionalPayloadPtr(f, inst), | 2390 | .optional_payload_ptr => try airOptionalPayloadPtr(f, inst), |
| ... | @@ -1833,10 +2396,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1833,10 +2396,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1833 | .is_err_ptr => try airIsErr(f, inst, true, "!="), | 2396 | .is_err_ptr => try airIsErr(f, inst, true, "!="), |
| 1834 | .is_non_err_ptr => try airIsErr(f, inst, true, "=="), | 2397 | .is_non_err_ptr => try airIsErr(f, inst, true, "=="), |
| 1835 | 2398 | ||
| 1836 | .is_null => try airIsNull(f, inst, "==", ""), | 2399 | .is_null => try airIsNull(f, inst, "==", false), |
| 1837 | .is_non_null => try airIsNull(f, inst, "!=", ""), | 2400 | .is_non_null => try airIsNull(f, inst, "!=", false), |
| 1838 | .is_null_ptr => try airIsNull(f, inst, "==", "[0]"), | 2401 | .is_null_ptr => try airIsNull(f, inst, "==", true), |
| 1839 | .is_non_null_ptr => try airIsNull(f, inst, "!=", "[0]"), | 2402 | .is_non_null_ptr => try airIsNull(f, inst, "!=", true), |
| 1840 | 2403 | ||
| 1841 | .alloc => try airAlloc(f, inst), | 2404 | .alloc => try airAlloc(f, inst), |
| 1842 | .ret_ptr => try airRetPtr(f, inst), | 2405 | .ret_ptr => try airRetPtr(f, inst), |
| ... | @@ -1848,8 +2411,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1848,8 +2411,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1848 | .trunc => try airTrunc(f, inst), | 2411 | .trunc => try airTrunc(f, inst), |
| 1849 | .bool_to_int => try airBoolToInt(f, inst), | 2412 | .bool_to_int => try airBoolToInt(f, inst), |
| 1850 | .load => try airLoad(f, inst), | 2413 | .load => try airLoad(f, inst), |
| 1851 | .ret => try airRet(f, inst), | 2414 | .ret => try airRet(f, inst, false), |
| 1852 | .ret_load => try airRetLoad(f, inst), | 2415 | .ret_load => try airRet(f, inst, true), |
| 1853 | .store => try airStore(f, inst), | 2416 | .store => try airStore(f, inst), |
| 1854 | .loop => try airLoop(f, inst), | 2417 | .loop => try airLoop(f, inst), |
| 1855 | .cond_br => try airCondBr(f, inst), | 2418 | .cond_br => try airCondBr(f, inst), |
| ... | @@ -1865,11 +2428,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1865,11 +2428,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1865 | .memcpy => try airMemcpy(f, inst), | 2428 | .memcpy => try airMemcpy(f, inst), |
| 1866 | .set_union_tag => try airSetUnionTag(f, inst), | 2429 | .set_union_tag => try airSetUnionTag(f, inst), |
| 1867 | .get_union_tag => try airGetUnionTag(f, inst), | 2430 | .get_union_tag => try airGetUnionTag(f, inst), |
| 1868 | .clz => try airBuiltinCall(f, inst, "clz"), | 2431 | .clz => try airUnBuiltinCall(f, inst, "clz", .Bits), |
| 1869 | .ctz => try airBuiltinCall(f, inst, "ctz"), | 2432 | .ctz => try airUnBuiltinCall(f, inst, "ctz", .Bits), |
| 1870 | .popcount => try airBuiltinCall(f, inst, "popcount"), | 2433 | .popcount => try airUnBuiltinCall(f, inst, "popcount", .Bits), |
| 1871 | .byte_swap => try airBuiltinCall(f, inst, "byte_swap"), | 2434 | .byte_swap => try airUnBuiltinCall(f, inst, "byte_swap", .Bits), |
| 1872 | .bit_reverse => try airBuiltinCall(f, inst, "bit_reverse"), | 2435 | .bit_reverse => try airUnBuiltinCall(f, inst, "bit_reverse", .Bits), |
| 1873 | .tag_name => try airTagName(f, inst), | 2436 | .tag_name => try airTagName(f, inst), |
| 1874 | .error_name => try airErrorName(f, inst), | 2437 | .error_name => try airErrorName(f, inst), |
| 1875 | .splat => try airSplat(f, inst), | 2438 | .splat => try airSplat(f, inst), |
| ... | @@ -1922,11 +2485,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1922,11 +2485,11 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1922 | .field_parent_ptr => try airFieldParentPtr(f, inst), | 2485 | .field_parent_ptr => try airFieldParentPtr(f, inst), |
| 1923 | 2486 | ||
| 1924 | .struct_field_val => try airStructFieldVal(f, inst), | 2487 | .struct_field_val => try airStructFieldVal(f, inst), |
| 1925 | .slice_ptr => try airSliceField(f, inst, ".ptr;\n"), | 2488 | .slice_ptr => try airSliceField(f, inst, false, "ptr"), |
| 1926 | .slice_len => try airSliceField(f, inst, ".len;\n"), | 2489 | .slice_len => try airSliceField(f, inst, false, "len"), |
| 1927 | 2490 | ||
| 1928 | .ptr_slice_len_ptr => try airPtrSliceFieldPtr(f, inst, ".len;\n"), | 2491 | .ptr_slice_len_ptr => try airSliceField(f, inst, true, "len"), |
| 1929 | .ptr_slice_ptr_ptr => try airPtrSliceFieldPtr(f, inst, ".ptr;\n"), | 2492 | .ptr_slice_ptr_ptr => try airSliceField(f, inst, true, "ptr"), |
| 1930 | 2493 | ||
| 1931 | .ptr_elem_val => try airPtrElemVal(f, inst), | 2494 | .ptr_elem_val => try airPtrElemVal(f, inst), |
| 1932 | .ptr_elem_ptr => try airPtrElemPtr(f, inst), | 2495 | .ptr_elem_ptr => try airPtrElemPtr(f, inst), |
| ... | @@ -1934,8 +2497,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1934,8 +2497,8 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1934 | .slice_elem_ptr => try airSliceElemPtr(f, inst), | 2497 | .slice_elem_ptr => try airSliceElemPtr(f, inst), |
| 1935 | .array_elem_val => try airArrayElemVal(f, inst), | 2498 | .array_elem_val => try airArrayElemVal(f, inst), |
| 1936 | 2499 | ||
| 1937 | .unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst, ""), | 2500 | .unwrap_errunion_payload => try airUnwrapErrUnionPay(f, inst, false), |
| 1938 | .unwrap_errunion_payload_ptr => try airUnwrapErrUnionPay(f, inst, "&"), | 2501 | .unwrap_errunion_payload_ptr => try airUnwrapErrUnionPay(f, inst, true), |
| 1939 | .unwrap_errunion_err => try airUnwrapErrUnionErr(f, inst), | 2502 | .unwrap_errunion_err => try airUnwrapErrUnionErr(f, inst), |
| 1940 | .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst), | 2503 | .unwrap_errunion_err_ptr => try airUnwrapErrUnionErr(f, inst), |
| 1941 | .wrap_errunion_payload => try airWrapErrUnionPay(f, inst), | 2504 | .wrap_errunion_payload => try airWrapErrUnionPay(f, inst), |
| ... | @@ -1983,10 +2546,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO | ... | @@ -1983,10 +2546,10 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO |
| 1983 | } | 2546 | } |
| 1984 | 2547 | ||
| 1985 | f.object.indent_writer.popIndent(); | 2548 | f.object.indent_writer.popIndent(); |
| 1986 | try writer.writeAll("}"); | 2549 | try writer.writeByte('}'); |
| 1987 | } | 2550 | } |
| 1988 | 2551 | ||
| 1989 | fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue { | 2552 | fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: []const u8) !CValue { |
| 1990 | if (f.liveness.isUnused(inst)) return CValue.none; | 2553 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 1991 | 2554 | ||
| 1992 | const inst_ty = f.air.typeOfIndex(inst); | 2555 | const inst_ty = f.air.typeOfIndex(inst); |
| ... | @@ -1995,26 +2558,14 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue | ... | @@ -1995,26 +2558,14 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue |
| 1995 | const writer = f.object.writer(); | 2558 | const writer = f.object.writer(); |
| 1996 | const local = try f.allocLocal(inst_ty, .Const); | 2559 | const local = try f.allocLocal(inst_ty, .Const); |
| 1997 | try writer.writeAll(" = "); | 2560 | try writer.writeAll(" = "); |
| 1998 | try f.writeCValue(writer, operand); | 2561 | if (is_ptr) { |
| 1999 | try writer.writeAll(suffix); | 2562 | try writer.writeByte('&'); |
| 2563 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = field_name }); | ||
| 2564 | } else try f.writeCValueMember(writer, operand, .{ .identifier = field_name }); | ||
| 2565 | try writer.writeAll(";\n"); | ||
| 2000 | return local; | 2566 | return local; |
| 2001 | } | 2567 | } |
| 2002 | 2568 | ||
| 2003 | fn airPtrSliceFieldPtr(f: *Function, inst: Air.Inst.Index, suffix: []const u8) !CValue { | ||
| 2004 | if (f.liveness.isUnused(inst)) | ||
| 2005 | return CValue.none; | ||
| 2006 | |||
| 2007 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; | ||
| 2008 | const operand = try f.resolveInst(ty_op.operand); | ||
| 2009 | const writer = f.object.writer(); | ||
| 2010 | |||
| 2011 | _ = writer; | ||
| 2012 | _ = operand; | ||
| 2013 | _ = suffix; | ||
| 2014 | |||
| 2015 | return f.fail("TODO: C backend: airPtrSliceFieldPtr", .{}); | ||
| 2016 | } | ||
| 2017 | |||
| 2018 | fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | 2569 | fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2019 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | 2570 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 2020 | const ptr_ty = f.air.typeOf(bin_op.lhs); | 2571 | const ptr_ty = f.air.typeOf(bin_op.lhs); |
| ... | @@ -2025,9 +2576,9 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2025,9 +2576,9 @@ fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2025 | const writer = f.object.writer(); | 2576 | const writer = f.object.writer(); |
| 2026 | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); | 2577 | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); |
| 2027 | try writer.writeAll(" = "); | 2578 | try writer.writeAll(" = "); |
| 2028 | try f.writeCValue(writer, ptr); | 2579 | try f.writeCValue(writer, ptr, .Other); |
| 2029 | try writer.writeByte('['); | 2580 | try writer.writeByte('['); |
| 2030 | try f.writeCValue(writer, index); | 2581 | try f.writeCValue(writer, index, .Other); |
| 2031 | try writer.writeAll("];\n"); | 2582 | try writer.writeAll("];\n"); |
| 2032 | return local; | 2583 | return local; |
| 2033 | } | 2584 | } |
| ... | @@ -2049,10 +2600,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2049,10 +2600,10 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2049 | // It's a pointer to an array, so we need to de-reference. | 2600 | // It's a pointer to an array, so we need to de-reference. |
| 2050 | try f.writeCValueDeref(writer, ptr); | 2601 | try f.writeCValueDeref(writer, ptr); |
| 2051 | } else { | 2602 | } else { |
| 2052 | try f.writeCValue(writer, ptr); | 2603 | try f.writeCValue(writer, ptr, .Other); |
| 2053 | } | 2604 | } |
| 2054 | try writer.writeAll(")["); | 2605 | try writer.writeAll(")["); |
| 2055 | try f.writeCValue(writer, index); | 2606 | try f.writeCValue(writer, index, .Other); |
| 2056 | try writer.writeAll("];\n"); | 2607 | try writer.writeAll("];\n"); |
| 2057 | return local; | 2608 | return local; |
| 2058 | } | 2609 | } |
| ... | @@ -2067,9 +2618,9 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2067,9 +2618,9 @@ fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2067 | const writer = f.object.writer(); | 2618 | const writer = f.object.writer(); |
| 2068 | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); | 2619 | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); |
| 2069 | try writer.writeAll(" = "); | 2620 | try writer.writeAll(" = "); |
| 2070 | try f.writeCValue(writer, slice); | 2621 | try f.writeCValue(writer, slice, .Other); |
| 2071 | try writer.writeAll(".ptr["); | 2622 | try writer.writeAll(".ptr["); |
| 2072 | try f.writeCValue(writer, index); | 2623 | try f.writeCValue(writer, index, .Other); |
| 2073 | try writer.writeAll("];\n"); | 2624 | try writer.writeAll("];\n"); |
| 2074 | return local; | 2625 | return local; |
| 2075 | } | 2626 | } |
| ... | @@ -2085,9 +2636,9 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2085,9 +2636,9 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2085 | const writer = f.object.writer(); | 2636 | const writer = f.object.writer(); |
| 2086 | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); | 2637 | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); |
| 2087 | try writer.writeAll(" = &"); | 2638 | try writer.writeAll(" = &"); |
| 2088 | try f.writeCValue(writer, slice); | 2639 | try f.writeCValue(writer, slice, .Other); |
| 2089 | try writer.writeAll(".ptr["); | 2640 | try writer.writeAll(".ptr["); |
| 2090 | try f.writeCValue(writer, index); | 2641 | try f.writeCValue(writer, index, .Other); |
| 2091 | try writer.writeAll("];\n"); | 2642 | try writer.writeAll("];\n"); |
| 2092 | return local; | 2643 | return local; |
| 2093 | } | 2644 | } |
| ... | @@ -2101,9 +2652,9 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2101,9 +2652,9 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2101 | const writer = f.object.writer(); | 2652 | const writer = f.object.writer(); |
| 2102 | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); | 2653 | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); |
| 2103 | try writer.writeAll(" = "); | 2654 | try writer.writeAll(" = "); |
| 2104 | try f.writeCValue(writer, array); | 2655 | try f.writeCValue(writer, array, .Other); |
| 2105 | try writer.writeAll("["); | 2656 | try writer.writeByte('['); |
| 2106 | try f.writeCValue(writer, index); | 2657 | try f.writeCValue(writer, index, .Other); |
| 2107 | try writer.writeAll("];\n"); | 2658 | try writer.writeAll("];\n"); |
| 2108 | return local; | 2659 | return local; |
| 2109 | } | 2660 | } |
| ... | @@ -2115,7 +2666,7 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2115,7 +2666,7 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2115 | const elem_type = inst_ty.elemType(); | 2666 | const elem_type = inst_ty.elemType(); |
| 2116 | const mutability: Mutability = if (inst_ty.isConstPtr()) .Const else .Mut; | 2667 | const mutability: Mutability = if (inst_ty.isConstPtr()) .Const else .Mut; |
| 2117 | if (!elem_type.isFnOrHasRuntimeBitsIgnoreComptime()) { | 2668 | if (!elem_type.isFnOrHasRuntimeBitsIgnoreComptime()) { |
| 2118 | return CValue.undefined_ptr; | 2669 | return CValue{ .undef = inst_ty }; |
| 2119 | } | 2670 | } |
| 2120 | 2671 | ||
| 2121 | const target = f.object.dg.module.getTarget(); | 2672 | const target = f.object.dg.module.getTarget(); |
| ... | @@ -2130,9 +2681,13 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2130,9 +2681,13 @@ fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2130 | const writer = f.object.writer(); | 2681 | const writer = f.object.writer(); |
| 2131 | const inst_ty = f.air.typeOfIndex(inst); | 2682 | const inst_ty = f.air.typeOfIndex(inst); |
| 2132 | 2683 | ||
| 2684 | const elem_ty = inst_ty.elemType(); | ||
| 2685 | if (!elem_ty.hasRuntimeBitsIgnoreComptime()) { | ||
| 2686 | return CValue{ .undef = inst_ty }; | ||
| 2687 | } | ||
| 2688 | |||
| 2133 | // First line: the variable used as data storage. | 2689 | // First line: the variable used as data storage. |
| 2134 | const elem_type = inst_ty.elemType(); | 2690 | const local = try f.allocLocal(elem_ty, .Mut); |
| 2135 | const local = try f.allocLocal(elem_type, .Mut); | ||
| 2136 | try writer.writeAll(";\n"); | 2691 | try writer.writeAll(";\n"); |
| 2137 | 2692 | ||
| 2138 | return CValue{ .local_ref = local.local }; | 2693 | return CValue{ .local_ref = local.local }; |
| ... | @@ -2146,13 +2701,15 @@ fn airArg(f: *Function) CValue { | ... | @@ -2146,13 +2701,15 @@ fn airArg(f: *Function) CValue { |
| 2146 | 2701 | ||
| 2147 | fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { | 2702 | fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2148 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; | 2703 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 2149 | const is_volatile = f.air.typeOf(ty_op.operand).isVolatilePtr(); | 2704 | const ptr_info = f.air.typeOf(ty_op.operand).ptrInfo().data; |
| 2150 | 2705 | ||
| 2151 | if (!is_volatile and f.liveness.isUnused(inst)) | 2706 | const inst_ty = f.air.typeOfIndex(inst); |
| 2707 | if (!inst_ty.hasRuntimeBitsIgnoreComptime() or | ||
| 2708 | !ptr_info.@"volatile" and f.liveness.isUnused(inst)) | ||
| 2152 | return CValue.none; | 2709 | return CValue.none; |
| 2153 | 2710 | ||
| 2154 | const inst_ty = f.air.typeOfIndex(inst); | 2711 | const target = f.object.dg.module.getTarget(); |
| 2155 | const is_array = inst_ty.zigTypeTag() == .Array; | 2712 | const is_array = lowersToArray(inst_ty, target); |
| 2156 | const operand = try f.resolveInst(ty_op.operand); | 2713 | const operand = try f.resolveInst(ty_op.operand); |
| 2157 | const writer = f.object.writer(); | 2714 | const writer = f.object.writer(); |
| 2158 | 2715 | ||
| ... | @@ -2162,53 +2719,97 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2162,53 +2719,97 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2162 | if (is_array) { | 2719 | if (is_array) { |
| 2163 | // Insert a memcpy to initialize this array. The source operand is always a pointer | 2720 | // Insert a memcpy to initialize this array. The source operand is always a pointer |
| 2164 | // and thus we only need to know size/type information from the local type/dest. | 2721 | // and thus we only need to know size/type information from the local type/dest. |
| 2165 | try writer.writeAll(";"); | 2722 | try writer.writeAll(";\n"); |
| 2166 | try f.object.indent_writer.insertNewline(); | ||
| 2167 | try writer.writeAll("memcpy("); | 2723 | try writer.writeAll("memcpy("); |
| 2168 | try f.writeCValue(writer, local); | 2724 | try f.writeCValue(writer, local, .FunctionArgument); |
| 2169 | try writer.writeAll(", "); | 2725 | try writer.writeAll(", "); |
| 2170 | try f.writeCValue(writer, operand); | 2726 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 2171 | try writer.writeAll(", sizeof("); | 2727 | try writer.writeAll(", sizeof("); |
| 2172 | try f.writeCValue(writer, local); | 2728 | try f.renderTypecast(writer, inst_ty); |
| 2173 | try writer.writeAll("));\n"); | 2729 | try writer.writeAll("))"); |
| 2174 | } else { | 2730 | } else if (ptr_info.host_size != 0) { |
| 2175 | try writer.writeAll(" = "); | 2731 | var host_pl = Type.Payload.Bits{ |
| 2176 | try f.writeCValueDeref(writer, operand); | 2732 | .base = .{ .tag = .int_unsigned }, |
| 2177 | try writer.writeAll(";\n"); | 2733 | .data = ptr_info.host_size * 8, |
| 2178 | } | 2734 | }; |
| 2179 | return local; | 2735 | const host_ty = Type.initPayload(&host_pl.base); |
| 2180 | } | ||
| 2181 | 2736 | ||
| 2182 | fn airRet(f: *Function, inst: Air.Inst.Index) !CValue { | 2737 | var bit_offset_ty_pl = Type.Payload.Bits{ |
| 2183 | const un_op = f.air.instructions.items(.data)[inst].un_op; | 2738 | .base = .{ .tag = .int_unsigned }, |
| 2184 | const writer = f.object.writer(); | 2739 | .data = Type.smallestUnsignedBits(host_pl.data - 1), |
| 2185 | const ret_ty = f.air.typeOf(un_op); | 2740 | }; |
| 2186 | if (ret_ty.isFnOrHasRuntimeBitsIgnoreComptime()) { | 2741 | const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base); |
| 2187 | const operand = try f.resolveInst(un_op); | 2742 | |
| 2188 | try writer.writeAll("return "); | 2743 | var bit_offset_val_pl: Value.Payload.U64 = .{ |
| 2189 | try f.writeCValue(writer, operand); | 2744 | .base = .{ .tag = .int_u64 }, |
| 2190 | try writer.writeAll(";\n"); | 2745 | .data = ptr_info.bit_offset, |
| 2191 | } else if (ret_ty.isError()) { | 2746 | }; |
| 2192 | try writer.writeAll("return 0;"); | 2747 | const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base); |
| 2748 | |||
| 2749 | var field_pl = Type.Payload.Bits{ | ||
| 2750 | .base = .{ .tag = .int_unsigned }, | ||
| 2751 | .data = @intCast(u16, inst_ty.bitSize(target)), | ||
| 2752 | }; | ||
| 2753 | const field_ty = Type.initPayload(&field_pl.base); | ||
| 2754 | |||
| 2755 | try writer.writeAll(" = ("); | ||
| 2756 | try f.renderTypecast(writer, inst_ty); | ||
| 2757 | try writer.writeAll(")zig_wrap_"); | ||
| 2758 | try f.object.dg.renderTypeForBuiltinFnName(writer, field_ty); | ||
| 2759 | try writer.writeAll("(("); | ||
| 2760 | try f.renderTypecast(writer, field_ty); | ||
| 2761 | try writer.writeAll(")zig_shr_"); | ||
| 2762 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); | ||
| 2763 | try writer.writeByte('('); | ||
| 2764 | try f.writeCValueDeref(writer, operand); | ||
| 2765 | try writer.print(", {})", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)}); | ||
| 2766 | try f.object.dg.renderBuiltinInfo(writer, field_ty, .Bits); | ||
| 2767 | try writer.writeByte(')'); | ||
| 2193 | } else { | 2768 | } else { |
| 2194 | try writer.writeAll("return;\n"); | 2769 | try writer.writeAll(" = "); |
| 2770 | try f.writeCValueDeref(writer, operand); | ||
| 2195 | } | 2771 | } |
| 2196 | return CValue.none; | 2772 | try writer.writeAll(";\n"); |
| 2773 | return local; | ||
| 2197 | } | 2774 | } |
| 2198 | 2775 | ||
| 2199 | fn airRetLoad(f: *Function, inst: Air.Inst.Index) !CValue { | 2776 | fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { |
| 2200 | const un_op = f.air.instructions.items(.data)[inst].un_op; | 2777 | const un_op = f.air.instructions.items(.data)[inst].un_op; |
| 2201 | const writer = f.object.writer(); | 2778 | const writer = f.object.writer(); |
| 2202 | const ptr_ty = f.air.typeOf(un_op); | 2779 | const target = f.object.dg.module.getTarget(); |
| 2203 | const ret_ty = ptr_ty.childType(); | 2780 | const op_ty = f.air.typeOf(un_op); |
| 2204 | if (ret_ty.isFnOrHasRuntimeBitsIgnoreComptime()) { | 2781 | const ret_ty = if (is_ptr) op_ty.childType() else op_ty; |
| 2205 | const ptr = try f.resolveInst(un_op); | 2782 | var lowered_ret_buf: LowerFnRetTyBuffer = undefined; |
| 2206 | try writer.writeAll("return *"); | 2783 | const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, target); |
| 2207 | try f.writeCValue(writer, ptr); | 2784 | |
| 2785 | if (lowered_ret_ty.hasRuntimeBitsIgnoreComptime()) { | ||
| 2786 | var deref = is_ptr; | ||
| 2787 | const operand = try f.resolveInst(un_op); | ||
| 2788 | const ret_val = if (lowersToArray(ret_ty, target)) ret_val: { | ||
| 2789 | const array_local = try f.allocLocal(lowered_ret_ty, .Mut); | ||
| 2790 | try writer.writeAll(";\n"); | ||
| 2791 | try writer.writeAll("memcpy("); | ||
| 2792 | try f.writeCValueMember(writer, array_local, .{ .identifier = "array" }); | ||
| 2793 | try writer.writeAll(", "); | ||
| 2794 | if (deref) | ||
| 2795 | try f.writeCValueDeref(writer, operand) | ||
| 2796 | else | ||
| 2797 | try f.writeCValue(writer, operand, .FunctionArgument); | ||
| 2798 | deref = false; | ||
| 2799 | try writer.writeAll(", sizeof("); | ||
| 2800 | try f.renderTypecast(writer, ret_ty); | ||
| 2801 | try writer.writeAll("));\n"); | ||
| 2802 | break :ret_val array_local; | ||
| 2803 | } else operand; | ||
| 2804 | |||
| 2805 | try writer.writeAll("return "); | ||
| 2806 | if (deref) | ||
| 2807 | try f.writeCValueDeref(writer, ret_val) | ||
| 2808 | else | ||
| 2809 | try f.writeCValue(writer, ret_val, .Other); | ||
| 2208 | try writer.writeAll(";\n"); | 2810 | try writer.writeAll(";\n"); |
| 2209 | } else if (ret_ty.isError()) { | 2811 | } else if (f.object.dg.decl.ty.fnCallingConvention() != .Naked) { |
| 2210 | try writer.writeAll("return 0;\n"); | 2812 | // Not even allowed to return void in a naked function. |
| 2211 | } else { | ||
| 2212 | try writer.writeAll("return;\n"); | 2813 | try writer.writeAll("return;\n"); |
| 2213 | } | 2814 | } |
| 2214 | return CValue.none; | 2815 | return CValue.none; |
| ... | @@ -2226,8 +2827,8 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2226,8 +2827,8 @@ fn airIntCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2226 | const local = try f.allocLocal(inst_ty, .Const); | 2827 | const local = try f.allocLocal(inst_ty, .Const); |
| 2227 | try writer.writeAll(" = ("); | 2828 | try writer.writeAll(" = ("); |
| 2228 | try f.renderTypecast(writer, inst_ty); | 2829 | try f.renderTypecast(writer, inst_ty); |
| 2229 | try writer.writeAll(")"); | 2830 | try writer.writeByte(')'); |
| 2230 | try f.writeCValue(writer, operand); | 2831 | try f.writeCValue(writer, operand, .Other); |
| 2231 | try writer.writeAll(";\n"); | 2832 | try writer.writeAll(";\n"); |
| 2232 | return local; | 2833 | return local; |
| 2233 | } | 2834 | } |
| ... | @@ -2244,32 +2845,44 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2244,32 +2845,44 @@ fn airTrunc(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2244 | const dest_int_info = inst_ty.intInfo(target); | 2845 | const dest_int_info = inst_ty.intInfo(target); |
| 2245 | const dest_bits = dest_int_info.bits; | 2846 | const dest_bits = dest_int_info.bits; |
| 2246 | 2847 | ||
| 2247 | try writer.writeAll(" = "); | 2848 | try writer.writeAll(" = ("); |
| 2849 | try f.renderTypecast(writer, inst_ty); | ||
| 2850 | try writer.writeByte(')'); | ||
| 2248 | 2851 | ||
| 2249 | if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) { | 2852 | if (dest_bits >= 8 and std.math.isPowerOfTwo(dest_bits)) { |
| 2250 | try f.writeCValue(writer, operand); | 2853 | try f.writeCValue(writer, operand, .Other); |
| 2251 | try writer.writeAll(";\n"); | 2854 | try writer.writeAll(";\n"); |
| 2252 | return local; | 2855 | } else switch (dest_int_info.signedness) { |
| 2253 | } | ||
| 2254 | |||
| 2255 | switch (dest_int_info.signedness) { | ||
| 2256 | .unsigned => { | 2856 | .unsigned => { |
| 2257 | try f.writeCValue(writer, operand); | 2857 | var arena = std.heap.ArenaAllocator.init(f.object.dg.gpa); |
| 2258 | const mask = (@as(u65, 1) << @intCast(u7, dest_bits)) - 1; | 2858 | defer arena.deinit(); |
| 2259 | try writer.print(" & {d}ULL;\n", .{mask}); | 2859 | |
| 2260 | return local; | 2860 | const ExpectedContents = union { u: Value.Payload.U64, i: Value.Payload.I64 }; |
| 2861 | var stack align(@alignOf(ExpectedContents)) = | ||
| 2862 | std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator()); | ||
| 2863 | |||
| 2864 | const mask_val = try inst_ty.maxInt(stack.get(), target); | ||
| 2865 | |||
| 2866 | try writer.writeByte('('); | ||
| 2867 | try f.writeCValue(writer, operand, .Other); | ||
| 2868 | try writer.print(" & {x});\n", .{try f.fmtIntLiteral(inst_ty, mask_val)}); | ||
| 2261 | }, | 2869 | }, |
| 2262 | .signed => { | 2870 | .signed => { |
| 2263 | const operand_ty = f.air.typeOf(ty_op.operand); | 2871 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 2264 | const c_bits = toCIntBits(operand_ty.intInfo(target).bits) orelse | 2872 | const c_bits = toCIntBits(operand_ty.intInfo(target).bits) orelse |
| 2265 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); | 2873 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); |
| 2266 | const shift_rhs = c_bits - dest_bits; | 2874 | var shift_pl = Value.Payload.U64{ |
| 2267 | try writer.print("(int{d}_t)((uint{d}_t)", .{ c_bits, c_bits }); | 2875 | .base = .{ .tag = .int_u64 }, |
| 2268 | try f.writeCValue(writer, operand); | 2876 | .data = c_bits - dest_bits, |
| 2269 | try writer.print(" << {d}) >> {d};\n", .{ shift_rhs, shift_rhs }); | 2877 | }; |
| 2270 | return local; | 2878 | const shift_val = Value.initPayload(&shift_pl.base); |
| 2879 | |||
| 2880 | try writer.print("((int{d}_t)((uint{0d}_t)", .{c_bits}); | ||
| 2881 | try f.writeCValue(writer, operand, .Other); | ||
| 2882 | try writer.print(" << {}) >> {0});\n", .{try f.fmtIntLiteral(Type.u8, shift_val)}); | ||
| 2271 | }, | 2883 | }, |
| 2272 | } | 2884 | } |
| 2885 | return local; | ||
| 2273 | } | 2886 | } |
| 2274 | 2887 | ||
| 2275 | fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue { | 2888 | fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | @@ -2281,256 +2894,127 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2281,256 +2894,127 @@ fn airBoolToInt(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2281 | const operand = try f.resolveInst(un_op); | 2894 | const operand = try f.resolveInst(un_op); |
| 2282 | const local = try f.allocLocal(inst_ty, .Const); | 2895 | const local = try f.allocLocal(inst_ty, .Const); |
| 2283 | try writer.writeAll(" = "); | 2896 | try writer.writeAll(" = "); |
| 2284 | try f.writeCValue(writer, operand); | 2897 | try f.writeCValue(writer, operand, .Other); |
| 2285 | try writer.writeAll(";\n"); | 2898 | try writer.writeAll(";\n"); |
| 2286 | return local; | 2899 | return local; |
| 2287 | } | 2900 | } |
| 2288 | 2901 | ||
| 2289 | fn airStoreUndefined(f: *Function, dest_ptr: CValue) !CValue { | 2902 | fn airStoreUndefined(f: *Function, lhs_child_ty: Type, dest_ptr: CValue) !CValue { |
| 2290 | const is_debug_build = f.object.dg.module.optimizeMode() == .Debug; | 2903 | if (f.wantSafety()) { |
| 2291 | if (!is_debug_build) | 2904 | const writer = f.object.writer(); |
| 2292 | return CValue.none; | 2905 | try writer.writeAll("memset("); |
| 2293 | 2906 | try f.writeCValue(writer, dest_ptr, .FunctionArgument); | |
| 2294 | const writer = f.object.writer(); | 2907 | try writer.print(", {x}, sizeof(", .{try f.fmtIntLiteral(Type.u8, Value.undef)}); |
| 2295 | try writer.writeAll("memset("); | 2908 | try f.renderTypecast(writer, lhs_child_ty); |
| 2296 | try f.writeCValue(writer, dest_ptr); | 2909 | try writer.writeAll("));\n"); |
| 2297 | try writer.writeAll(", 0xaa, sizeof("); | 2910 | } |
| 2298 | try f.writeCValueDeref(writer, dest_ptr); | ||
| 2299 | try writer.writeAll("));\n"); | ||
| 2300 | return CValue.none; | 2911 | return CValue.none; |
| 2301 | } | 2912 | } |
| 2302 | 2913 | ||
| 2303 | fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { | 2914 | fn airStore(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2304 | // *a = b; | 2915 | // *a = b; |
| 2305 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | 2916 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 2306 | const dest_ptr = try f.resolveInst(bin_op.lhs); | 2917 | const ptr_info = f.air.typeOf(bin_op.lhs).ptrInfo().data; |
| 2918 | if (!ptr_info.pointee_type.hasRuntimeBitsIgnoreComptime()) return CValue.none; | ||
| 2919 | |||
| 2920 | const ptr_val = try f.resolveInst(bin_op.lhs); | ||
| 2921 | const src_ty = f.air.typeOf(bin_op.rhs); | ||
| 2307 | const src_val = try f.resolveInst(bin_op.rhs); | 2922 | const src_val = try f.resolveInst(bin_op.rhs); |
| 2308 | const lhs_child_type = f.air.typeOf(bin_op.lhs).childType(); | ||
| 2309 | 2923 | ||
| 2310 | // TODO Sema should emit a different instruction when the store should | 2924 | // TODO Sema should emit a different instruction when the store should |
| 2311 | // possibly do the safety 0xaa bytes for undefined. | 2925 | // possibly do the safety 0xaa bytes for undefined. |
| 2312 | const src_val_is_undefined = | 2926 | const src_val_is_undefined = |
| 2313 | if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false; | 2927 | if (f.air.value(bin_op.rhs)) |v| v.isUndefDeep() else false; |
| 2314 | if (src_val_is_undefined) | 2928 | if (src_val_is_undefined) |
| 2315 | return try airStoreUndefined(f, dest_ptr); | 2929 | return try airStoreUndefined(f, ptr_info.pointee_type, ptr_val); |
| 2316 | 2930 | ||
| 2931 | const target = f.object.dg.module.getTarget(); | ||
| 2317 | const writer = f.object.writer(); | 2932 | const writer = f.object.writer(); |
| 2318 | if (lhs_child_type.zigTypeTag() == .Array) { | 2933 | if (lowersToArray(ptr_info.pointee_type, target)) { |
| 2319 | // For this memcpy to safely work we need the rhs to have the same | 2934 | // For this memcpy to safely work we need the rhs to have the same |
| 2320 | // underlying type as the lhs (i.e. they must both be arrays of the same underlying type). | 2935 | // underlying type as the lhs (i.e. they must both be arrays of the same underlying type). |
| 2321 | const rhs_type = f.air.typeOf(bin_op.rhs); | 2936 | assert(src_ty.eql(ptr_info.pointee_type, f.object.dg.module)); |
| 2322 | assert(rhs_type.eql(lhs_child_type, f.object.dg.module)); | ||
| 2323 | 2937 | ||
| 2324 | // If the source is a constant, writeCValue will emit a brace initialization | 2938 | // If the source is a constant, writeCValue will emit a brace initialization |
| 2325 | // so work around this by initializing into new local. | 2939 | // so work around this by initializing into new local. |
| 2326 | // TODO this should be done by manually initializing elements of the dest array | 2940 | // TODO this should be done by manually initializing elements of the dest array |
| 2327 | const array_src = if (src_val == .constant) blk: { | 2941 | const array_src = if (src_val == .constant) blk: { |
| 2328 | const new_local = try f.allocLocal(rhs_type, .Const); | 2942 | const new_local = try f.allocLocal(src_ty, .Const); |
| 2329 | try writer.writeAll(" = "); | 2943 | try writer.writeAll(" = "); |
| 2330 | try f.writeCValue(writer, src_val); | 2944 | try f.writeCValue(writer, src_val, .Initializer); |
| 2331 | try writer.writeAll(";"); | 2945 | try writer.writeAll(";\n"); |
| 2332 | try f.object.indent_writer.insertNewline(); | ||
| 2333 | 2946 | ||
| 2334 | break :blk new_local; | 2947 | break :blk new_local; |
| 2335 | } else src_val; | 2948 | } else src_val; |
| 2336 | 2949 | ||
| 2337 | try writer.writeAll("memcpy("); | 2950 | try writer.writeAll("memcpy("); |
| 2338 | try f.writeCValue(writer, dest_ptr); | 2951 | try f.writeCValue(writer, ptr_val, .FunctionArgument); |
| 2339 | try writer.writeAll(", "); | 2952 | try writer.writeAll(", "); |
| 2340 | try f.writeCValue(writer, array_src); | 2953 | try f.writeCValue(writer, array_src, .FunctionArgument); |
| 2341 | try writer.writeAll(", sizeof("); | 2954 | try writer.writeAll(", sizeof("); |
| 2342 | try f.writeCValue(writer, array_src); | 2955 | try f.renderTypecast(writer, src_ty); |
| 2343 | try writer.writeAll("));\n"); | 2956 | try writer.writeAll("))"); |
| 2344 | } else { | 2957 | } else if (ptr_info.host_size != 0) { |
| 2345 | try f.writeCValueDeref(writer, dest_ptr); | 2958 | const host_bits = ptr_info.host_size * 8; |
| 2346 | try writer.writeAll(" = "); | 2959 | var host_pl = Type.Payload.Bits{ .base = .{ .tag = .int_unsigned }, .data = host_bits }; |
| 2347 | try f.writeCValue(writer, src_val); | 2960 | const host_ty = Type.initPayload(&host_pl.base); |
| 2348 | try writer.writeAll(";\n"); | 2961 | |
| 2349 | } | 2962 | var bit_offset_ty_pl = Type.Payload.Bits{ |
| 2350 | return CValue.none; | 2963 | .base = .{ .tag = .int_unsigned }, |
| 2351 | } | 2964 | .data = Type.smallestUnsignedBits(host_bits - 1), |
| 2352 | |||
| 2353 | fn airWrapOp( | ||
| 2354 | f: *Function, | ||
| 2355 | inst: Air.Inst.Index, | ||
| 2356 | str_op: [*:0]const u8, | ||
| 2357 | fn_op: [*:0]const u8, | ||
| 2358 | ) !CValue { | ||
| 2359 | if (f.liveness.isUnused(inst)) | ||
| 2360 | return CValue.none; | ||
| 2361 | |||
| 2362 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | ||
| 2363 | const inst_ty = f.air.typeOfIndex(inst); | ||
| 2364 | const target = f.object.dg.module.getTarget(); | ||
| 2365 | const int_info = inst_ty.intInfo(target); | ||
| 2366 | const bits = int_info.bits; | ||
| 2367 | |||
| 2368 | // if it's an unsigned int with non-arbitrary bit size then we can just add | ||
| 2369 | if (int_info.signedness == .unsigned) { | ||
| 2370 | const ok_bits = switch (bits) { | ||
| 2371 | 8, 16, 32, 64, 128 => true, | ||
| 2372 | else => false, | ||
| 2373 | }; | 2965 | }; |
| 2374 | if (ok_bits or inst_ty.tag() != .int_unsigned) { | 2966 | const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base); |
| 2375 | return try airBinOp(f, inst, str_op); | ||
| 2376 | } | ||
| 2377 | } | ||
| 2378 | |||
| 2379 | if (bits > 64) { | ||
| 2380 | return f.fail("TODO: C backend: airWrapOp for large integers", .{}); | ||
| 2381 | } | ||
| 2382 | |||
| 2383 | var max_buf: [80]u8 = undefined; | ||
| 2384 | const max = intMax(inst_ty, target, &max_buf); | ||
| 2385 | |||
| 2386 | const lhs = try f.resolveInst(bin_op.lhs); | ||
| 2387 | const rhs = try f.resolveInst(bin_op.rhs); | ||
| 2388 | const w = f.object.writer(); | ||
| 2389 | |||
| 2390 | const ret = try f.allocLocal(inst_ty, .Mut); | ||
| 2391 | try w.print(" = zig_{s}", .{fn_op}); | ||
| 2392 | |||
| 2393 | switch (inst_ty.tag()) { | ||
| 2394 | .isize => try w.writeAll("isize"), | ||
| 2395 | .c_short => try w.writeAll("short"), | ||
| 2396 | .c_int => try w.writeAll("int"), | ||
| 2397 | .c_long => try w.writeAll("long"), | ||
| 2398 | .c_longlong => try w.writeAll("longlong"), | ||
| 2399 | else => { | ||
| 2400 | const prefix_byte: u8 = signAbbrev(int_info.signedness); | ||
| 2401 | for ([_]u8{ 8, 16, 32, 64 }) |nbits| { | ||
| 2402 | if (bits <= nbits) { | ||
| 2403 | try w.print("{c}{d}", .{ prefix_byte, nbits }); | ||
| 2404 | break; | ||
| 2405 | } | ||
| 2406 | } else { | ||
| 2407 | unreachable; | ||
| 2408 | } | ||
| 2409 | }, | ||
| 2410 | } | ||
| 2411 | |||
| 2412 | try w.writeByte('('); | ||
| 2413 | try f.writeCValue(w, lhs); | ||
| 2414 | try w.writeAll(", "); | ||
| 2415 | try f.writeCValue(w, rhs); | ||
| 2416 | |||
| 2417 | if (int_info.signedness == .signed) { | ||
| 2418 | var min_buf: [80]u8 = undefined; | ||
| 2419 | const min = intMin(inst_ty, target, &min_buf); | ||
| 2420 | |||
| 2421 | try w.print(", {s}", .{min}); | ||
| 2422 | } | ||
| 2423 | |||
| 2424 | try w.print(", {s});", .{max}); | ||
| 2425 | try f.object.indent_writer.insertNewline(); | ||
| 2426 | |||
| 2427 | return ret; | ||
| 2428 | } | ||
| 2429 | |||
| 2430 | fn airSatOp(f: *Function, inst: Air.Inst.Index, fn_op: [*:0]const u8) !CValue { | ||
| 2431 | if (f.liveness.isUnused(inst)) | ||
| 2432 | return CValue.none; | ||
| 2433 | |||
| 2434 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | ||
| 2435 | const inst_ty = f.air.typeOfIndex(inst); | ||
| 2436 | const int_info = inst_ty.intInfo(f.object.dg.module.getTarget()); | ||
| 2437 | const bits = int_info.bits; | ||
| 2438 | |||
| 2439 | switch (bits) { | ||
| 2440 | 8, 16, 32, 64, 128 => {}, | ||
| 2441 | else => return f.object.dg.fail("TODO: C backend: airSatOp for non power of 2 integers", .{}), | ||
| 2442 | } | ||
| 2443 | |||
| 2444 | // if it's an unsigned int with non-arbitrary bit size then we can just add | ||
| 2445 | if (bits > 64) { | ||
| 2446 | return f.object.dg.fail("TODO: C backend: airSatOp for large integers", .{}); | ||
| 2447 | } | ||
| 2448 | 2967 | ||
| 2449 | var min_buf: [80]u8 = undefined; | 2968 | var bit_offset_val_pl: Value.Payload.U64 = .{ |
| 2450 | const min = switch (int_info.signedness) { | 2969 | .base = .{ .tag = .int_u64 }, |
| 2451 | .unsigned => "0", | 2970 | .data = ptr_info.bit_offset, |
| 2452 | else => switch (inst_ty.tag()) { | 2971 | }; |
| 2453 | .c_short => "SHRT_MIN", | 2972 | const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base); |
| 2454 | .c_int => "INT_MIN", | ||
| 2455 | .c_long => "LONG_MIN", | ||
| 2456 | .c_longlong => "LLONG_MIN", | ||
| 2457 | .isize => "INTPTR_MIN", | ||
| 2458 | else => blk: { | ||
| 2459 | // compute the type minimum based on the bitcount (bits) | ||
| 2460 | const val = -1 * std.math.pow(i65, 2, @intCast(i65, bits - 1)); | ||
| 2461 | break :blk std.fmt.bufPrint(&min_buf, "{d}", .{val}) catch |err| switch (err) { | ||
| 2462 | error.NoSpaceLeft => unreachable, | ||
| 2463 | }; | ||
| 2464 | }, | ||
| 2465 | }, | ||
| 2466 | }; | ||
| 2467 | 2973 | ||
| 2468 | var max_buf: [80]u8 = undefined; | 2974 | const src_bits = src_ty.bitSize(target); |
| 2469 | const max = switch (inst_ty.tag()) { | ||
| 2470 | .c_short => "SHRT_MAX", | ||
| 2471 | .c_ushort => "USHRT_MAX", | ||
| 2472 | .c_int => "INT_MAX", | ||
| 2473 | .c_uint => "UINT_MAX", | ||
| 2474 | .c_long => "LONG_MAX", | ||
| 2475 | .c_ulong => "ULONG_MAX", | ||
| 2476 | .c_longlong => "LLONG_MAX", | ||
| 2477 | .c_ulonglong => "ULLONG_MAX", | ||
| 2478 | .isize => "INTPTR_MAX", | ||
| 2479 | .usize => "UINTPTR_MAX", | ||
| 2480 | else => blk: { | ||
| 2481 | const pow_bits = switch (int_info.signedness) { | ||
| 2482 | .signed => bits - 1, | ||
| 2483 | .unsigned => bits, | ||
| 2484 | }; | ||
| 2485 | const val = std.math.pow(u65, 2, pow_bits) - 1; | ||
| 2486 | break :blk std.fmt.bufPrint(&max_buf, "{}", .{val}) catch |err| switch (err) { | ||
| 2487 | error.NoSpaceLeft => unreachable, | ||
| 2488 | }; | ||
| 2489 | }, | ||
| 2490 | }; | ||
| 2491 | 2975 | ||
| 2492 | const lhs = try f.resolveInst(bin_op.lhs); | 2976 | const Limb = std.math.big.Limb; |
| 2493 | const rhs = try f.resolveInst(bin_op.rhs); | 2977 | const ExpectedContents = [BigInt.Managed.default_capacity]Limb; |
| 2494 | const w = f.object.writer(); | 2978 | var stack align(@alignOf(ExpectedContents)) = |
| 2979 | std.heap.stackFallback(@sizeOf(ExpectedContents), f.object.dg.gpa); | ||
| 2495 | 2980 | ||
| 2496 | const ret = try f.allocLocal(inst_ty, .Mut); | 2981 | var mask = try BigInt.Managed.initCapacity(stack.get(), BigInt.calcTwosCompLimbCount(host_bits)); |
| 2497 | try w.print(" = zig_{s}", .{fn_op}); | 2982 | defer mask.deinit(); |
| 2498 | 2983 | ||
| 2499 | switch (inst_ty.tag()) { | 2984 | try mask.setTwosCompIntLimit(.max, .unsigned, @intCast(usize, src_bits)); |
| 2500 | .isize => try w.writeAll("isize"), | 2985 | try mask.shiftLeft(&mask, ptr_info.bit_offset); |
| 2501 | .c_short => try w.writeAll("short"), | 2986 | try mask.bitNotWrap(&mask, .unsigned, host_bits); |
| 2502 | .c_int => try w.writeAll("int"), | ||
| 2503 | .c_long => try w.writeAll("long"), | ||
| 2504 | .c_longlong => try w.writeAll("longlong"), | ||
| 2505 | else => { | ||
| 2506 | const prefix_byte: u8 = signAbbrev(int_info.signedness); | ||
| 2507 | for ([_]u8{ 8, 16, 32, 64 }) |nbits| { | ||
| 2508 | if (bits <= nbits) { | ||
| 2509 | try w.print("{c}{d}", .{ prefix_byte, nbits }); | ||
| 2510 | break; | ||
| 2511 | } | ||
| 2512 | } else { | ||
| 2513 | unreachable; | ||
| 2514 | } | ||
| 2515 | }, | ||
| 2516 | } | ||
| 2517 | 2987 | ||
| 2518 | try w.writeByte('('); | 2988 | var mask_pl = Value.Payload.BigInt{ |
| 2519 | try f.writeCValue(w, lhs); | 2989 | .base = .{ .tag = .int_big_positive }, |
| 2520 | try w.writeAll(", "); | 2990 | .data = mask.limbs[0..mask.len()], |
| 2521 | try f.writeCValue(w, rhs); | 2991 | }; |
| 2992 | const mask_val = Value.initPayload(&mask_pl.base); | ||
| 2522 | 2993 | ||
| 2523 | if (int_info.signedness == .signed) { | 2994 | try f.writeCValueDeref(writer, ptr_val); |
| 2524 | try w.print(", {s}", .{min}); | 2995 | try writer.writeAll(" = zig_or_"); |
| 2996 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); | ||
| 2997 | try writer.writeAll("(zig_and_"); | ||
| 2998 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); | ||
| 2999 | try writer.writeByte('('); | ||
| 3000 | try f.writeCValueDeref(writer, ptr_val); | ||
| 3001 | try writer.print(", {x}), zig_shl_", .{try f.fmtIntLiteral(host_ty, mask_val)}); | ||
| 3002 | try f.object.dg.renderTypeForBuiltinFnName(writer, host_ty); | ||
| 3003 | try writer.writeAll("(("); | ||
| 3004 | try f.renderTypecast(writer, host_ty); | ||
| 3005 | try writer.writeByte(')'); | ||
| 3006 | try f.writeCValue(writer, src_val, .Other); | ||
| 3007 | try writer.print(", {}))", .{try f.fmtIntLiteral(bit_offset_ty, bit_offset_val)}); | ||
| 3008 | } else { | ||
| 3009 | try f.writeCValueDeref(writer, ptr_val); | ||
| 3010 | try writer.writeAll(" = "); | ||
| 3011 | try f.writeCValue(writer, src_val, .Other); | ||
| 2525 | } | 3012 | } |
| 2526 | 3013 | try writer.writeAll(";\n"); | |
| 2527 | try w.print(", {s});", .{max}); | 3014 | return CValue.none; |
| 2528 | try f.object.indent_writer.insertNewline(); | ||
| 2529 | |||
| 2530 | return ret; | ||
| 2531 | } | 3015 | } |
| 2532 | 3016 | ||
| 2533 | fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8) !CValue { | 3017 | fn airOverflow(f: *Function, inst: Air.Inst.Index, operation: []const u8, info: BuiltinInfo) !CValue { |
| 2534 | if (f.liveness.isUnused(inst)) | 3018 | if (f.liveness.isUnused(inst)) |
| 2535 | return CValue.none; | 3019 | return CValue.none; |
| 2536 | 3020 | ||
| ... | @@ -2542,56 +3026,29 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8) !CV | ... | @@ -2542,56 +3026,29 @@ fn airOverflow(f: *Function, inst: Air.Inst.Index, op_abbrev: [*:0]const u8) !CV |
| 2542 | 3026 | ||
| 2543 | const inst_ty = f.air.typeOfIndex(inst); | 3027 | const inst_ty = f.air.typeOfIndex(inst); |
| 2544 | const scalar_ty = f.air.typeOf(bin_op.lhs).scalarType(); | 3028 | const scalar_ty = f.air.typeOf(bin_op.lhs).scalarType(); |
| 2545 | const target = f.object.dg.module.getTarget(); | ||
| 2546 | const int_info = scalar_ty.intInfo(target); | ||
| 2547 | const w = f.object.writer(); | 3029 | const w = f.object.writer(); |
| 2548 | const c_bits = toCIntBits(int_info.bits) orelse | ||
| 2549 | return f.fail("TODO: C backend: implement integer arithmetic larger than 128 bits", .{}); | ||
| 2550 | |||
| 2551 | var max_buf: [80]u8 = undefined; | ||
| 2552 | const max = intMax(scalar_ty, target, &max_buf); | ||
| 2553 | |||
| 2554 | const ret = try f.allocLocal(inst_ty, .Mut); | ||
| 2555 | try w.writeAll(";"); | ||
| 2556 | try f.object.indent_writer.insertNewline(); | ||
| 2557 | try f.writeCValue(w, ret); | ||
| 2558 | |||
| 2559 | switch (int_info.signedness) { | ||
| 2560 | .unsigned => { | ||
| 2561 | try w.print(".field_1 = zig_{s}u{d}(", .{ | ||
| 2562 | op_abbrev, c_bits, | ||
| 2563 | }); | ||
| 2564 | try f.writeCValue(w, lhs); | ||
| 2565 | try w.writeAll(", "); | ||
| 2566 | try f.writeCValue(w, rhs); | ||
| 2567 | try w.writeAll(", &"); | ||
| 2568 | try f.writeCValue(w, ret); | ||
| 2569 | try w.print(".field_0, {s}", .{max}); | ||
| 2570 | }, | ||
| 2571 | .signed => { | ||
| 2572 | var min_buf: [80]u8 = undefined; | ||
| 2573 | const min = intMin(scalar_ty, target, &min_buf); | ||
| 2574 | |||
| 2575 | try w.print(".field_1 = zig_{s}i{d}(", .{ | ||
| 2576 | op_abbrev, c_bits, | ||
| 2577 | }); | ||
| 2578 | try f.writeCValue(w, lhs); | ||
| 2579 | try w.writeAll(", "); | ||
| 2580 | try f.writeCValue(w, rhs); | ||
| 2581 | try w.writeAll(", &"); | ||
| 2582 | try f.writeCValue(w, ret); | ||
| 2583 | try w.print(".field_0, {s}, {s}", .{ min, max }); | ||
| 2584 | }, | ||
| 2585 | } | ||
| 2586 | 3030 | ||
| 2587 | try w.writeAll(");"); | 3031 | const local = try f.allocLocal(inst_ty, .Mut); |
| 2588 | try f.object.indent_writer.insertNewline(); | 3032 | try w.writeAll(";\n"); |
| 2589 | return ret; | 3033 | |
| 3034 | try f.writeCValue(w, local, .Other); | ||
| 3035 | try w.writeAll(".field_1 = zig_"); | ||
| 3036 | try w.writeAll(operation); | ||
| 3037 | try w.writeAll("o_"); | ||
| 3038 | try f.object.dg.renderTypeForBuiltinFnName(w, scalar_ty); | ||
| 3039 | try w.writeAll("(&"); | ||
| 3040 | try f.writeCValueMember(w, local, .{ .identifier = "field_0" }); | ||
| 3041 | try w.writeAll(", "); | ||
| 3042 | try f.writeCValue(w, lhs, .FunctionArgument); | ||
| 3043 | try w.writeAll(", "); | ||
| 3044 | try f.writeCValue(w, rhs, .FunctionArgument); | ||
| 3045 | try f.object.dg.renderBuiltinInfo(w, scalar_ty, info); | ||
| 3046 | try w.writeAll(");\n"); | ||
| 3047 | return local; | ||
| 2590 | } | 3048 | } |
| 2591 | 3049 | ||
| 2592 | fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { | 3050 | fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2593 | if (f.liveness.isUnused(inst)) | 3051 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 2594 | return CValue.none; | ||
| 2595 | 3052 | ||
| 2596 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; | 3053 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 2597 | const op = try f.resolveInst(ty_op.operand); | 3054 | const op = try f.resolveInst(ty_op.operand); |
| ... | @@ -2600,33 +3057,74 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2600,33 +3057,74 @@ fn airNot(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2600 | const inst_ty = f.air.typeOfIndex(inst); | 3057 | const inst_ty = f.air.typeOfIndex(inst); |
| 2601 | const local = try f.allocLocal(inst_ty, .Const); | 3058 | const local = try f.allocLocal(inst_ty, .Const); |
| 2602 | 3059 | ||
| 3060 | const target = f.object.dg.module.getTarget(); | ||
| 3061 | if (inst_ty.bitSize(target) > 64) {} | ||
| 3062 | |||
| 2603 | try writer.writeAll(" = "); | 3063 | try writer.writeAll(" = "); |
| 2604 | if (inst_ty.zigTypeTag() == .Bool) | 3064 | try writer.writeByte(if (inst_ty.tag() == .bool) '!' else '~'); |
| 2605 | try writer.writeAll("!") | 3065 | try f.writeCValue(writer, op, .Other); |
| 2606 | else | ||
| 2607 | try writer.writeAll("~"); | ||
| 2608 | try f.writeCValue(writer, op); | ||
| 2609 | try writer.writeAll(";\n"); | 3066 | try writer.writeAll(";\n"); |
| 2610 | 3067 | ||
| 2611 | return local; | 3068 | return local; |
| 2612 | } | 3069 | } |
| 2613 | 3070 | ||
| 2614 | fn airBinOp(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue { | 3071 | fn airBinOp( |
| 2615 | if (f.liveness.isUnused(inst)) | 3072 | f: *Function, |
| 2616 | return CValue.none; | 3073 | inst: Air.Inst.Index, |
| 3074 | operator: []const u8, | ||
| 3075 | operation: []const u8, | ||
| 3076 | info: BuiltinInfo, | ||
| 3077 | ) !CValue { | ||
| 3078 | if (f.liveness.isUnused(inst)) return CValue.none; | ||
| 2617 | 3079 | ||
| 2618 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | 3080 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 3081 | |||
| 3082 | const operand_ty = f.air.typeOf(bin_op.lhs); | ||
| 3083 | const target = f.object.dg.module.getTarget(); | ||
| 3084 | if (operand_ty.isInt() and operand_ty.bitSize(target) > 64) | ||
| 3085 | return try airBinBuiltinCall(f, inst, operation, info); | ||
| 3086 | |||
| 3087 | const inst_ty = f.air.typeOfIndex(inst); | ||
| 2619 | const lhs = try f.resolveInst(bin_op.lhs); | 3088 | const lhs = try f.resolveInst(bin_op.lhs); |
| 2620 | const rhs = try f.resolveInst(bin_op.rhs); | 3089 | const rhs = try f.resolveInst(bin_op.rhs); |
| 2621 | 3090 | ||
| 2622 | const writer = f.object.writer(); | 3091 | const writer = f.object.writer(); |
| 3092 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 3093 | |||
| 3094 | try writer.writeAll(" = "); | ||
| 3095 | try f.writeCValue(writer, lhs, .Other); | ||
| 3096 | try writer.writeByte(' '); | ||
| 3097 | try writer.writeAll(operator); | ||
| 3098 | try writer.writeByte(' '); | ||
| 3099 | try f.writeCValue(writer, rhs, .Other); | ||
| 3100 | try writer.writeAll(";\n"); | ||
| 3101 | |||
| 3102 | return local; | ||
| 3103 | } | ||
| 3104 | |||
| 3105 | fn airCmpOp(f: *Function, inst: Air.Inst.Index, operator: []const u8) !CValue { | ||
| 3106 | if (f.liveness.isUnused(inst)) return CValue.none; | ||
| 3107 | |||
| 3108 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | ||
| 3109 | |||
| 3110 | const operand_ty = f.air.typeOf(bin_op.lhs); | ||
| 3111 | const target = f.object.dg.module.getTarget(); | ||
| 3112 | if (operand_ty.isInt() and operand_ty.bitSize(target) > 64) | ||
| 3113 | return try airCmpBuiltinCall(f, inst, operator); | ||
| 3114 | |||
| 2623 | const inst_ty = f.air.typeOfIndex(inst); | 3115 | const inst_ty = f.air.typeOfIndex(inst); |
| 3116 | const lhs = try f.resolveInst(bin_op.lhs); | ||
| 3117 | const rhs = try f.resolveInst(bin_op.rhs); | ||
| 3118 | |||
| 3119 | const writer = f.object.writer(); | ||
| 2624 | const local = try f.allocLocal(inst_ty, .Const); | 3120 | const local = try f.allocLocal(inst_ty, .Const); |
| 2625 | 3121 | ||
| 2626 | try writer.writeAll(" = "); | 3122 | try writer.writeAll(" = "); |
| 2627 | try f.writeCValue(writer, lhs); | 3123 | try f.writeCValue(writer, lhs, .Other); |
| 2628 | try writer.print("{s}", .{operator}); | 3124 | try writer.writeByte(' '); |
| 2629 | try f.writeCValue(writer, rhs); | 3125 | try writer.writeAll(operator); |
| 3126 | try writer.writeByte(' '); | ||
| 3127 | try f.writeCValue(writer, rhs, .Other); | ||
| 2630 | try writer.writeAll(";\n"); | 3128 | try writer.writeAll(";\n"); |
| 2631 | 3129 | ||
| 2632 | return local; | 3130 | return local; |
| ... | @@ -2656,31 +3154,48 @@ fn airEquality( | ... | @@ -2656,31 +3154,48 @@ fn airEquality( |
| 2656 | // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload | 3154 | // A = lhs.is_null ; B = rhs.is_null ; C = rhs.payload == lhs.payload |
| 2657 | 3155 | ||
| 2658 | try writer.writeAll(negate_prefix); | 3156 | try writer.writeAll(negate_prefix); |
| 2659 | try f.writeCValue(writer, lhs); | 3157 | try f.writeCValue(writer, lhs, .Other); |
| 2660 | try writer.writeAll(".is_null && "); | 3158 | try writer.writeAll(".is_null && "); |
| 2661 | try f.writeCValue(writer, rhs); | 3159 | try f.writeCValue(writer, rhs, .Other); |
| 2662 | try writer.writeAll(".is_null) || ("); | 3160 | try writer.writeAll(".is_null) || ("); |
| 2663 | try f.writeCValue(writer, lhs); | 3161 | try f.writeCValue(writer, lhs, .Other); |
| 2664 | try writer.writeAll(".payload == "); | 3162 | try writer.writeAll(".payload == "); |
| 2665 | try f.writeCValue(writer, rhs); | 3163 | try f.writeCValue(writer, rhs, .Other); |
| 2666 | try writer.writeAll(".payload && "); | 3164 | try writer.writeAll(".payload && "); |
| 2667 | try f.writeCValue(writer, lhs); | 3165 | try f.writeCValue(writer, lhs, .Other); |
| 2668 | try writer.writeAll(".is_null == "); | 3166 | try writer.writeAll(".is_null == "); |
| 2669 | try f.writeCValue(writer, rhs); | 3167 | try f.writeCValue(writer, rhs, .Other); |
| 2670 | try writer.writeAll(".is_null));\n"); | 3168 | try writer.writeAll(".is_null));\n"); |
| 2671 | 3169 | ||
| 2672 | return local; | 3170 | return local; |
| 2673 | } | 3171 | } |
| 2674 | 3172 | ||
| 2675 | try f.writeCValue(writer, lhs); | 3173 | try f.writeCValue(writer, lhs, .Other); |
| 3174 | try writer.writeByte(' '); | ||
| 2676 | try writer.writeAll(eq_op_str); | 3175 | try writer.writeAll(eq_op_str); |
| 2677 | try f.writeCValue(writer, rhs); | 3176 | try writer.writeByte(' '); |
| 3177 | try f.writeCValue(writer, rhs, .Other); | ||
| 2678 | try writer.writeAll(";\n"); | 3178 | try writer.writeAll(";\n"); |
| 2679 | 3179 | ||
| 2680 | return local; | 3180 | return local; |
| 2681 | } | 3181 | } |
| 2682 | 3182 | ||
| 2683 | fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue { | 3183 | fn airCmpLtErrorsLen(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3184 | if (f.liveness.isUnused(inst)) return CValue.none; | ||
| 3185 | |||
| 3186 | const un_op = f.air.instructions.items(.data)[inst].un_op; | ||
| 3187 | const inst_ty = f.air.typeOfIndex(inst); | ||
| 3188 | const operand = try f.resolveInst(un_op); | ||
| 3189 | |||
| 3190 | const writer = f.object.writer(); | ||
| 3191 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 3192 | try writer.writeAll(" = "); | ||
| 3193 | try f.writeCValue(writer, operand, .Other); | ||
| 3194 | try writer.print(" < sizeof({ }) / sizeof(*{0 });\n", .{fmtIdent("zig_errorName")}); | ||
| 3195 | return local; | ||
| 3196 | } | ||
| 3197 | |||
| 3198 | fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { | ||
| 2684 | if (f.liveness.isUnused(inst)) return CValue.none; | 3199 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 2685 | 3200 | ||
| 2686 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; | 3201 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| ... | @@ -2704,17 +3219,19 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CV | ... | @@ -2704,17 +3219,19 @@ fn airPtrAddSub(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CV |
| 2704 | try writer.writeAll(" = ("); | 3219 | try writer.writeAll(" = ("); |
| 2705 | try f.renderTypecast(writer, inst_ty); | 3220 | try f.renderTypecast(writer, inst_ty); |
| 2706 | try writer.writeAll(")(((uintptr_t)"); | 3221 | try writer.writeAll(")(((uintptr_t)"); |
| 2707 | try f.writeCValue(writer, lhs); | 3222 | try f.writeCValue(writer, lhs, .Other); |
| 2708 | try writer.print("){s}(", .{operator}); | 3223 | try writer.writeAll(") "); |
| 2709 | try f.writeCValue(writer, rhs); | 3224 | try writer.writeByte(operator); |
| 3225 | try writer.writeAll(" ("); | ||
| 3226 | try f.writeCValue(writer, rhs, .Other); | ||
| 2710 | try writer.writeAll("*sizeof("); | 3227 | try writer.writeAll("*sizeof("); |
| 2711 | try f.renderTypecast(writer, elem_ty); | 3228 | try f.renderTypecast(writer, elem_ty); |
| 2712 | try writer.print(")));\n", .{}); | 3229 | try writer.writeAll(")));\n"); |
| 2713 | 3230 | ||
| 2714 | return local; | 3231 | return local; |
| 2715 | } | 3232 | } |
| 2716 | 3233 | ||
| 2717 | fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValue { | 3234 | fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8) !CValue { |
| 2718 | if (f.liveness.isUnused(inst)) return CValue.none; | 3235 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 2719 | 3236 | ||
| 2720 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | 3237 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -2727,13 +3244,15 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValu | ... | @@ -2727,13 +3244,15 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: [*:0]const u8) !CValu |
| 2727 | 3244 | ||
| 2728 | // (lhs <> rhs) ? lhs : rhs | 3245 | // (lhs <> rhs) ? lhs : rhs |
| 2729 | try writer.writeAll(" = ("); | 3246 | try writer.writeAll(" = ("); |
| 2730 | try f.writeCValue(writer, lhs); | 3247 | try f.writeCValue(writer, lhs, .Other); |
| 2731 | try writer.print("{s}", .{operator}); | 3248 | try writer.writeByte(' '); |
| 2732 | try f.writeCValue(writer, rhs); | 3249 | try writer.writeByte(operator); |
| 3250 | try writer.writeByte(' '); | ||
| 3251 | try f.writeCValue(writer, rhs, .Other); | ||
| 2733 | try writer.writeAll(") ? "); | 3252 | try writer.writeAll(") ? "); |
| 2734 | try f.writeCValue(writer, lhs); | 3253 | try f.writeCValue(writer, lhs, .Other); |
| 2735 | try writer.writeAll(" : "); | 3254 | try writer.writeAll(" : "); |
| 2736 | try f.writeCValue(writer, rhs); | 3255 | try f.writeCValue(writer, rhs, .Other); |
| 2737 | try writer.writeAll(";\n"); | 3256 | try writer.writeAll(";\n"); |
| 2738 | 3257 | ||
| 2739 | return local; | 3258 | return local; |
| ... | @@ -2751,10 +3270,13 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2751,10 +3270,13 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2751 | const inst_ty = f.air.typeOfIndex(inst); | 3270 | const inst_ty = f.air.typeOfIndex(inst); |
| 2752 | const local = try f.allocLocal(inst_ty, .Const); | 3271 | const local = try f.allocLocal(inst_ty, .Const); |
| 2753 | 3272 | ||
| 2754 | try writer.writeAll(" = {"); | 3273 | try writer.writeAll(" = {("); |
| 2755 | try f.writeCValue(writer, ptr); | 3274 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 3275 | try f.renderTypecast(writer, inst_ty.slicePtrFieldType(&buf)); | ||
| 3276 | try writer.writeByte(')'); | ||
| 3277 | try f.writeCValue(writer, ptr, .Other); | ||
| 2756 | try writer.writeAll(", "); | 3278 | try writer.writeAll(", "); |
| 2757 | try f.writeCValue(writer, len); | 3279 | try f.writeCValue(writer, len, .Initializer); |
| 2758 | try writer.writeAll("};\n"); | 3280 | try writer.writeAll("};\n"); |
| 2759 | 3281 | ||
| 2760 | return local; | 3282 | return local; |
| ... | @@ -2765,6 +3287,9 @@ fn airCall( | ... | @@ -2765,6 +3287,9 @@ fn airCall( |
| 2765 | inst: Air.Inst.Index, | 3287 | inst: Air.Inst.Index, |
| 2766 | modifier: std.builtin.CallOptions.Modifier, | 3288 | modifier: std.builtin.CallOptions.Modifier, |
| 2767 | ) !CValue { | 3289 | ) !CValue { |
| 3290 | // Not even allowed to call panic in a naked function. | ||
| 3291 | if (f.object.dg.decl.ty.fnCallingConvention() == .Naked) return .none; | ||
| 3292 | |||
| 2768 | switch (modifier) { | 3293 | switch (modifier) { |
| 2769 | .auto => {}, | 3294 | .auto => {}, |
| 2770 | .always_tail => return f.fail("TODO: C backend: call with always_tail attribute", .{}), | 3295 | .always_tail => return f.fail("TODO: C backend: call with always_tail attribute", .{}), |
| ... | @@ -2783,39 +3308,50 @@ fn airCall( | ... | @@ -2783,39 +3308,50 @@ fn airCall( |
| 2783 | }; | 3308 | }; |
| 2784 | const writer = f.object.writer(); | 3309 | const writer = f.object.writer(); |
| 2785 | 3310 | ||
| 2786 | const result_local: CValue = r: { | 3311 | const target = f.object.dg.module.getTarget(); |
| 2787 | if (f.liveness.isUnused(inst)) { | 3312 | const ret_ty = fn_ty.fnReturnType(); |
| 2788 | if (loweredFnRetTyHasBits(fn_ty)) { | 3313 | var lowered_ret_buf: LowerFnRetTyBuffer = undefined; |
| 2789 | try writer.print("(void)", .{}); | 3314 | const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, target); |
| 2790 | } | 3315 | |
| 2791 | break :r .none; | 3316 | const result_local: CValue = if (!lowered_ret_ty.hasRuntimeBitsIgnoreComptime()) |
| 2792 | } else { | 3317 | .none |
| 2793 | const local = try f.allocLocal(fn_ty.fnReturnType(), .Const); | 3318 | else if (f.liveness.isUnused(inst)) r: { |
| 2794 | try writer.writeAll(" = "); | 3319 | try writer.writeByte('('); |
| 2795 | break :r local; | 3320 | try f.renderTypecast(writer, Type.void); |
| 2796 | } | 3321 | try writer.writeByte(')'); |
| 3322 | break :r .none; | ||
| 3323 | } else r: { | ||
| 3324 | const local = try f.allocLocal(lowered_ret_ty, .Const); | ||
| 3325 | try writer.writeAll(" = "); | ||
| 3326 | break :r local; | ||
| 2797 | }; | 3327 | }; |
| 2798 | 3328 | ||
| 3329 | var is_extern = false; | ||
| 3330 | var name: [*:0]const u8 = ""; | ||
| 2799 | callee: { | 3331 | callee: { |
| 2800 | known: { | 3332 | known: { |
| 2801 | const fn_decl = fn_decl: { | 3333 | const fn_decl = fn_decl: { |
| 2802 | const callee_val = f.air.value(pl_op.operand) orelse break :known; | 3334 | const callee_val = f.air.value(pl_op.operand) orelse break :known; |
| 2803 | break :fn_decl switch (callee_val.tag()) { | 3335 | break :fn_decl switch (callee_val.tag()) { |
| 2804 | .extern_fn => callee_val.castTag(.extern_fn).?.data.owner_decl, | 3336 | .extern_fn => blk: { |
| 3337 | is_extern = true; | ||
| 3338 | break :blk callee_val.castTag(.extern_fn).?.data.owner_decl; | ||
| 3339 | }, | ||
| 2805 | .function => callee_val.castTag(.function).?.data.owner_decl, | 3340 | .function => callee_val.castTag(.function).?.data.owner_decl, |
| 2806 | .decl_ref => callee_val.castTag(.decl_ref).?.data, | 3341 | .decl_ref => callee_val.castTag(.decl_ref).?.data, |
| 2807 | else => break :known, | 3342 | else => break :known, |
| 2808 | }; | 3343 | }; |
| 2809 | }; | 3344 | }; |
| 3345 | name = f.object.dg.module.declPtr(fn_decl).name; | ||
| 2810 | try f.object.dg.renderDeclName(writer, fn_decl); | 3346 | try f.object.dg.renderDeclName(writer, fn_decl); |
| 2811 | break :callee; | 3347 | break :callee; |
| 2812 | } | 3348 | } |
| 2813 | // Fall back to function pointer call. | 3349 | // Fall back to function pointer call. |
| 2814 | const callee = try f.resolveInst(pl_op.operand); | 3350 | const callee = try f.resolveInst(pl_op.operand); |
| 2815 | try f.writeCValue(writer, callee); | 3351 | try f.writeCValue(writer, callee, .Other); |
| 2816 | } | 3352 | } |
| 2817 | 3353 | ||
| 2818 | try writer.writeAll("("); | 3354 | try writer.writeByte('('); |
| 2819 | var args_written: usize = 0; | 3355 | var args_written: usize = 0; |
| 2820 | for (args) |arg| { | 3356 | for (args) |arg| { |
| 2821 | const ty = f.air.typeOf(arg); | 3357 | const ty = f.air.typeOf(arg); |
| ... | @@ -2823,16 +3359,32 @@ fn airCall( | ... | @@ -2823,16 +3359,32 @@ fn airCall( |
| 2823 | if (args_written != 0) { | 3359 | if (args_written != 0) { |
| 2824 | try writer.writeAll(", "); | 3360 | try writer.writeAll(", "); |
| 2825 | } | 3361 | } |
| 2826 | if (f.air.value(arg)) |val| { | 3362 | if ((is_extern or std.mem.eql(u8, std.mem.span(name), "main")) and |
| 2827 | try f.object.dg.renderValue(writer, f.air.typeOf(arg), val, .FunctionArgument); | 3363 | ty.isCPtr() and ty.childType().tag() == .u8) |
| 2828 | } else { | 3364 | { |
| 2829 | const val = try f.resolveInst(arg); | 3365 | // Corresponds with hack in renderType .Pointer case. |
| 2830 | try f.writeCValue(writer, val); | 3366 | try writer.writeAll("(char"); |
| 3367 | if (ty.isConstPtr()) try writer.writeAll(" const"); | ||
| 3368 | if (ty.isVolatilePtr()) try writer.writeAll(" volatile"); | ||
| 3369 | try writer.writeAll(" *)"); | ||
| 2831 | } | 3370 | } |
| 3371 | try f.writeCValue(writer, try f.resolveInst(arg), .FunctionArgument); | ||
| 2832 | args_written += 1; | 3372 | args_written += 1; |
| 2833 | } | 3373 | } |
| 2834 | try writer.writeAll(");\n"); | 3374 | try writer.writeAll(");\n"); |
| 2835 | return result_local; | 3375 | |
| 3376 | if (result_local == .none or !lowersToArray(ret_ty, target)) return result_local; | ||
| 3377 | |||
| 3378 | const array_local = try f.allocLocal(ret_ty, .Mut); | ||
| 3379 | try writer.writeAll(";\n"); | ||
| 3380 | try writer.writeAll("memcpy("); | ||
| 3381 | try f.writeCValue(writer, array_local, .FunctionArgument); | ||
| 3382 | try writer.writeAll(", "); | ||
| 3383 | try f.writeCValueMember(writer, result_local, .{ .identifier = "array" }); | ||
| 3384 | try writer.writeAll(", sizeof("); | ||
| 3385 | try f.renderTypecast(writer, ret_ty); | ||
| 3386 | try writer.writeAll("));\n"); | ||
| 3387 | return array_local; | ||
| 2836 | } | 3388 | } |
| 2837 | 3389 | ||
| 2838 | fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue { | 3390 | fn airDbgStmt(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | @@ -2931,27 +3483,19 @@ fn lowerTry( | ... | @@ -2931,27 +3483,19 @@ fn lowerTry( |
| 2931 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(); | 3483 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(); |
| 2932 | 3484 | ||
| 2933 | if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) { | 3485 | if (!err_union_ty.errorUnionSet().errorSetIsEmpty()) { |
| 2934 | err: { | 3486 | try writer.writeAll("if ("); |
| 2935 | if (!payload_has_bits) { | 3487 | if (!payload_has_bits) { |
| 2936 | if (operand_is_ptr) { | 3488 | if (operand_is_ptr) |
| 2937 | try writer.writeAll("if(*"); | 3489 | try f.writeCValueDeref(writer, err_union) |
| 2938 | } else { | 3490 | else |
| 2939 | try writer.writeAll("if("); | 3491 | try f.writeCValue(writer, err_union, .Other); |
| 2940 | } | 3492 | } else { |
| 2941 | try f.writeCValue(writer, err_union); | 3493 | if (operand_is_ptr or isByRef(err_union_ty)) |
| 2942 | try writer.writeAll(")"); | 3494 | try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "error" }) |
| 2943 | break :err; | 3495 | else |
| 2944 | } | 3496 | try f.writeCValueMember(writer, err_union, .{ .identifier = "error" }); |
| 2945 | if (operand_is_ptr or isByRef(err_union_ty)) { | ||
| 2946 | try writer.writeAll("if("); | ||
| 2947 | try f.writeCValue(writer, err_union); | ||
| 2948 | try writer.writeAll("->error)"); | ||
| 2949 | break :err; | ||
| 2950 | } | ||
| 2951 | try writer.writeAll("if("); | ||
| 2952 | try f.writeCValue(writer, err_union); | ||
| 2953 | try writer.writeAll(".error)"); | ||
| 2954 | } | 3497 | } |
| 3498 | try writer.writeByte(')'); | ||
| 2955 | 3499 | ||
| 2956 | try genBody(f, body); | 3500 | try genBody(f, body); |
| 2957 | try f.object.indent_writer.insertNewline(); | 3501 | try f.object.indent_writer.insertNewline(); |
| ... | @@ -2965,15 +3509,25 @@ fn lowerTry( | ... | @@ -2965,15 +3509,25 @@ fn lowerTry( |
| 2965 | } | 3509 | } |
| 2966 | } | 3510 | } |
| 2967 | 3511 | ||
| 2968 | const local = try f.allocLocal(result_ty, .Const); | 3512 | const target = f.object.dg.module.getTarget(); |
| 2969 | if (operand_is_ptr or isByRef(payload_ty)) { | 3513 | const is_array = lowersToArray(payload_ty, target); |
| 2970 | try writer.writeAll(" = &"); | 3514 | const local = try f.allocLocal(result_ty, if (is_array) .Mut else .Const); |
| 2971 | try f.writeCValue(writer, err_union); | 3515 | if (is_array) { |
| 2972 | try writer.writeAll("->payload;\n"); | 3516 | try writer.writeAll(";\n"); |
| 3517 | try writer.writeAll("memcpy("); | ||
| 3518 | try f.writeCValue(writer, local, .FunctionArgument); | ||
| 3519 | try writer.writeAll(", "); | ||
| 3520 | try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" }); | ||
| 3521 | try writer.writeAll(", sizeof("); | ||
| 3522 | try f.renderTypecast(writer, payload_ty); | ||
| 3523 | try writer.writeAll("));\n"); | ||
| 2973 | } else { | 3524 | } else { |
| 2974 | try writer.writeAll(" = "); | 3525 | try writer.writeAll(" = "); |
| 2975 | try f.writeCValue(writer, err_union); | 3526 | if (operand_is_ptr or isByRef(payload_ty)) { |
| 2976 | try writer.writeAll(".payload;\n"); | 3527 | try writer.writeByte('&'); |
| 3528 | try f.writeCValueDerefMember(writer, err_union, .{ .identifier = "payload" }); | ||
| 3529 | } else try f.writeCValueMember(writer, err_union, .{ .identifier = "payload" }); | ||
| 3530 | try writer.writeAll(";\n"); | ||
| 2977 | } | 3531 | } |
| 2978 | return local; | 3532 | return local; |
| 2979 | } | 3533 | } |
| ... | @@ -2987,9 +3541,9 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2987,9 +3541,9 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2987 | // If result is .none then the value of the block is unused. | 3541 | // If result is .none then the value of the block is unused. |
| 2988 | if (result != .none) { | 3542 | if (result != .none) { |
| 2989 | const operand = try f.resolveInst(branch.operand); | 3543 | const operand = try f.resolveInst(branch.operand); |
| 2990 | try f.writeCValue(writer, result); | 3544 | try f.writeCValue(writer, result, .Other); |
| 2991 | try writer.writeAll(" = "); | 3545 | try writer.writeAll(" = "); |
| 2992 | try f.writeCValue(writer, operand); | 3546 | try f.writeCValue(writer, operand, .Other); |
| 2993 | try writer.writeAll(";\n"); | 3547 | try writer.writeAll(";\n"); |
| 2994 | } | 3548 | } |
| 2995 | 3549 | ||
| ... | @@ -3013,8 +3567,8 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3013,8 +3567,8 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3013 | try writer.writeAll(" = ("); | 3567 | try writer.writeAll(" = ("); |
| 3014 | try f.renderTypecast(writer, inst_ty); | 3568 | try f.renderTypecast(writer, inst_ty); |
| 3015 | 3569 | ||
| 3016 | try writer.writeAll(")"); | 3570 | try writer.writeByte(')'); |
| 3017 | try f.writeCValue(writer, operand); | 3571 | try f.writeCValue(writer, operand, .Other); |
| 3018 | try writer.writeAll(";\n"); | 3572 | try writer.writeAll(";\n"); |
| 3019 | return local; | 3573 | return local; |
| 3020 | } | 3574 | } |
| ... | @@ -3023,32 +3577,38 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3023,32 +3577,38 @@ fn airBitcast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3023 | try writer.writeAll(";\n"); | 3577 | try writer.writeAll(";\n"); |
| 3024 | 3578 | ||
| 3025 | try writer.writeAll("memcpy(&"); | 3579 | try writer.writeAll("memcpy(&"); |
| 3026 | try f.writeCValue(writer, local); | 3580 | try f.writeCValue(writer, local, .Other); |
| 3027 | try writer.writeAll(", &"); | 3581 | try writer.writeAll(", &"); |
| 3028 | try f.writeCValue(writer, operand); | 3582 | try f.writeCValue(writer, operand, .Other); |
| 3029 | try writer.writeAll(", sizeof("); | 3583 | try writer.writeAll(", sizeof("); |
| 3030 | try f.writeCValue(writer, local); | 3584 | try f.renderTypecast(writer, inst_ty); |
| 3031 | try writer.writeAll("));\n"); | 3585 | try writer.writeAll("));\n"); |
| 3032 | 3586 | ||
| 3033 | return local; | 3587 | return local; |
| 3034 | } | 3588 | } |
| 3035 | 3589 | ||
| 3036 | fn airBreakpoint(f: *Function) !CValue { | 3590 | fn airBreakpoint(writer: anytype) !CValue { |
| 3037 | try f.object.writer().writeAll("zig_breakpoint();\n"); | 3591 | try writer.writeAll("zig_breakpoint();\n"); |
| 3038 | return CValue.none; | 3592 | return CValue.none; |
| 3039 | } | 3593 | } |
| 3040 | 3594 | ||
| 3041 | fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue { | 3595 | fn airRetAddr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3042 | if (f.liveness.isUnused(inst)) return CValue.none; | 3596 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 3597 | const writer = f.object.writer(); | ||
| 3043 | const local = try f.allocLocal(Type.usize, .Const); | 3598 | const local = try f.allocLocal(Type.usize, .Const); |
| 3044 | try f.object.writer().writeAll(" = zig_return_address();\n"); | 3599 | try writer.writeAll(" = ("); |
| 3600 | try f.renderTypecast(writer, Type.usize); | ||
| 3601 | try writer.writeAll(")zig_return_address();\n"); | ||
| 3045 | return local; | 3602 | return local; |
| 3046 | } | 3603 | } |
| 3047 | 3604 | ||
| 3048 | fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue { | 3605 | fn airFrameAddress(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3049 | if (f.liveness.isUnused(inst)) return CValue.none; | 3606 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 3607 | const writer = f.object.writer(); | ||
| 3050 | const local = try f.allocLocal(Type.usize, .Const); | 3608 | const local = try f.allocLocal(Type.usize, .Const); |
| 3051 | try f.object.writer().writeAll(" = zig_frame_address();\n"); | 3609 | try writer.writeAll(" = ("); |
| 3610 | try f.renderTypecast(writer, Type.usize); | ||
| 3611 | try writer.writeAll(")zig_frame_address();\n"); | ||
| 3052 | return local; | 3612 | return local; |
| 3053 | } | 3613 | } |
| 3054 | 3614 | ||
| ... | @@ -3064,6 +3624,9 @@ fn airFence(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3064,6 +3624,9 @@ fn airFence(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3064 | } | 3624 | } |
| 3065 | 3625 | ||
| 3066 | fn airUnreach(f: *Function) !CValue { | 3626 | fn airUnreach(f: *Function) !CValue { |
| 3627 | // Not even allowed to call unreachable in a naked function. | ||
| 3628 | if (f.object.dg.decl.ty.fnCallingConvention() == .Naked) return .none; | ||
| 3629 | |||
| 3067 | try f.object.writer().writeAll("zig_unreachable();\n"); | 3630 | try f.object.writer().writeAll("zig_unreachable();\n"); |
| 3068 | return CValue.none; | 3631 | return CValue.none; |
| 3069 | } | 3632 | } |
| ... | @@ -3072,9 +3635,12 @@ fn airLoop(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3072,9 +3635,12 @@ fn airLoop(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3072 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; | 3635 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| 3073 | const loop = f.air.extraData(Air.Block, ty_pl.payload); | 3636 | const loop = f.air.extraData(Air.Block, ty_pl.payload); |
| 3074 | const body = f.air.extra[loop.end..][0..loop.data.body_len]; | 3637 | const body = f.air.extra[loop.end..][0..loop.data.body_len]; |
| 3075 | try f.object.writer().writeAll("while (true) "); | 3638 | const writer = f.object.writer(); |
| 3639 | try writer.writeAll("while ("); | ||
| 3640 | try f.object.dg.renderValue(writer, Type.bool, Value.@"true", .Other); | ||
| 3641 | try writer.writeAll(") "); | ||
| 3076 | try genBody(f, body); | 3642 | try genBody(f, body); |
| 3077 | try f.object.indent_writer.insertNewline(); | 3643 | try writer.writeByte('\n'); |
| 3078 | return CValue.none; | 3644 | return CValue.none; |
| 3079 | } | 3645 | } |
| 3080 | 3646 | ||
| ... | @@ -3087,7 +3653,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3087,7 +3653,7 @@ fn airCondBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3087 | const writer = f.object.writer(); | 3653 | const writer = f.object.writer(); |
| 3088 | 3654 | ||
| 3089 | try writer.writeAll("if ("); | 3655 | try writer.writeAll("if ("); |
| 3090 | try f.writeCValue(writer, cond); | 3656 | try f.writeCValue(writer, cond, .Other); |
| 3091 | try writer.writeAll(") "); | 3657 | try writer.writeAll(") "); |
| 3092 | try genBody(f, then_body); | 3658 | try genBody(f, then_body); |
| 3093 | try writer.writeAll(" else "); | 3659 | try writer.writeAll(" else "); |
| ... | @@ -3105,7 +3671,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3105,7 +3671,12 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3105 | const writer = f.object.writer(); | 3671 | const writer = f.object.writer(); |
| 3106 | 3672 | ||
| 3107 | try writer.writeAll("switch ("); | 3673 | try writer.writeAll("switch ("); |
| 3108 | try f.writeCValue(writer, condition); | 3674 | if (condition_ty.tag() == .bool) { |
| 3675 | try writer.writeByte('('); | ||
| 3676 | try f.renderTypecast(writer, Type.u1); | ||
| 3677 | try writer.writeByte(')'); | ||
| 3678 | } | ||
| 3679 | try f.writeCValue(writer, condition, .Other); | ||
| 3109 | try writer.writeAll(") {"); | 3680 | try writer.writeAll(") {"); |
| 3110 | f.object.indent_writer.pushIndent(); | 3681 | f.object.indent_writer.pushIndent(); |
| 3111 | 3682 | ||
| ... | @@ -3138,6 +3709,14 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3138,6 +3709,14 @@ fn airSwitchBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3138 | return CValue.none; | 3709 | return CValue.none; |
| 3139 | } | 3710 | } |
| 3140 | 3711 | ||
| 3712 | fn asmInputNeedsLocal(constraint: []const u8, value: CValue) bool { | ||
| 3713 | return switch (constraint[0]) { | ||
| 3714 | '{' => true, | ||
| 3715 | 'i', 'r' => false, | ||
| 3716 | else => value == .constant, | ||
| 3717 | }; | ||
| 3718 | } | ||
| 3719 | |||
| 3141 | fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | 3720 | fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3142 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; | 3721 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| 3143 | const extra = f.air.extraData(Air.Asm, ty_pl.payload); | 3722 | const extra = f.air.extraData(Air.Asm, ty_pl.payload); |
| ... | @@ -3151,54 +3730,79 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3151,54 +3730,79 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3151 | 3730 | ||
| 3152 | if (!is_volatile and f.liveness.isUnused(inst)) return CValue.none; | 3731 | if (!is_volatile and f.liveness.isUnused(inst)) return CValue.none; |
| 3153 | 3732 | ||
| 3154 | if (outputs.len > 1) { | 3733 | const writer = f.object.writer(); |
| 3155 | return f.fail("TODO implement codegen for asm with more than 1 output", .{}); | 3734 | const inst_ty = f.air.typeOfIndex(inst); |
| 3156 | } | 3735 | const local = if (inst_ty.hasRuntimeBitsIgnoreComptime()) local: { |
| 3157 | 3736 | const local = try f.allocLocal(inst_ty, .Mut); | |
| 3158 | const output_constraint: ?[]const u8 = for (outputs) |output| { | 3737 | if (f.wantSafety()) { |
| 3159 | if (output != .none) { | 3738 | try writer.writeAll(" = "); |
| 3160 | return f.fail("TODO implement codegen for non-expr asm", .{}); | 3739 | try f.writeCValue(writer, .{ .undef = inst_ty }, .Initializer); |
| 3161 | } | 3740 | } |
| 3741 | try writer.writeAll(";\n"); | ||
| 3742 | break :local local; | ||
| 3743 | } else .none; | ||
| 3744 | |||
| 3745 | const locals_begin = f.next_local_index; | ||
| 3746 | const constraints_extra_begin = extra_i; | ||
| 3747 | for (outputs) |output| { | ||
| 3162 | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); | 3748 | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); |
| 3163 | const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0); | 3749 | const constraint = std.mem.sliceTo(extra_bytes, 0); |
| 3164 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | 3750 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); |
| 3165 | // This equation accounts for the fact that even if we have exactly 4 bytes | 3751 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 3166 | // for the string, we still use the next u32 for the null terminator. | 3752 | // for the string, we still use the next u32 for the null terminator. |
| 3167 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | 3753 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| 3168 | 3754 | ||
| 3169 | break constraint; | 3755 | if (constraint.len < 2 or constraint[0] != '=' or |
| 3170 | } else null; | 3756 | (constraint[1] == '{' and constraint[constraint.len - 1] != '}')) |
| 3171 | 3757 | { | |
| 3172 | const writer = f.object.writer(); | 3758 | return f.fail("CBE: constraint not supported: '{s}'", .{constraint}); |
| 3173 | try writer.writeAll("{\n"); | 3759 | } |
| 3174 | 3760 | ||
| 3175 | const inputs_extra_begin = extra_i; | 3761 | const is_reg = constraint[1] == '{'; |
| 3176 | for (inputs) |input, i| { | 3762 | if (is_reg) { |
| 3177 | const input_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); | 3763 | const output_ty = if (output == .none) inst_ty else f.air.typeOf(output).childType(); |
| 3178 | const constraint = std.mem.sliceTo(input_bytes, 0); | 3764 | try writer.writeAll("register "); |
| 3179 | const name = std.mem.sliceTo(input_bytes[constraint.len + 1 ..], 0); | 3765 | _ = try f.allocLocal(output_ty, .Mut); |
| 3766 | try writer.writeAll(" __asm(\""); | ||
| 3767 | try writer.writeAll(constraint["={".len .. constraint.len - "}".len]); | ||
| 3768 | try writer.writeAll("\")"); | ||
| 3769 | if (f.wantSafety()) { | ||
| 3770 | try writer.writeAll(" = "); | ||
| 3771 | try f.writeCValue(writer, .{ .undef = output_ty }, .Initializer); | ||
| 3772 | } | ||
| 3773 | try writer.writeAll(";\n"); | ||
| 3774 | } | ||
| 3775 | } | ||
| 3776 | for (inputs) |input| { | ||
| 3777 | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); | ||
| 3778 | const constraint = std.mem.sliceTo(extra_bytes, 0); | ||
| 3779 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | ||
| 3180 | // This equation accounts for the fact that even if we have exactly 4 bytes | 3780 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 3181 | // for the string, we still use the next u32 for the null terminator. | 3781 | // for the string, we still use the next u32 for the null terminator. |
| 3182 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | 3782 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; |
| 3183 | 3783 | ||
| 3184 | if (constraint[0] == '{' and constraint[constraint.len - 1] == '}') { | 3784 | if (constraint.len < 1 or std.mem.indexOfScalar(u8, "=+&%", constraint[0]) != null or |
| 3185 | const reg = constraint[1 .. constraint.len - 1]; | 3785 | (constraint[0] == '{' and constraint[constraint.len - 1] != '}')) |
| 3186 | const arg_c_value = try f.resolveInst(input); | 3786 | { |
| 3187 | try writer.writeAll("register "); | 3787 | return f.fail("CBE: constraint not supported: '{s}'", .{constraint}); |
| 3188 | try f.renderType(writer, f.air.typeOf(input)); | 3788 | } |
| 3189 | 3789 | ||
| 3190 | try writer.print(" {s}_constant __asm__(\"{s}\") = ", .{ reg, reg }); | 3790 | const is_reg = constraint[0] == '{'; |
| 3191 | try f.writeCValue(writer, arg_c_value); | 3791 | const input_val = try f.resolveInst(input); |
| 3192 | try writer.writeAll(";\n"); | 3792 | if (asmInputNeedsLocal(constraint, input_val)) { |
| 3193 | } else { | 3793 | const input_ty = f.air.typeOf(input); |
| 3194 | try writer.writeAll("register "); | 3794 | if (is_reg) try writer.writeAll("register "); |
| 3195 | try f.renderType(writer, f.air.typeOf(input)); | 3795 | _ = try f.allocLocal(input_ty, .Const); |
| 3196 | try writer.print(" input_{d} = ", .{i}); | 3796 | if (is_reg) { |
| 3197 | try f.writeCValue(writer, try f.resolveInst(input)); | 3797 | try writer.writeAll(" __asm(\""); |
| 3798 | try writer.writeAll(constraint["{".len .. constraint.len - "}".len]); | ||
| 3799 | try writer.writeAll("\")"); | ||
| 3800 | } | ||
| 3801 | try writer.writeAll(" = "); | ||
| 3802 | try f.writeCValue(writer, input_val, .Initializer); | ||
| 3198 | try writer.writeAll(";\n"); | 3803 | try writer.writeAll(";\n"); |
| 3199 | } | 3804 | } |
| 3200 | } | 3805 | } |
| 3201 | |||
| 3202 | { | 3806 | { |
| 3203 | var clobber_i: u32 = 0; | 3807 | var clobber_i: u32 = 0; |
| 3204 | while (clobber_i < clobbers_len) : (clobber_i += 1) { | 3808 | while (clobber_i < clobbers_len) : (clobber_i += 1) { |
| ... | @@ -3206,58 +3810,109 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3206,58 +3810,109 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3206 | // This equation accounts for the fact that even if we have exactly 4 bytes | 3810 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 3207 | // for the string, we still use the next u32 for the null terminator. | 3811 | // for the string, we still use the next u32 for the null terminator. |
| 3208 | extra_i += clobber.len / 4 + 1; | 3812 | extra_i += clobber.len / 4 + 1; |
| 3209 | |||
| 3210 | // TODO honor these | ||
| 3211 | } | 3813 | } |
| 3212 | } | 3814 | } |
| 3213 | |||
| 3214 | const asm_source = std.mem.sliceAsBytes(f.air.extra[extra_i..])[0..extra.data.source_len]; | 3815 | const asm_source = std.mem.sliceAsBytes(f.air.extra[extra_i..])[0..extra.data.source_len]; |
| 3215 | 3816 | ||
| 3216 | const volatile_string: []const u8 = if (is_volatile) "volatile " else ""; | 3817 | try writer.writeAll("__asm"); |
| 3217 | try writer.print("__asm {s}(\"{s}\"", .{ volatile_string, asm_source }); | 3818 | if (is_volatile) try writer.writeAll(" volatile"); |
| 3218 | if (output_constraint) |_| { | 3819 | try writer.print("({s}", .{fmtStringLiteral(asm_source)}); |
| 3219 | return f.fail("TODO: CBE inline asm output", .{}); | 3820 | |
| 3220 | } | 3821 | extra_i = constraints_extra_begin; |
| 3221 | if (inputs.len > 0) { | 3822 | var locals_index = locals_begin; |
| 3222 | if (output_constraint == null) { | 3823 | try writer.writeByte(':'); |
| 3223 | try writer.writeAll(" :"); | 3824 | for (outputs) |output, index| { |
| 3825 | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); | ||
| 3826 | const constraint = std.mem.sliceTo(extra_bytes, 0); | ||
| 3827 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | ||
| 3828 | // This equation accounts for the fact that even if we have exactly 4 bytes | ||
| 3829 | // for the string, we still use the next u32 for the null terminator. | ||
| 3830 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | ||
| 3831 | |||
| 3832 | if (index > 0) try writer.writeByte(','); | ||
| 3833 | try writer.writeByte(' '); | ||
| 3834 | if (!std.mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name}); | ||
| 3835 | const is_reg = constraint[1] == '{'; | ||
| 3836 | try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "=r" else constraint)}); | ||
| 3837 | if (is_reg) { | ||
| 3838 | try f.writeCValue(writer, .{ .local = locals_index }, .Other); | ||
| 3839 | locals_index += 1; | ||
| 3840 | } else { | ||
| 3841 | try f.writeCValueDeref(writer, try f.resolveInst(output)); | ||
| 3224 | } | 3842 | } |
| 3225 | try writer.writeAll(": "); | 3843 | try writer.writeByte(')'); |
| 3226 | extra_i = inputs_extra_begin; | 3844 | } |
| 3227 | for (inputs) |_, index| { | 3845 | try writer.writeByte(':'); |
| 3228 | const constraint = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0); | 3846 | for (inputs) |input, index| { |
| 3847 | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); | ||
| 3848 | const constraint = std.mem.sliceTo(extra_bytes, 0); | ||
| 3849 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | ||
| 3850 | // This equation accounts for the fact that even if we have exactly 4 bytes | ||
| 3851 | // for the string, we still use the next u32 for the null terminator. | ||
| 3852 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | ||
| 3853 | |||
| 3854 | if (index > 0) try writer.writeByte(','); | ||
| 3855 | try writer.writeByte(' '); | ||
| 3856 | if (!std.mem.eql(u8, name, "_")) try writer.print("[{s}]", .{name}); | ||
| 3857 | |||
| 3858 | const is_reg = constraint[0] == '{'; | ||
| 3859 | const input_val = try f.resolveInst(input); | ||
| 3860 | try writer.print("{s}(", .{fmtStringLiteral(if (is_reg) "r" else constraint)}); | ||
| 3861 | try f.writeCValue(writer, if (asmInputNeedsLocal(constraint, input_val)) local: { | ||
| 3862 | const input_local = CValue{ .local = locals_index }; | ||
| 3863 | locals_index += 1; | ||
| 3864 | break :local input_local; | ||
| 3865 | } else input_val, .Other); | ||
| 3866 | try writer.writeByte(')'); | ||
| 3867 | } | ||
| 3868 | try writer.writeByte(':'); | ||
| 3869 | { | ||
| 3870 | var clobber_i: u32 = 0; | ||
| 3871 | while (clobber_i < clobbers_len) : (clobber_i += 1) { | ||
| 3872 | const clobber = std.mem.sliceTo(std.mem.sliceAsBytes(f.air.extra[extra_i..]), 0); | ||
| 3229 | // This equation accounts for the fact that even if we have exactly 4 bytes | 3873 | // This equation accounts for the fact that even if we have exactly 4 bytes |
| 3230 | // for the string, we still use the next u32 for the null terminator. | 3874 | // for the string, we still use the next u32 for the null terminator. |
| 3231 | extra_i += constraint.len / 4 + 1; | 3875 | extra_i += clobber.len / 4 + 1; |
| 3232 | 3876 | ||
| 3233 | if (constraint[0] == '{' and constraint[constraint.len - 1] == '}') { | 3877 | if (clobber.len == 0) continue; |
| 3234 | const reg = constraint[1 .. constraint.len - 1]; | 3878 | |
| 3235 | if (index > 0) { | 3879 | if (clobber_i > 0) try writer.writeByte(','); |
| 3236 | try writer.writeAll(", "); | 3880 | try writer.print(" {s}", .{fmtStringLiteral(clobber)}); |
| 3237 | } | ||
| 3238 | try writer.print("\"r\"({s}_constant)", .{reg}); | ||
| 3239 | } else { | ||
| 3240 | if (index > 0) { | ||
| 3241 | try writer.writeAll(", "); | ||
| 3242 | } | ||
| 3243 | try writer.print("\"r\"(input_{d})", .{index}); | ||
| 3244 | } | ||
| 3245 | } | 3881 | } |
| 3246 | } | 3882 | } |
| 3247 | try writer.writeAll(");\n"); | 3883 | try writer.writeAll(");\n"); |
| 3248 | try writer.writeAll("}\n"); | ||
| 3249 | 3884 | ||
| 3250 | if (f.liveness.isUnused(inst)) | 3885 | extra_i = constraints_extra_begin; |
| 3251 | return CValue.none; | 3886 | locals_index = locals_begin; |
| 3887 | for (outputs) |output| { | ||
| 3888 | const extra_bytes = std.mem.sliceAsBytes(f.air.extra[extra_i..]); | ||
| 3889 | const constraint = std.mem.sliceTo(extra_bytes, 0); | ||
| 3890 | const name = std.mem.sliceTo(extra_bytes[constraint.len + 1 ..], 0); | ||
| 3891 | // This equation accounts for the fact that even if we have exactly 4 bytes | ||
| 3892 | // for the string, we still use the next u32 for the null terminator. | ||
| 3893 | extra_i += (constraint.len + name.len + (2 + 3)) / 4; | ||
| 3252 | 3894 | ||
| 3253 | return f.fail("TODO: C backend: inline asm expression result used", .{}); | 3895 | const is_reg = constraint[1] == '{'; |
| 3896 | if (is_reg) { | ||
| 3897 | try f.writeCValueDeref(writer, if (output == .none) | ||
| 3898 | CValue{ .local_ref = local.local } | ||
| 3899 | else | ||
| 3900 | try f.resolveInst(output)); | ||
| 3901 | try writer.writeAll(" = "); | ||
| 3902 | try f.writeCValue(writer, .{ .local = locals_index }, .Other); | ||
| 3903 | locals_index += 1; | ||
| 3904 | try writer.writeAll(";\n"); | ||
| 3905 | } | ||
| 3906 | } | ||
| 3907 | |||
| 3908 | return local; | ||
| 3254 | } | 3909 | } |
| 3255 | 3910 | ||
| 3256 | fn airIsNull( | 3911 | fn airIsNull( |
| 3257 | f: *Function, | 3912 | f: *Function, |
| 3258 | inst: Air.Inst.Index, | 3913 | inst: Air.Inst.Index, |
| 3259 | operator: [*:0]const u8, | 3914 | operator: []const u8, |
| 3260 | deref_suffix: [*:0]const u8, | 3915 | is_ptr: bool, |
| 3261 | ) !CValue { | 3916 | ) !CValue { |
| 3262 | if (f.liveness.isUnused(inst)) | 3917 | if (f.liveness.isUnused(inst)) |
| 3263 | return CValue.none; | 3918 | return CValue.none; |
| ... | @@ -3267,26 +3922,35 @@ fn airIsNull( | ... | @@ -3267,26 +3922,35 @@ fn airIsNull( |
| 3267 | const operand = try f.resolveInst(un_op); | 3922 | const operand = try f.resolveInst(un_op); |
| 3268 | 3923 | ||
| 3269 | const local = try f.allocLocal(Type.initTag(.bool), .Const); | 3924 | const local = try f.allocLocal(Type.initTag(.bool), .Const); |
| 3270 | try writer.writeAll(" = ("); | 3925 | try writer.writeAll(" = "); |
| 3271 | try f.writeCValue(writer, operand); | 3926 | try if (is_ptr) f.writeCValueDeref(writer, operand) else f.writeCValue(writer, operand, .Other); |
| 3272 | |||
| 3273 | const ty = f.air.typeOf(un_op); | ||
| 3274 | const opt_ty = if (deref_suffix[0] != 0) ty.childType() else ty; | ||
| 3275 | var opt_buf: Type.Payload.ElemType = undefined; | ||
| 3276 | const payload_ty = opt_ty.optionalChild(&opt_buf); | ||
| 3277 | 3927 | ||
| 3278 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 3928 | const operand_ty = f.air.typeOf(un_op); |
| 3279 | try writer.print("){s} {s} true;\n", .{ deref_suffix, operator }); | 3929 | const optional_ty = if (is_ptr) operand_ty.childType() else operand_ty; |
| 3280 | } else if (ty.isPtrLikeOptional()) { | 3930 | var payload_buf: Type.Payload.ElemType = undefined; |
| 3931 | const payload_ty = optional_ty.optionalChild(&payload_buf); | ||
| 3932 | var slice_ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; | ||
| 3933 | |||
| 3934 | const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime()) | ||
| 3935 | TypedValue{ .ty = Type.bool, .val = Value.@"true" } | ||
| 3936 | else if (operand_ty.isPtrLikeOptional()) | ||
| 3281 | // operand is a regular pointer, test `operand !=/== NULL` | 3937 | // operand is a regular pointer, test `operand !=/== NULL` |
| 3282 | try writer.print("){s} {s} NULL;\n", .{ deref_suffix, operator }); | 3938 | TypedValue{ .ty = operand_ty, .val = Value.@"null" } |
| 3283 | } else if (payload_ty.zigTypeTag() == .ErrorSet) { | 3939 | else if (payload_ty.zigTypeTag() == .ErrorSet) |
| 3284 | try writer.print("){s} {s} 0;\n", .{ deref_suffix, operator }); | 3940 | TypedValue{ .ty = payload_ty, .val = Value.zero } |
| 3285 | } else if (payload_ty.isSlice() and opt_ty.optionalReprIsPayload()) { | 3941 | else if (payload_ty.isSlice() and optional_ty.optionalReprIsPayload()) rhs: { |
| 3286 | try writer.print("){s}.ptr {s} NULL;\n", .{ deref_suffix, operator }); | 3942 | try writer.writeAll(".ptr"); |
| 3287 | } else { | 3943 | const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf); |
| 3288 | try writer.print("){s}.is_null {s} true;\n", .{ deref_suffix, operator }); | 3944 | break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.@"null" }; |
| 3289 | } | 3945 | } else rhs: { |
| 3946 | try writer.writeAll(".is_null"); | ||
| 3947 | break :rhs TypedValue{ .ty = Type.bool, .val = Value.@"true" }; | ||
| 3948 | }; | ||
| 3949 | try writer.writeByte(' '); | ||
| 3950 | try writer.writeAll(operator); | ||
| 3951 | try writer.writeByte(' '); | ||
| 3952 | try f.object.dg.renderValue(writer, rhs.ty, rhs.val, .Other); | ||
| 3953 | try writer.writeAll(";\n"); | ||
| 3290 | return local; | 3954 | return local; |
| 3291 | } | 3955 | } |
| 3292 | 3956 | ||
| ... | @@ -3312,7 +3976,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3312,7 +3976,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3312 | const inst_ty = f.air.typeOfIndex(inst); | 3976 | const inst_ty = f.air.typeOfIndex(inst); |
| 3313 | const local = try f.allocLocal(inst_ty, .Const); | 3977 | const local = try f.allocLocal(inst_ty, .Const); |
| 3314 | try writer.writeAll(" = ("); | 3978 | try writer.writeAll(" = ("); |
| 3315 | try f.writeCValue(writer, operand); | 3979 | try f.writeCValue(writer, operand, .Other); |
| 3316 | try writer.writeAll(").payload;\n"); | 3980 | try writer.writeAll(").payload;\n"); |
| 3317 | return local; | 3981 | return local; |
| 3318 | } | 3982 | } |
| ... | @@ -3325,11 +3989,10 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3325,11 +3989,10 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3325 | const operand = try f.resolveInst(ty_op.operand); | 3989 | const operand = try f.resolveInst(ty_op.operand); |
| 3326 | const ptr_ty = f.air.typeOf(ty_op.operand); | 3990 | const ptr_ty = f.air.typeOf(ty_op.operand); |
| 3327 | const opt_ty = ptr_ty.childType(); | 3991 | const opt_ty = ptr_ty.childType(); |
| 3328 | var buf: Type.Payload.ElemType = undefined; | 3992 | const inst_ty = f.air.typeOfIndex(inst); |
| 3329 | const payload_ty = opt_ty.optionalChild(&buf); | ||
| 3330 | 3993 | ||
| 3331 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 3994 | if (!inst_ty.childType().hasRuntimeBitsIgnoreComptime()) { |
| 3332 | return operand; | 3995 | return CValue{ .undef = inst_ty }; |
| 3333 | } | 3996 | } |
| 3334 | 3997 | ||
| 3335 | if (opt_ty.optionalReprIsPayload()) { | 3998 | if (opt_ty.optionalReprIsPayload()) { |
| ... | @@ -3338,11 +4001,10 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3338,11 +4001,10 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3338 | return operand; | 4001 | return operand; |
| 3339 | } | 4002 | } |
| 3340 | 4003 | ||
| 3341 | const inst_ty = f.air.typeOfIndex(inst); | ||
| 3342 | const local = try f.allocLocal(inst_ty, .Const); | 4004 | const local = try f.allocLocal(inst_ty, .Const); |
| 3343 | try writer.writeAll(" = &("); | 4005 | try writer.writeAll(" = &"); |
| 3344 | try f.writeCValue(writer, operand); | 4006 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" }); |
| 3345 | try writer.writeAll(")->payload;\n"); | 4007 | try writer.writeAll(";\n"); |
| 3346 | return local; | 4008 | return local; |
| 3347 | } | 4009 | } |
| 3348 | 4010 | ||
| ... | @@ -3361,7 +4023,9 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3361,7 +4023,9 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3361 | } | 4023 | } |
| 3362 | 4024 | ||
| 3363 | try f.writeCValueDeref(writer, operand); | 4025 | try f.writeCValueDeref(writer, operand); |
| 3364 | try writer.writeAll(".is_null = false;\n"); | 4026 | try writer.writeAll(".is_null = "); |
| 4027 | try f.object.dg.renderValue(writer, Type.bool, Value.@"false", .Initializer); | ||
| 4028 | try writer.writeAll(";\n"); | ||
| 3365 | 4029 | ||
| 3366 | const inst_ty = f.air.typeOfIndex(inst); | 4030 | const inst_ty = f.air.typeOfIndex(inst); |
| 3367 | const local = try f.allocLocal(inst_ty, .Const); | 4031 | const local = try f.allocLocal(inst_ty, .Const); |
| ... | @@ -3396,55 +4060,111 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue | ... | @@ -3396,55 +4060,111 @@ fn airStructFieldPtrIndex(f: *Function, inst: Air.Inst.Index, index: u8) !CValue |
| 3396 | } | 4060 | } |
| 3397 | 4061 | ||
| 3398 | fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { | 4062 | fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3399 | _ = inst; | 4063 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 3400 | return f.fail("TODO: C backend: implement airFieldParentPtr", .{}); | 4064 | |
| 4065 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; | ||
| 4066 | const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; | ||
| 4067 | |||
| 4068 | const struct_ptr_ty = f.air.typeOfIndex(inst); | ||
| 4069 | const field_ptr_ty = f.air.typeOf(extra.field_ptr); | ||
| 4070 | const field_ptr_val = try f.resolveInst(extra.field_ptr); | ||
| 4071 | |||
| 4072 | const target = f.object.dg.module.getTarget(); | ||
| 4073 | const struct_ty = struct_ptr_ty.childType(); | ||
| 4074 | const field_offset = struct_ty.structFieldOffset(extra.field_index, target); | ||
| 4075 | |||
| 4076 | var field_offset_pl = Value.Payload.I64{ | ||
| 4077 | .base = .{ .tag = .int_i64 }, | ||
| 4078 | .data = -@intCast(i64, field_offset), | ||
| 4079 | }; | ||
| 4080 | const field_offset_val = Value.initPayload(&field_offset_pl.base); | ||
| 4081 | |||
| 4082 | var u8_ptr_pl = field_ptr_ty.ptrInfo(); | ||
| 4083 | u8_ptr_pl.data.pointee_type = Type.u8; | ||
| 4084 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); | ||
| 4085 | |||
| 4086 | const writer = f.object.writer(); | ||
| 4087 | const local = try f.allocLocal(struct_ptr_ty, .Const); | ||
| 4088 | try writer.writeAll(" = ("); | ||
| 4089 | try f.renderTypecast(writer, struct_ptr_ty); | ||
| 4090 | try writer.writeAll(")&(("); | ||
| 4091 | try f.renderTypecast(writer, u8_ptr_ty); | ||
| 4092 | try writer.writeByte(')'); | ||
| 4093 | try f.writeCValue(writer, field_ptr_val, .Other); | ||
| 4094 | try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.isize, field_offset_val)}); | ||
| 4095 | return local; | ||
| 3401 | } | 4096 | } |
| 3402 | 4097 | ||
| 3403 | fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struct_ptr: CValue, index: u32) !CValue { | 4098 | fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struct_ptr: CValue, index: u32) !CValue { |
| 3404 | const writer = f.object.writer(); | 4099 | const writer = f.object.writer(); |
| 4100 | const field_ptr_ty = f.air.typeOfIndex(inst); | ||
| 4101 | const field_ptr_info = field_ptr_ty.ptrInfo(); | ||
| 3405 | const struct_ty = struct_ptr_ty.elemType(); | 4102 | const struct_ty = struct_ptr_ty.elemType(); |
| 3406 | var field_name: []const u8 = undefined; | 4103 | const field_ty = struct_ty.structFieldType(index); |
| 3407 | var field_val_ty: Type = undefined; | 4104 | |
| 3408 | 4105 | // Ensure complete type definition is visible before accessing fields. | |
| 3409 | var buf = std.ArrayList(u8).init(f.object.dg.gpa); | 4106 | try f.renderType(std.io.null_writer, struct_ty); |
| 3410 | defer buf.deinit(); | 4107 | |
| 3411 | switch (struct_ty.tag()) { | 4108 | const local = try f.allocLocal(field_ptr_ty, .Const); |
| 3412 | .@"struct" => { | 4109 | try writer.writeAll(" = ("); |
| 3413 | const fields = struct_ty.structFields(); | 4110 | try f.renderTypecast(writer, field_ptr_ty); |
| 3414 | field_name = fields.keys()[index]; | 4111 | try writer.writeByte(')'); |
| 3415 | field_val_ty = fields.values()[index].ty; | 4112 | |
| 3416 | }, | 4113 | const extra_name: ?[]const u8 = switch (struct_ty.tag()) { |
| 3417 | .@"union", .union_safety_tagged, .union_tagged => { | 4114 | .union_tagged, .union_safety_tagged => "payload", |
| 3418 | const fields = struct_ty.unionFields(); | 4115 | else => null, |
| 3419 | field_name = fields.keys()[index]; | 4116 | }; |
| 3420 | field_val_ty = fields.values()[index].ty; | 4117 | |
| 4118 | var field_name_buf: []const u8 = &.{}; | ||
| 4119 | defer f.object.dg.gpa.free(field_name_buf); | ||
| 4120 | const field_name: ?[]const u8 = switch (struct_ty.tag()) { | ||
| 4121 | .@"struct" => switch (struct_ty.containerLayout()) { | ||
| 4122 | .Auto, .Extern => struct_ty.structFieldName(index), | ||
| 4123 | .Packed => if (field_ptr_info.data.host_size == 0) { | ||
| 4124 | const target = f.object.dg.module.getTarget(); | ||
| 4125 | |||
| 4126 | const byte_offset = struct_ty.packedStructFieldByteOffset(index, target); | ||
| 4127 | var byte_offset_pl = Value.Payload.U64{ | ||
| 4128 | .base = .{ .tag = .int_u64 }, | ||
| 4129 | .data = byte_offset, | ||
| 4130 | }; | ||
| 4131 | const byte_offset_val = Value.initPayload(&byte_offset_pl.base); | ||
| 4132 | |||
| 4133 | var u8_ptr_pl = field_ptr_info; | ||
| 4134 | u8_ptr_pl.data.pointee_type = Type.u8; | ||
| 4135 | const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); | ||
| 4136 | |||
| 4137 | try writer.writeAll("&(("); | ||
| 4138 | try f.renderTypecast(writer, u8_ptr_ty); | ||
| 4139 | try writer.writeByte(')'); | ||
| 4140 | try f.writeCValue(writer, struct_ptr, .Other); | ||
| 4141 | try writer.print(")[{}];\n", .{try f.fmtIntLiteral(Type.usize, byte_offset_val)}); | ||
| 4142 | return local; | ||
| 4143 | } else null, | ||
| 3421 | }, | 4144 | }, |
| 3422 | .tuple, .anon_struct => { | 4145 | .@"union", .union_safety_tagged, .union_tagged => struct_ty.unionFields().keys()[index], |
| 4146 | .tuple, .anon_struct => |tag| field_name: { | ||
| 3423 | const tuple = struct_ty.tupleFields(); | 4147 | const tuple = struct_ty.tupleFields(); |
| 3424 | if (tuple.values[index].tag() != .unreachable_value) return CValue.none; | 4148 | if (tuple.values[index].tag() != .unreachable_value) return CValue.none; |
| 3425 | 4149 | ||
| 3426 | try buf.writer().print("field_{d}", .{index}); | 4150 | if (tag == .anon_struct) break :field_name struct_ty.structFieldName(index); |
| 3427 | field_name = buf.items; | 4151 | |
| 3428 | field_val_ty = tuple.types[index]; | 4152 | field_name_buf = try std.fmt.allocPrint(f.object.dg.gpa, "field_{d}", .{index}); |
| 4153 | break :field_name field_name_buf; | ||
| 3429 | }, | 4154 | }, |
| 3430 | else => unreachable, | 4155 | else => unreachable, |
| 3431 | } | 4156 | }; |
| 3432 | const payload = if (struct_ty.tag() == .union_tagged or struct_ty.tag() == .union_safety_tagged) "payload." else ""; | ||
| 3433 | |||
| 3434 | const inst_ty = f.air.typeOfIndex(inst); | ||
| 3435 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 3436 | 4157 | ||
| 3437 | if (field_val_ty.hasRuntimeBitsIgnoreComptime()) { | 4158 | if (field_ty.hasRuntimeBitsIgnoreComptime()) { |
| 3438 | try writer.writeAll(" = &"); | 4159 | try writer.writeByte('&'); |
| 3439 | try f.writeCValueDeref(writer, struct_ptr); | 4160 | if (extra_name orelse field_name) |name| |
| 3440 | try writer.print(".{s}{ };\n", .{ payload, fmtIdent(field_name) }); | 4161 | try f.writeCValueDerefMember(writer, struct_ptr, .{ .identifier = name }) |
| 3441 | } else { | 4162 | else |
| 3442 | try writer.writeAll(" = ("); | 4163 | try f.writeCValueDeref(writer, struct_ptr); |
| 3443 | try f.renderTypecast(writer, inst_ty); | 4164 | if (extra_name) |_| if (field_name) |name| |
| 3444 | try writer.writeByte(')'); | 4165 | try writer.print(".{ }", .{fmtIdent(name)}); |
| 3445 | try f.writeCValue(writer, struct_ptr); | 4166 | } else try f.writeCValue(writer, struct_ptr, .Other); |
| 3446 | try writer.writeAll(";\n"); | 4167 | try writer.writeAll(";\n"); |
| 3447 | } | ||
| 3448 | return local; | 4168 | return local; |
| 3449 | } | 4169 | } |
| 3450 | 4170 | ||
| ... | @@ -3454,100 +4174,162 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3454,100 +4174,162 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3454 | 4174 | ||
| 3455 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; | 4175 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| 3456 | const extra = f.air.extraData(Air.StructField, ty_pl.payload).data; | 4176 | const extra = f.air.extraData(Air.StructField, ty_pl.payload).data; |
| 3457 | const writer = f.object.writer(); | 4177 | const inst_ty = f.air.typeOfIndex(inst); |
| 4178 | const target = f.object.dg.module.getTarget(); | ||
| 3458 | const struct_byval = try f.resolveInst(extra.struct_operand); | 4179 | const struct_byval = try f.resolveInst(extra.struct_operand); |
| 3459 | const struct_ty = f.air.typeOf(extra.struct_operand); | 4180 | const struct_ty = f.air.typeOf(extra.struct_operand); |
| 3460 | var buf = std.ArrayList(u8).init(f.object.dg.gpa); | 4181 | const writer = f.object.writer(); |
| 3461 | defer buf.deinit(); | 4182 | |
| 4183 | // Ensure complete type definition is visible before accessing fields. | ||
| 4184 | try f.renderType(std.io.null_writer, struct_ty); | ||
| 4185 | |||
| 4186 | var field_name_buf: []const u8 = ""; | ||
| 4187 | defer f.object.dg.gpa.free(field_name_buf); | ||
| 3462 | const field_name = switch (struct_ty.tag()) { | 4188 | const field_name = switch (struct_ty.tag()) { |
| 3463 | .@"struct" => struct_ty.structFields().keys()[extra.field_index], | 4189 | .@"struct" => switch (struct_ty.containerLayout()) { |
| 4190 | .Auto, .Extern => struct_ty.structFieldName(extra.field_index), | ||
| 4191 | .Packed => { | ||
| 4192 | const struct_obj = struct_ty.castTag(.@"struct").?.data; | ||
| 4193 | const int_info = struct_ty.intInfo(target); | ||
| 4194 | |||
| 4195 | var bit_offset_ty_pl = Type.Payload.Bits{ | ||
| 4196 | .base = .{ .tag = .int_unsigned }, | ||
| 4197 | .data = Type.smallestUnsignedBits(int_info.bits - 1), | ||
| 4198 | }; | ||
| 4199 | const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base); | ||
| 4200 | |||
| 4201 | var bit_offset_val_pl: Value.Payload.U64 = .{ | ||
| 4202 | .base = .{ .tag = .int_u64 }, | ||
| 4203 | .data = struct_obj.packedFieldBitOffset(target, extra.field_index), | ||
| 4204 | }; | ||
| 4205 | const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base); | ||
| 4206 | |||
| 4207 | const field_int_signedness = if (inst_ty.isAbiInt()) | ||
| 4208 | inst_ty.intInfo(target).signedness | ||
| 4209 | else | ||
| 4210 | .unsigned; | ||
| 4211 | var field_int_pl = Type.Payload.Bits{ | ||
| 4212 | .base = .{ .tag = switch (field_int_signedness) { | ||
| 4213 | .unsigned => .int_unsigned, | ||
| 4214 | .signed => .int_signed, | ||
| 4215 | } }, | ||
| 4216 | .data = @intCast(u16, inst_ty.bitSize(target)), | ||
| 4217 | }; | ||
| 4218 | const field_int_ty = Type.initPayload(&field_int_pl.base); | ||
| 4219 | |||
| 4220 | const temp_local = try f.allocLocal(field_int_ty, .Const); | ||
| 4221 | try writer.writeAll(" = zig_wrap_"); | ||
| 4222 | try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty); | ||
| 4223 | try writer.writeAll("(("); | ||
| 4224 | try f.renderTypecast(writer, field_int_ty); | ||
| 4225 | try writer.writeAll(")zig_shr_"); | ||
| 4226 | try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty); | ||
| 4227 | try writer.writeByte('('); | ||
| 4228 | try f.writeCValue(writer, struct_byval, .Other); | ||
| 4229 | try writer.writeAll(", "); | ||
| 4230 | try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument); | ||
| 4231 | try writer.writeByte(')'); | ||
| 4232 | try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .Bits); | ||
| 4233 | try writer.writeAll(");\n"); | ||
| 4234 | if (inst_ty.eql(field_int_ty, f.object.dg.module)) return temp_local; | ||
| 4235 | |||
| 4236 | const local = try f.allocLocal(inst_ty, .Mut); | ||
| 4237 | try writer.writeAll(";\n"); | ||
| 4238 | try writer.writeAll("memcpy("); | ||
| 4239 | try f.writeCValue(writer, .{ .local_ref = local.local }, .FunctionArgument); | ||
| 4240 | try writer.writeAll(", "); | ||
| 4241 | try f.writeCValue(writer, .{ .local_ref = temp_local.local }, .FunctionArgument); | ||
| 4242 | try writer.writeAll(", sizeof("); | ||
| 4243 | try f.renderTypecast(writer, inst_ty); | ||
| 4244 | try writer.writeAll("));\n"); | ||
| 4245 | return local; | ||
| 4246 | }, | ||
| 4247 | }, | ||
| 3464 | .@"union", .union_safety_tagged, .union_tagged => struct_ty.unionFields().keys()[extra.field_index], | 4248 | .@"union", .union_safety_tagged, .union_tagged => struct_ty.unionFields().keys()[extra.field_index], |
| 3465 | .tuple, .anon_struct => blk: { | 4249 | .tuple, .anon_struct => |tag| blk: { |
| 3466 | const tuple = struct_ty.tupleFields(); | 4250 | const tuple = struct_ty.tupleFields(); |
| 3467 | if (tuple.values[extra.field_index].tag() != .unreachable_value) return CValue.none; | 4251 | if (tuple.values[extra.field_index].tag() != .unreachable_value) return CValue.none; |
| 3468 | 4252 | ||
| 3469 | try buf.writer().print("field_{d}", .{extra.field_index}); | 4253 | if (tag == .anon_struct) break :blk struct_ty.structFieldName(extra.field_index); |
| 3470 | break :blk buf.items; | 4254 | |
| 4255 | field_name_buf = try std.fmt.allocPrint(f.object.dg.gpa, "field_{d}", .{extra.field_index}); | ||
| 4256 | break :blk field_name_buf; | ||
| 3471 | }, | 4257 | }, |
| 3472 | else => unreachable, | 4258 | else => unreachable, |
| 3473 | }; | 4259 | }; |
| 3474 | const payload = if (struct_ty.tag() == .union_tagged or struct_ty.tag() == .union_safety_tagged) "payload." else ""; | 4260 | const payload = if (struct_ty.tag() == .union_tagged or struct_ty.tag() == .union_safety_tagged) "payload." else ""; |
| 3475 | 4261 | ||
| 3476 | const inst_ty = f.air.typeOfIndex(inst); | 4262 | const is_array = lowersToArray(inst_ty, target); |
| 3477 | const local = try f.allocLocal(inst_ty, .Const); | 4263 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); |
| 3478 | try writer.writeAll(" = "); | 4264 | if (is_array) { |
| 3479 | try f.writeCValue(writer, struct_byval); | 4265 | try writer.writeAll(";\n"); |
| 3480 | try writer.print(".{s}{ };\n", .{ payload, fmtIdent(field_name) }); | 4266 | try writer.writeAll("memcpy("); |
| 4267 | try f.writeCValue(writer, local, .FunctionArgument); | ||
| 4268 | try writer.writeAll(", "); | ||
| 4269 | try f.writeCValue(writer, struct_byval, .Other); | ||
| 4270 | try writer.print(".{s}{ }, sizeof(", .{ payload, fmtIdent(field_name) }); | ||
| 4271 | try f.renderTypecast(writer, inst_ty); | ||
| 4272 | try writer.writeAll("));\n"); | ||
| 4273 | } else { | ||
| 4274 | try writer.writeAll(" = "); | ||
| 4275 | try f.writeCValue(writer, struct_byval, .Other); | ||
| 4276 | try writer.print(".{s}{ };\n", .{ payload, fmtIdent(field_name) }); | ||
| 4277 | } | ||
| 3481 | return local; | 4278 | return local; |
| 3482 | } | 4279 | } |
| 3483 | 4280 | ||
| 3484 | /// *(E!T) -> E | 4281 | /// *(E!T) -> E |
| 3485 | /// Note that the result is never a pointer. | 4282 | /// Note that the result is never a pointer. |
| 3486 | fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | 4283 | fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3487 | if (f.liveness.isUnused(inst)) | 4284 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 3488 | return CValue.none; | ||
| 3489 | 4285 | ||
| 3490 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; | 4286 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 3491 | const inst_ty = f.air.typeOfIndex(inst); | 4287 | const inst_ty = f.air.typeOfIndex(inst); |
| 3492 | const writer = f.object.writer(); | ||
| 3493 | const operand = try f.resolveInst(ty_op.operand); | 4288 | const operand = try f.resolveInst(ty_op.operand); |
| 3494 | const operand_ty = f.air.typeOf(ty_op.operand); | 4289 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 3495 | 4290 | ||
| 3496 | if (operand_ty.zigTypeTag() == .Pointer) { | 4291 | const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer; |
| 3497 | const err_union_ty = operand_ty.childType(); | 4292 | const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; |
| 3498 | if (err_union_ty.errorUnionSet().errorSetIsEmpty()) { | 4293 | const error_ty = error_union_ty.errorUnionSet(); |
| 3499 | return CValue{ .bytes = "0" }; | 4294 | const payload_ty = error_union_ty.errorUnionPayload(); |
| 3500 | } | 4295 | if (!payload_ty.hasRuntimeBits()) return operand; |
| 3501 | if (!err_union_ty.errorUnionPayload().hasRuntimeBits()) { | ||
| 3502 | return operand; | ||
| 3503 | } | ||
| 3504 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 3505 | try writer.writeAll(" = *"); | ||
| 3506 | try f.writeCValue(writer, operand); | ||
| 3507 | try writer.writeAll(";\n"); | ||
| 3508 | return local; | ||
| 3509 | } | ||
| 3510 | if (operand_ty.errorUnionSet().errorSetIsEmpty()) { | ||
| 3511 | return CValue{ .bytes = "0" }; | ||
| 3512 | } | ||
| 3513 | if (!operand_ty.errorUnionPayload().hasRuntimeBits()) { | ||
| 3514 | return operand; | ||
| 3515 | } | ||
| 3516 | 4296 | ||
| 4297 | const writer = f.object.writer(); | ||
| 3517 | const local = try f.allocLocal(inst_ty, .Const); | 4298 | const local = try f.allocLocal(inst_ty, .Const); |
| 3518 | try writer.writeAll(" = "); | 4299 | try writer.writeAll(" = "); |
| 3519 | if (operand_ty.zigTypeTag() == .Pointer) { | 4300 | if (!error_ty.errorSetIsEmpty()) |
| 3520 | try f.writeCValueDeref(writer, operand); | 4301 | if (operand_is_ptr) |
| 3521 | } else { | 4302 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }) |
| 3522 | try f.writeCValue(writer, operand); | 4303 | else |
| 3523 | } | 4304 | try f.writeCValueMember(writer, operand, .{ .identifier = "error" }) |
| 3524 | try writer.writeAll(".error;\n"); | 4305 | else |
| 4306 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer); | ||
| 4307 | try writer.writeAll(";\n"); | ||
| 3525 | return local; | 4308 | return local; |
| 3526 | } | 4309 | } |
| 3527 | 4310 | ||
| 3528 | fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, maybe_addrof: [*:0]const u8) !CValue { | 4311 | fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { |
| 3529 | if (f.liveness.isUnused(inst)) | 4312 | if (f.liveness.isUnused(inst)) |
| 3530 | return CValue.none; | 4313 | return CValue.none; |
| 3531 | 4314 | ||
| 3532 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; | 4315 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 3533 | const writer = f.object.writer(); | 4316 | const inst_ty = f.air.typeOfIndex(inst); |
| 3534 | const operand = try f.resolveInst(ty_op.operand); | 4317 | const operand = try f.resolveInst(ty_op.operand); |
| 3535 | const operand_ty = f.air.typeOf(ty_op.operand); | 4318 | const operand_ty = f.air.typeOf(ty_op.operand); |
| 3536 | const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer; | 4319 | const operand_is_ptr = operand_ty.zigTypeTag() == .Pointer; |
| 3537 | const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; | 4320 | const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; |
| 3538 | 4321 | ||
| 3539 | if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) { | 4322 | if (!error_union_ty.errorUnionPayload().hasRuntimeBits()) return CValue.none; |
| 3540 | return CValue.none; | ||
| 3541 | } | ||
| 3542 | |||
| 3543 | const inst_ty = f.air.typeOfIndex(inst); | ||
| 3544 | const maybe_deref = if (operand_is_ptr) "->" else "."; | ||
| 3545 | 4323 | ||
| 4324 | const writer = f.object.writer(); | ||
| 3546 | const local = try f.allocLocal(inst_ty, .Const); | 4325 | const local = try f.allocLocal(inst_ty, .Const); |
| 3547 | try writer.print(" = {s}(", .{maybe_addrof}); | 4326 | try writer.writeAll(" = "); |
| 3548 | try f.writeCValue(writer, operand); | 4327 | if (is_ptr) try writer.writeByte('&'); |
| 3549 | 4328 | if (operand_is_ptr) | |
| 3550 | try writer.print("){s}payload;\n", .{maybe_deref}); | 4329 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "payload" }) |
| 4330 | else | ||
| 4331 | try f.writeCValueMember(writer, operand, .{ .identifier = "payload" }); | ||
| 4332 | try writer.writeAll(";\n"); | ||
| 3551 | return local; | 4333 | return local; |
| 3552 | } | 4334 | } |
| 3553 | 4335 | ||
| ... | @@ -3566,9 +4348,11 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3566,9 +4348,11 @@ fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3566 | 4348 | ||
| 3567 | // .wrap_optional is used to convert non-optionals into optionals so it can never be null. | 4349 | // .wrap_optional is used to convert non-optionals into optionals so it can never be null. |
| 3568 | const local = try f.allocLocal(inst_ty, .Const); | 4350 | const local = try f.allocLocal(inst_ty, .Const); |
| 3569 | try writer.writeAll(" = { .is_null = false, .payload ="); | 4351 | try writer.writeAll(" = { .payload = "); |
| 3570 | try f.writeCValue(writer, operand); | 4352 | try f.writeCValue(writer, operand, .Initializer); |
| 3571 | try writer.writeAll("};\n"); | 4353 | try writer.writeAll(", .is_null = "); |
| 4354 | try f.object.dg.renderValue(writer, Type.bool, Value.@"false", .Initializer); | ||
| 4355 | try writer.writeAll(" };\n"); | ||
| 3572 | return local; | 4356 | return local; |
| 3573 | } | 4357 | } |
| 3574 | 4358 | ||
| ... | @@ -3578,15 +4362,15 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3578,15 +4362,15 @@ fn airWrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3578 | const writer = f.object.writer(); | 4362 | const writer = f.object.writer(); |
| 3579 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; | 4363 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 3580 | const operand = try f.resolveInst(ty_op.operand); | 4364 | const operand = try f.resolveInst(ty_op.operand); |
| 3581 | const err_un_ty = f.air.typeOfIndex(inst); | 4365 | const error_union_ty = f.air.typeOfIndex(inst); |
| 3582 | const payload_ty = err_un_ty.errorUnionPayload(); | 4366 | const payload_ty = error_union_ty.errorUnionPayload(); |
| 3583 | if (!payload_ty.hasRuntimeBits()) { | 4367 | if (!payload_ty.hasRuntimeBits()) return operand; |
| 3584 | return operand; | ||
| 3585 | } | ||
| 3586 | 4368 | ||
| 3587 | const local = try f.allocLocal(err_un_ty, .Const); | 4369 | const local = try f.allocLocal(error_union_ty, .Const); |
| 3588 | try writer.writeAll(" = { .error = "); | 4370 | try writer.writeAll(" = { .payload = "); |
| 3589 | try f.writeCValue(writer, operand); | 4371 | try f.writeCValue(writer, .{ .undef = payload_ty }, .Initializer); |
| 4372 | try writer.writeAll(", .error = "); | ||
| 4373 | try f.writeCValue(writer, operand, .Initializer); | ||
| 3590 | try writer.writeAll(" };\n"); | 4374 | try writer.writeAll(" };\n"); |
| 3591 | return local; | 4375 | return local; |
| 3592 | } | 4376 | } |
| ... | @@ -3648,19 +4432,31 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3648,19 +4432,31 @@ fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3648 | const operand = try f.resolveInst(ty_op.operand); | 4432 | const operand = try f.resolveInst(ty_op.operand); |
| 3649 | 4433 | ||
| 3650 | const inst_ty = f.air.typeOfIndex(inst); | 4434 | const inst_ty = f.air.typeOfIndex(inst); |
| 3651 | const local = try f.allocLocal(inst_ty, .Const); | 4435 | const payload_ty = inst_ty.errorUnionPayload(); |
| 3652 | try writer.writeAll(" = { .error = 0, .payload = "); | 4436 | const error_ty = inst_ty.errorUnionSet(); |
| 3653 | try f.writeCValue(writer, operand); | 4437 | const target = f.object.dg.module.getTarget(); |
| 4438 | const is_array = lowersToArray(payload_ty, target); | ||
| 4439 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); | ||
| 4440 | try writer.writeAll(" = { .payload = "); | ||
| 4441 | try f.writeCValue(writer, if (is_array) CValue{ .undef = payload_ty } else operand, .Initializer); | ||
| 4442 | try writer.writeAll(", .error = "); | ||
| 4443 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer); | ||
| 3654 | try writer.writeAll(" };\n"); | 4444 | try writer.writeAll(" };\n"); |
| 4445 | |||
| 4446 | if (is_array) { | ||
| 4447 | try writer.writeAll("memcpy("); | ||
| 4448 | try f.writeCValue(writer, local, .Other); | ||
| 4449 | try writer.writeAll(".payload, "); | ||
| 4450 | try f.writeCValue(writer, operand, .FunctionArgument); | ||
| 4451 | try writer.writeAll(", sizeof("); | ||
| 4452 | try f.renderTypecast(writer, payload_ty); | ||
| 4453 | try writer.writeAll("));\n"); | ||
| 4454 | } | ||
| 4455 | |||
| 3655 | return local; | 4456 | return local; |
| 3656 | } | 4457 | } |
| 3657 | 4458 | ||
| 3658 | fn airIsErr( | 4459 | fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const u8) !CValue { |
| 3659 | f: *Function, | ||
| 3660 | inst: Air.Inst.Index, | ||
| 3661 | is_ptr: bool, | ||
| 3662 | op_str: [*:0]const u8, | ||
| 3663 | ) !CValue { | ||
| 3664 | if (f.liveness.isUnused(inst)) | 4460 | if (f.liveness.isUnused(inst)) |
| 3665 | return CValue.none; | 4461 | return CValue.none; |
| 3666 | 4462 | ||
| ... | @@ -3675,19 +4471,21 @@ fn airIsErr( | ... | @@ -3675,19 +4471,21 @@ fn airIsErr( |
| 3675 | 4471 | ||
| 3676 | try writer.writeAll(" = "); | 4472 | try writer.writeAll(" = "); |
| 3677 | 4473 | ||
| 3678 | if (error_ty.errorSetIsEmpty()) { | 4474 | if (!error_ty.errorSetIsEmpty()) |
| 3679 | try writer.print("0 {s} 0;\n", .{op_str}); | 4475 | if (payload_ty.hasRuntimeBits()) |
| 3680 | } else { | 4476 | if (is_ptr) |
| 3681 | if (is_ptr) { | 4477 | try f.writeCValueDerefMember(writer, operand, .{ .identifier = "error" }) |
| 3682 | try f.writeCValueDeref(writer, operand); | 4478 | else |
| 3683 | } else { | 4479 | try f.writeCValueMember(writer, operand, .{ .identifier = "error" }) |
| 3684 | try f.writeCValue(writer, operand); | 4480 | else |
| 3685 | } | 4481 | try f.writeCValue(writer, operand, .Other) |
| 3686 | if (payload_ty.hasRuntimeBits()) { | 4482 | else |
| 3687 | try writer.writeAll(".error"); | 4483 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other); |
| 3688 | } | 4484 | try writer.writeByte(' '); |
| 3689 | try writer.print(" {s} 0;\n", .{op_str}); | 4485 | try writer.writeAll(operator); |
| 3690 | } | 4486 | try writer.writeByte(' '); |
| 4487 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Other); | ||
| 4488 | try writer.writeAll(";\n"); | ||
| 3691 | return local; | 4489 | return local; |
| 3692 | } | 4490 | } |
| 3693 | 4491 | ||
| ... | @@ -3703,16 +4501,20 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3703,16 +4501,20 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3703 | const array_len = f.air.typeOf(ty_op.operand).elemType().arrayLen(); | 4501 | const array_len = f.air.typeOf(ty_op.operand).elemType().arrayLen(); |
| 3704 | 4502 | ||
| 3705 | try writer.writeAll(" = { .ptr = "); | 4503 | try writer.writeAll(" = { .ptr = "); |
| 3706 | if (operand == .undefined_ptr) { | 4504 | if (operand == .undef) { |
| 3707 | // Unfortunately, C does not support any equivalent to | 4505 | // Unfortunately, C does not support any equivalent to |
| 3708 | // &(*(void *)p)[0], although LLVM does via GetElementPtr | 4506 | // &(*(void *)p)[0], although LLVM does via GetElementPtr |
| 3709 | try f.writeCValue(writer, CValue.undefined_ptr); | 4507 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 4508 | try f.writeCValue(writer, CValue{ .undef = inst_ty.slicePtrFieldType(&buf) }, .Initializer); | ||
| 3710 | } else { | 4509 | } else { |
| 3711 | try writer.writeAll("&("); | 4510 | try writer.writeAll("&("); |
| 3712 | try f.writeCValueDeref(writer, operand); | 4511 | try f.writeCValueDeref(writer, operand); |
| 3713 | try writer.writeAll(")[0]"); | 4512 | try writer.print(")[{}]", .{try f.fmtIntLiteral(Type.usize, Value.zero)}); |
| 3714 | } | 4513 | } |
| 3715 | try writer.print(", .len = {d} }};\n", .{array_len}); | 4514 | |
| 4515 | var len_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = array_len }; | ||
| 4516 | const len_val = Value.initPayload(&len_pl.base); | ||
| 4517 | try writer.print(", .len = {} }};\n", .{try f.fmtIntLiteral(Type.usize, len_val)}); | ||
| 3716 | return local; | 4518 | return local; |
| 3717 | } | 4519 | } |
| 3718 | 4520 | ||
| ... | @@ -3728,7 +4530,7 @@ fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3728,7 +4530,7 @@ fn airSimpleCast(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3728 | const operand = try f.resolveInst(ty_op.operand); | 4530 | const operand = try f.resolveInst(ty_op.operand); |
| 3729 | 4531 | ||
| 3730 | try writer.writeAll(" = "); | 4532 | try writer.writeAll(" = "); |
| 3731 | try f.writeCValue(writer, operand); | 4533 | try f.writeCValue(writer, operand, .Other); |
| 3732 | try writer.writeAll(";\n"); | 4534 | try writer.writeAll(";\n"); |
| 3733 | return local; | 4535 | return local; |
| 3734 | } | 4536 | } |
| ... | @@ -3744,61 +4546,80 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3744,61 +4546,80 @@ fn airPtrToInt(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3744 | 4546 | ||
| 3745 | try writer.writeAll(" = ("); | 4547 | try writer.writeAll(" = ("); |
| 3746 | try f.renderTypecast(writer, inst_ty); | 4548 | try f.renderTypecast(writer, inst_ty); |
| 3747 | try writer.writeAll(")"); | 4549 | try writer.writeByte(')'); |
| 3748 | try f.writeCValue(writer, operand); | 4550 | try f.writeCValue(writer, operand, .Other); |
| 3749 | try writer.writeAll(";\n"); | 4551 | try writer.writeAll(";\n"); |
| 3750 | return local; | 4552 | return local; |
| 3751 | } | 4553 | } |
| 3752 | 4554 | ||
| 3753 | fn airBuiltinCall(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u8) !CValue { | 4555 | fn airUnBuiltinCall( |
| 4556 | f: *Function, | ||
| 4557 | inst: Air.Inst.Index, | ||
| 4558 | operation: []const u8, | ||
| 4559 | info: BuiltinInfo, | ||
| 4560 | ) !CValue { | ||
| 3754 | if (f.liveness.isUnused(inst)) return CValue.none; | 4561 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 3755 | 4562 | ||
| 3756 | const inst_ty = f.air.typeOfIndex(inst); | 4563 | const inst_ty = f.air.typeOfIndex(inst); |
| 3757 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 3758 | const operand = f.air.instructions.items(.data)[inst].ty_op.operand; | 4564 | const operand = f.air.instructions.items(.data)[inst].ty_op.operand; |
| 3759 | const operand_ty = f.air.typeOf(operand); | 4565 | const operand_ty = f.air.typeOf(operand); |
| 3760 | const target = f.object.dg.module.getTarget(); | ||
| 3761 | const writer = f.object.writer(); | ||
| 3762 | |||
| 3763 | const int_info = operand_ty.intInfo(target); | ||
| 3764 | const c_bits = toCIntBits(int_info.bits) orelse | ||
| 3765 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); | ||
| 3766 | 4566 | ||
| 3767 | try writer.print(" = zig_{s}_", .{fn_name}); | 4567 | const local = try f.allocLocal(inst_ty, .Const); |
| 3768 | try writer.print("{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits }); | 4568 | const writer = f.object.writer(); |
| 3769 | try f.writeCValue(writer, try f.resolveInst(operand)); | 4569 | try writer.writeAll(" = zig_"); |
| 3770 | try writer.print(", {d});\n", .{int_info.bits}); | 4570 | try writer.writeAll(operation); |
| 4571 | try writer.writeByte('_'); | ||
| 4572 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | ||
| 4573 | try writer.writeByte('('); | ||
| 4574 | try f.writeCValue(writer, try f.resolveInst(operand), .FunctionArgument); | ||
| 4575 | try f.object.dg.renderBuiltinInfo(writer, operand_ty, info); | ||
| 4576 | try writer.writeAll(");\n"); | ||
| 3771 | return local; | 4577 | return local; |
| 3772 | } | 4578 | } |
| 3773 | 4579 | ||
| 3774 | fn airBinOpBuiltinCall(f: *Function, inst: Air.Inst.Index, fn_name: [*:0]const u8) !CValue { | 4580 | fn airBinBuiltinCall( |
| 4581 | f: *Function, | ||
| 4582 | inst: Air.Inst.Index, | ||
| 4583 | operation: []const u8, | ||
| 4584 | info: BuiltinInfo, | ||
| 4585 | ) !CValue { | ||
| 3775 | if (f.liveness.isUnused(inst)) return CValue.none; | 4586 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 3776 | 4587 | ||
| 3777 | const inst_ty = f.air.typeOfIndex(inst); | 4588 | const inst_ty = f.air.typeOfIndex(inst); |
| 3778 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 3779 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | 4589 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 3780 | const lhs_ty = f.air.typeOf(bin_op.lhs); | 4590 | const operand_ty = f.air.typeOf(bin_op.lhs); |
| 3781 | const target = f.object.dg.module.getTarget(); | 4591 | |
| 4592 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 3782 | const writer = f.object.writer(); | 4593 | const writer = f.object.writer(); |
| 4594 | try writer.writeAll(" = zig_"); | ||
| 4595 | try writer.writeAll(operation); | ||
| 4596 | try writer.writeByte('_'); | ||
| 4597 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | ||
| 4598 | try writer.writeByte('('); | ||
| 4599 | try f.writeCValue(writer, try f.resolveInst(bin_op.lhs), .FunctionArgument); | ||
| 4600 | try writer.writeAll(", "); | ||
| 4601 | try f.writeCValue(writer, try f.resolveInst(bin_op.rhs), .FunctionArgument); | ||
| 4602 | try f.object.dg.renderBuiltinInfo(writer, operand_ty, info); | ||
| 4603 | try writer.writeAll(");\n"); | ||
| 4604 | return local; | ||
| 4605 | } | ||
| 3783 | 4606 | ||
| 3784 | // For binary operations @TypeOf(lhs)==@TypeOf(rhs), so we only check one. | 4607 | fn airCmpBuiltinCall(f: *Function, inst: Air.Inst.Index, operator: []const u8) !CValue { |
| 3785 | if (lhs_ty.isInt()) { | 4608 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 3786 | const int_info = lhs_ty.intInfo(target); | ||
| 3787 | const c_bits = toCIntBits(int_info.bits) orelse | ||
| 3788 | return f.fail("TODO: C backend: implement integer types larger than 128 bits", .{}); | ||
| 3789 | try writer.print(" = zig_{s}_{c}{d}", .{ fn_name, signAbbrev(int_info.signedness), c_bits }); | ||
| 3790 | } else if (lhs_ty.isRuntimeFloat()) { | ||
| 3791 | const c_bits = lhs_ty.floatBits(target); | ||
| 3792 | try writer.print(" = zig_{s}_f{d}", .{ fn_name, c_bits }); | ||
| 3793 | } else { | ||
| 3794 | return f.fail("TODO: C backend: implement airBinOpBuiltinCall for type {s}", .{@tagName(lhs_ty.tag())}); | ||
| 3795 | } | ||
| 3796 | 4609 | ||
| 4610 | const inst_ty = f.air.typeOfIndex(inst); | ||
| 4611 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | ||
| 4612 | const operand_ty = f.air.typeOf(bin_op.lhs); | ||
| 4613 | |||
| 4614 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 4615 | const writer = f.object.writer(); | ||
| 4616 | try writer.writeAll(" = zig_cmp_"); | ||
| 4617 | try f.object.dg.renderTypeForBuiltinFnName(writer, operand_ty); | ||
| 3797 | try writer.writeByte('('); | 4618 | try writer.writeByte('('); |
| 3798 | try f.writeCValue(writer, try f.resolveInst(bin_op.lhs)); | 4619 | try f.writeCValue(writer, try f.resolveInst(bin_op.lhs), .FunctionArgument); |
| 3799 | try writer.writeAll(", "); | 4620 | try writer.writeAll(", "); |
| 3800 | try f.writeCValue(writer, try f.resolveInst(bin_op.rhs)); | 4621 | try f.writeCValue(writer, try f.resolveInst(bin_op.rhs), .FunctionArgument); |
| 3801 | try writer.writeAll(");\n"); | 4622 | try writer.print(") {s} {};\n", .{ operator, try f.fmtIntLiteral(Type.initTag(.i8), Value.zero) }); |
| 3802 | return local; | 4623 | return local; |
| 3803 | } | 4624 | } |
| 3804 | 4625 | ||
| ... | @@ -3806,23 +4627,58 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue | ... | @@ -3806,23 +4627,58 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue |
| 3806 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; | 4627 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| 3807 | const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data; | 4628 | const extra = f.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 3808 | const inst_ty = f.air.typeOfIndex(inst); | 4629 | const inst_ty = f.air.typeOfIndex(inst); |
| 4630 | const is_struct = !inst_ty.isPtrLikeOptional(); | ||
| 4631 | const ptr_ty = f.air.typeOf(extra.ptr); | ||
| 3809 | const ptr = try f.resolveInst(extra.ptr); | 4632 | const ptr = try f.resolveInst(extra.ptr); |
| 3810 | const expected_value = try f.resolveInst(extra.expected_value); | 4633 | const expected_value = try f.resolveInst(extra.expected_value); |
| 3811 | const new_value = try f.resolveInst(extra.new_value); | 4634 | const new_value = try f.resolveInst(extra.new_value); |
| 3812 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 3813 | const writer = f.object.writer(); | 4635 | const writer = f.object.writer(); |
| 3814 | 4636 | ||
| 3815 | try writer.print(" = zig_cmpxchg_{s}(", .{flavor}); | 4637 | const local = try f.allocLocal(inst_ty, .Mut); |
| 3816 | try f.writeCValue(writer, ptr); | 4638 | try writer.writeAll(" = "); |
| 4639 | if (is_struct) try writer.writeAll("{ .payload = "); | ||
| 4640 | try f.writeCValue(writer, expected_value, .Initializer); | ||
| 4641 | if (is_struct) { | ||
| 4642 | try writer.writeAll(", .is_null = "); | ||
| 4643 | try f.object.dg.renderValue(writer, Type.bool, Value.@"false", .Initializer); | ||
| 4644 | try writer.writeAll(" }"); | ||
| 4645 | } | ||
| 4646 | try writer.writeAll(";\n"); | ||
| 4647 | |||
| 4648 | if (is_struct) { | ||
| 4649 | try f.writeCValue(writer, local, .Other); | ||
| 4650 | try writer.writeAll(".is_null = "); | ||
| 4651 | } else { | ||
| 4652 | try writer.writeAll("if ("); | ||
| 4653 | } | ||
| 4654 | try writer.print("zig_cmpxchg_{s}((zig_atomic(", .{flavor}); | ||
| 4655 | try f.renderTypecast(writer, ptr_ty.elemType()); | ||
| 4656 | try writer.writeByte(')'); | ||
| 4657 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | ||
| 4658 | try writer.writeAll(" *)"); | ||
| 4659 | try f.writeCValue(writer, ptr, .Other); | ||
| 3817 | try writer.writeAll(", "); | 4660 | try writer.writeAll(", "); |
| 3818 | try f.writeCValue(writer, expected_value); | 4661 | if (is_struct) |
| 4662 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }) | ||
| 4663 | else | ||
| 4664 | try f.writeCValue(writer, local, .FunctionArgument); | ||
| 3819 | try writer.writeAll(", "); | 4665 | try writer.writeAll(", "); |
| 3820 | try f.writeCValue(writer, new_value); | 4666 | try f.writeCValue(writer, new_value, .FunctionArgument); |
| 3821 | try writer.writeAll(", "); | 4667 | try writer.writeAll(", "); |
| 3822 | try writeMemoryOrder(writer, extra.successOrder()); | 4668 | try writeMemoryOrder(writer, extra.successOrder()); |
| 3823 | try writer.writeAll(", "); | 4669 | try writer.writeAll(", "); |
| 3824 | try writeMemoryOrder(writer, extra.failureOrder()); | 4670 | try writeMemoryOrder(writer, extra.failureOrder()); |
| 3825 | try writer.writeAll(");\n"); | 4671 | try writer.writeByte(')'); |
| 4672 | if (is_struct) { | ||
| 4673 | try writer.writeAll(";\n"); | ||
| 4674 | } else { | ||
| 4675 | try writer.writeAll(") {\n"); | ||
| 4676 | f.object.indent_writer.pushIndent(); | ||
| 4677 | try f.writeCValue(writer, local, .Other); | ||
| 4678 | try writer.writeAll(" = NULL;\n"); | ||
| 4679 | f.object.indent_writer.popIndent(); | ||
| 4680 | try writer.writeAll("}\n"); | ||
| 4681 | } | ||
| 3826 | 4682 | ||
| 3827 | return local; | 4683 | return local; |
| 3828 | } | 4684 | } |
| ... | @@ -3831,15 +4687,29 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3831,15 +4687,29 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3831 | const pl_op = f.air.instructions.items(.data)[inst].pl_op; | 4687 | const pl_op = f.air.instructions.items(.data)[inst].pl_op; |
| 3832 | const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data; | 4688 | const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data; |
| 3833 | const inst_ty = f.air.typeOfIndex(inst); | 4689 | const inst_ty = f.air.typeOfIndex(inst); |
| 4690 | const ptr_ty = f.air.typeOf(pl_op.operand); | ||
| 3834 | const ptr = try f.resolveInst(pl_op.operand); | 4691 | const ptr = try f.resolveInst(pl_op.operand); |
| 3835 | const operand = try f.resolveInst(extra.operand); | 4692 | const operand = try f.resolveInst(extra.operand); |
| 3836 | const local = try f.allocLocal(inst_ty, .Const); | 4693 | const local = try f.allocLocal(inst_ty, .Const); |
| 3837 | const writer = f.object.writer(); | 4694 | const writer = f.object.writer(); |
| 3838 | 4695 | ||
| 3839 | try writer.print(" = zig_atomicrmw_{s}(", .{toAtomicRmwSuffix(extra.op())}); | 4696 | try writer.print(" = zig_atomicrmw_{s}((", .{toAtomicRmwSuffix(extra.op())}); |
| 3840 | try f.writeCValue(writer, ptr); | 4697 | switch (extra.op()) { |
| 4698 | else => { | ||
| 4699 | try writer.writeAll("zig_atomic("); | ||
| 4700 | try f.renderTypecast(writer, ptr_ty.elemType()); | ||
| 4701 | try writer.writeByte(')'); | ||
| 4702 | }, | ||
| 4703 | .Nand, .Min, .Max => { | ||
| 4704 | // These are missing from stdatomic.h, so no atomic types for now. | ||
| 4705 | try f.renderTypecast(writer, ptr_ty.elemType()); | ||
| 4706 | }, | ||
| 4707 | } | ||
| 4708 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | ||
| 4709 | try writer.writeAll(" *)"); | ||
| 4710 | try f.writeCValue(writer, ptr, .Other); | ||
| 3841 | try writer.writeAll(", "); | 4711 | try writer.writeAll(", "); |
| 3842 | try f.writeCValue(writer, operand); | 4712 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 3843 | try writer.writeAll(", "); | 4713 | try writer.writeAll(", "); |
| 3844 | try writeMemoryOrder(writer, extra.ordering()); | 4714 | try writeMemoryOrder(writer, extra.ordering()); |
| 3845 | try writer.writeAll(");\n"); | 4715 | try writer.writeAll(");\n"); |
| ... | @@ -3858,8 +4728,12 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3858,8 +4728,12 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3858 | const local = try f.allocLocal(inst_ty, .Const); | 4728 | const local = try f.allocLocal(inst_ty, .Const); |
| 3859 | const writer = f.object.writer(); | 4729 | const writer = f.object.writer(); |
| 3860 | 4730 | ||
| 3861 | try writer.writeAll(" = zig_atomic_load("); | 4731 | try writer.writeAll(" = zig_atomic_load((zig_atomic("); |
| 3862 | try f.writeCValue(writer, ptr); | 4732 | try f.renderTypecast(writer, ptr_ty.elemType()); |
| 4733 | try writer.writeByte(')'); | ||
| 4734 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | ||
| 4735 | try writer.writeAll(" *)"); | ||
| 4736 | try f.writeCValue(writer, ptr, .Other); | ||
| 3863 | try writer.writeAll(", "); | 4737 | try writer.writeAll(", "); |
| 3864 | try writeMemoryOrder(writer, atomic_load.order); | 4738 | try writeMemoryOrder(writer, atomic_load.order); |
| 3865 | try writer.writeAll(");\n"); | 4739 | try writer.writeAll(");\n"); |
| ... | @@ -3869,19 +4743,22 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3869,19 +4743,22 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3869 | 4743 | ||
| 3870 | fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue { | 4744 | fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CValue { |
| 3871 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | 4745 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 4746 | const ptr_ty = f.air.typeOf(bin_op.lhs); | ||
| 3872 | const ptr = try f.resolveInst(bin_op.lhs); | 4747 | const ptr = try f.resolveInst(bin_op.lhs); |
| 3873 | const element = try f.resolveInst(bin_op.rhs); | 4748 | const element = try f.resolveInst(bin_op.rhs); |
| 3874 | const inst_ty = f.air.typeOfIndex(inst); | ||
| 3875 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 3876 | const writer = f.object.writer(); | 4749 | const writer = f.object.writer(); |
| 3877 | 4750 | ||
| 3878 | try writer.writeAll(" = zig_atomic_store("); | 4751 | try writer.writeAll("zig_atomic_store((zig_atomic("); |
| 3879 | try f.writeCValue(writer, ptr); | 4752 | try f.renderTypecast(writer, ptr_ty.elemType()); |
| 4753 | try writer.writeByte(')'); | ||
| 4754 | if (ptr_ty.isVolatilePtr()) try writer.writeAll(" volatile"); | ||
| 4755 | try writer.writeAll(" *)"); | ||
| 4756 | try f.writeCValue(writer, ptr, .Other); | ||
| 3880 | try writer.writeAll(", "); | 4757 | try writer.writeAll(", "); |
| 3881 | try f.writeCValue(writer, element); | 4758 | try f.writeCValue(writer, element, .FunctionArgument); |
| 3882 | try writer.print(", {s});\n", .{order}); | 4759 | try writer.print(", {s});\n", .{order}); |
| 3883 | 4760 | ||
| 3884 | return local; | 4761 | return CValue.none; |
| 3885 | } | 4762 | } |
| 3886 | 4763 | ||
| 3887 | fn airMemset(f: *Function, inst: Air.Inst.Index) !CValue { | 4764 | fn airMemset(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | @@ -3893,11 +4770,11 @@ fn airMemset(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3893,11 +4770,11 @@ fn airMemset(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3893 | const writer = f.object.writer(); | 4770 | const writer = f.object.writer(); |
| 3894 | 4771 | ||
| 3895 | try writer.writeAll("memset("); | 4772 | try writer.writeAll("memset("); |
| 3896 | try f.writeCValue(writer, dest_ptr); | 4773 | try f.writeCValue(writer, dest_ptr, .FunctionArgument); |
| 3897 | try writer.writeAll(", "); | 4774 | try writer.writeAll(", "); |
| 3898 | try f.writeCValue(writer, value); | 4775 | try f.writeCValue(writer, value, .FunctionArgument); |
| 3899 | try writer.writeAll(", "); | 4776 | try writer.writeAll(", "); |
| 3900 | try f.writeCValue(writer, len); | 4777 | try f.writeCValue(writer, len, .FunctionArgument); |
| 3901 | try writer.writeAll(");\n"); | 4778 | try writer.writeAll(");\n"); |
| 3902 | 4779 | ||
| 3903 | return CValue.none; | 4780 | return CValue.none; |
| ... | @@ -3912,11 +4789,11 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3912,11 +4789,11 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3912 | const writer = f.object.writer(); | 4789 | const writer = f.object.writer(); |
| 3913 | 4790 | ||
| 3914 | try writer.writeAll("memcpy("); | 4791 | try writer.writeAll("memcpy("); |
| 3915 | try f.writeCValue(writer, dest_ptr); | 4792 | try f.writeCValue(writer, dest_ptr, .FunctionArgument); |
| 3916 | try writer.writeAll(", "); | 4793 | try writer.writeAll(", "); |
| 3917 | try f.writeCValue(writer, src_ptr); | 4794 | try f.writeCValue(writer, src_ptr, .FunctionArgument); |
| 3918 | try writer.writeAll(", "); | 4795 | try writer.writeAll(", "); |
| 3919 | try f.writeCValue(writer, len); | 4796 | try f.writeCValue(writer, len, .FunctionArgument); |
| 3920 | try writer.writeAll(");\n"); | 4797 | try writer.writeAll(");\n"); |
| 3921 | 4798 | ||
| 3922 | return CValue.none; | 4799 | return CValue.none; |
| ... | @@ -3933,9 +4810,10 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3933,9 +4810,10 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3933 | const layout = union_ty.unionGetLayout(target); | 4810 | const layout = union_ty.unionGetLayout(target); |
| 3934 | if (layout.tag_size == 0) return CValue.none; | 4811 | if (layout.tag_size == 0) return CValue.none; |
| 3935 | 4812 | ||
| 3936 | try f.writeCValue(writer, union_ptr); | 4813 | try writer.writeByte('('); |
| 3937 | try writer.writeAll("->tag = "); | 4814 | try f.writeCValue(writer, union_ptr, .Other); |
| 3938 | try f.writeCValue(writer, new_tag); | 4815 | try writer.writeAll(")->tag = "); |
| 4816 | try f.writeCValue(writer, new_tag, .Other); | ||
| 3939 | try writer.writeAll(";\n"); | 4817 | try writer.writeAll(";\n"); |
| 3940 | 4818 | ||
| 3941 | return CValue.none; | 4819 | return CValue.none; |
| ... | @@ -3957,7 +4835,7 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3957,7 +4835,7 @@ fn airGetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3957 | if (layout.tag_size == 0) return CValue.none; | 4835 | if (layout.tag_size == 0) return CValue.none; |
| 3958 | 4836 | ||
| 3959 | try writer.writeAll(" = "); | 4837 | try writer.writeAll(" = "); |
| 3960 | try f.writeCValue(writer, operand); | 4838 | try f.writeCValue(writer, operand, .Other); |
| 3961 | try writer.writeAll(".tag;\n"); | 4839 | try writer.writeAll(".tag;\n"); |
| 3962 | return local; | 4840 | return local; |
| 3963 | } | 4841 | } |
| ... | @@ -3966,18 +4844,17 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3966,18 +4844,17 @@ fn airTagName(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3966 | if (f.liveness.isUnused(inst)) return CValue.none; | 4844 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 3967 | 4845 | ||
| 3968 | const un_op = f.air.instructions.items(.data)[inst].un_op; | 4846 | const un_op = f.air.instructions.items(.data)[inst].un_op; |
| 3969 | const writer = f.object.writer(); | ||
| 3970 | const inst_ty = f.air.typeOfIndex(inst); | 4847 | const inst_ty = f.air.typeOfIndex(inst); |
| 4848 | const enum_ty = f.air.typeOf(un_op); | ||
| 3971 | const operand = try f.resolveInst(un_op); | 4849 | const operand = try f.resolveInst(un_op); |
| 3972 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 3973 | 4850 | ||
| 3974 | try writer.writeAll(" = "); | 4851 | const writer = f.object.writer(); |
| 4852 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 4853 | try writer.print(" = {s}(", .{try f.object.dg.getTagNameFn(enum_ty)}); | ||
| 4854 | try f.writeCValue(writer, operand, .Other); | ||
| 4855 | try writer.writeAll(");\n"); | ||
| 3975 | 4856 | ||
| 3976 | _ = operand; | 4857 | return local; |
| 3977 | _ = local; | ||
| 3978 | return f.fail("TODO: C backend: implement airTagName", .{}); | ||
| 3979 | //try writer.writeAll(";\n"); | ||
| 3980 | //return local; | ||
| 3981 | } | 4858 | } |
| 3982 | 4859 | ||
| 3983 | fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue { | 4860 | fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | @@ -3989,11 +4866,10 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3989,11 +4866,10 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3989 | const operand = try f.resolveInst(un_op); | 4866 | const operand = try f.resolveInst(un_op); |
| 3990 | const local = try f.allocLocal(inst_ty, .Const); | 4867 | const local = try f.allocLocal(inst_ty, .Const); |
| 3991 | 4868 | ||
| 3992 | try writer.writeAll(" = "); | 4869 | try writer.writeAll(" = zig_errorName["); |
| 3993 | 4870 | try f.writeCValue(writer, operand, .Other); | |
| 3994 | _ = operand; | 4871 | try writer.writeAll("];\n"); |
| 3995 | _ = local; | 4872 | return local; |
| 3996 | return f.fail("TODO: C backend: implement airErrorName", .{}); | ||
| 3997 | } | 4873 | } |
| 3998 | 4874 | ||
| 3999 | fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue { | 4875 | fn airSplat(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | @@ -4061,29 +4937,131 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4061,29 +4937,131 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4061 | 4937 | ||
| 4062 | const inst_ty = f.air.typeOfIndex(inst); | 4938 | const inst_ty = f.air.typeOfIndex(inst); |
| 4063 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; | 4939 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| 4064 | const vector_ty = f.air.getRefType(ty_pl.ty); | 4940 | const len = @intCast(usize, inst_ty.arrayLen()); |
| 4065 | const len = vector_ty.vectorLen(); | ||
| 4066 | const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]); | 4941 | const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]); |
| 4942 | const target = f.object.dg.module.getTarget(); | ||
| 4943 | const mutability: Mutability = for (elements) |element| { | ||
| 4944 | if (lowersToArray(f.air.typeOf(element), target)) break .Mut; | ||
| 4945 | } else .Const; | ||
| 4067 | 4946 | ||
| 4068 | const writer = f.object.writer(); | 4947 | const writer = f.object.writer(); |
| 4069 | const local = try f.allocLocal(inst_ty, .Const); | 4948 | const local = try f.allocLocal(inst_ty, mutability); |
| 4070 | try writer.writeAll(" = {"); | 4949 | try writer.writeAll(" = "); |
| 4071 | switch (vector_ty.zigTypeTag()) { | 4950 | switch (inst_ty.zigTypeTag()) { |
| 4072 | .Struct => { | 4951 | .Array => { |
| 4073 | const tuple = vector_ty.tupleFields(); | 4952 | const elem_ty = inst_ty.childType(); |
| 4074 | var i: usize = 0; | 4953 | try writer.writeByte('{'); |
| 4075 | for (elements) |elem, elem_index| { | 4954 | var empty = true; |
| 4076 | if (tuple.values[elem_index].tag() != .unreachable_value) continue; | 4955 | for (elements) |element| { |
| 4077 | 4956 | if (!empty) try writer.writeAll(", "); | |
| 4078 | const value = try f.resolveInst(elem); | 4957 | try f.writeCValue(writer, try f.resolveInst(element), .Initializer); |
| 4079 | if (i != 0) try writer.writeAll(", "); | 4958 | empty = false; |
| 4080 | try f.writeCValue(writer, value); | 4959 | } |
| 4081 | i += 1; | 4960 | if (inst_ty.sentinel()) |sentinel| { |
| 4961 | if (!empty) try writer.writeAll(", "); | ||
| 4962 | try f.object.dg.renderValue(writer, elem_ty, sentinel, .Initializer); | ||
| 4963 | empty = false; | ||
| 4082 | } | 4964 | } |
| 4965 | if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)}); | ||
| 4966 | try writer.writeAll("};\n"); | ||
| 4967 | }, | ||
| 4968 | .Struct => switch (inst_ty.containerLayout()) { | ||
| 4969 | .Auto, .Extern => { | ||
| 4970 | try writer.writeByte('{'); | ||
| 4971 | var empty = true; | ||
| 4972 | for (elements) |element, index| { | ||
| 4973 | if (inst_ty.structFieldValueComptime(index)) |_| continue; | ||
| 4974 | |||
| 4975 | if (!empty) try writer.writeAll(", "); | ||
| 4976 | if (!inst_ty.isTupleOrAnonStruct()) { | ||
| 4977 | try writer.print(".{ } = ", .{fmtIdent(inst_ty.structFieldName(index))}); | ||
| 4978 | } | ||
| 4979 | |||
| 4980 | const element_ty = f.air.typeOf(element); | ||
| 4981 | try f.writeCValue(writer, switch (element_ty.zigTypeTag()) { | ||
| 4982 | .Array => CValue{ .undef = element_ty }, | ||
| 4983 | else => try f.resolveInst(element), | ||
| 4984 | }, .Initializer); | ||
| 4985 | empty = false; | ||
| 4986 | } | ||
| 4987 | if (empty) try writer.print("{}", .{try f.fmtIntLiteral(Type.u8, Value.zero)}); | ||
| 4988 | try writer.writeAll("};\n"); | ||
| 4989 | |||
| 4990 | for (elements) |element, index| { | ||
| 4991 | if (inst_ty.structFieldValueComptime(index)) |_| continue; | ||
| 4992 | |||
| 4993 | const element_ty = f.air.typeOf(element); | ||
| 4994 | if (element_ty.zigTypeTag() != .Array) continue; | ||
| 4995 | |||
| 4996 | var field_name_buf: []u8 = &.{}; | ||
| 4997 | defer f.object.dg.gpa.free(field_name_buf); | ||
| 4998 | const field_name = if (inst_ty.isTuple()) field_name: { | ||
| 4999 | field_name_buf = try std.fmt.allocPrint(f.object.dg.gpa, "field_{d}", .{index}); | ||
| 5000 | break :field_name field_name_buf; | ||
| 5001 | } else inst_ty.structFieldName(index); | ||
| 5002 | |||
| 5003 | try writer.writeAll(";\n"); | ||
| 5004 | try writer.writeAll("memcpy("); | ||
| 5005 | try f.writeCValue(writer, local, .Other); | ||
| 5006 | try writer.print(".{ }, ", .{fmtIdent(field_name)}); | ||
| 5007 | try f.writeCValue(writer, try f.resolveInst(element), .FunctionArgument); | ||
| 5008 | try writer.writeAll(", sizeof("); | ||
| 5009 | try f.renderTypecast(writer, element_ty); | ||
| 5010 | try writer.writeAll("));\n"); | ||
| 5011 | } | ||
| 5012 | }, | ||
| 5013 | .Packed => { | ||
| 5014 | const int_info = inst_ty.intInfo(target); | ||
| 5015 | |||
| 5016 | var bit_offset_ty_pl = Type.Payload.Bits{ | ||
| 5017 | .base = .{ .tag = .int_unsigned }, | ||
| 5018 | .data = Type.smallestUnsignedBits(int_info.bits - 1), | ||
| 5019 | }; | ||
| 5020 | const bit_offset_ty = Type.initPayload(&bit_offset_ty_pl.base); | ||
| 5021 | |||
| 5022 | var bit_offset_val_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = 0 }; | ||
| 5023 | const bit_offset_val = Value.initPayload(&bit_offset_val_pl.base); | ||
| 5024 | |||
| 5025 | var empty = true; | ||
| 5026 | for (elements) |_, index| { | ||
| 5027 | const field_ty = inst_ty.structFieldType(index); | ||
| 5028 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; | ||
| 5029 | |||
| 5030 | if (!empty) { | ||
| 5031 | try writer.writeAll("zig_or_"); | ||
| 5032 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); | ||
| 5033 | try writer.writeByte('('); | ||
| 5034 | } | ||
| 5035 | empty = false; | ||
| 5036 | } | ||
| 5037 | empty = true; | ||
| 5038 | for (elements) |element, index| { | ||
| 5039 | const field_ty = inst_ty.structFieldType(index); | ||
| 5040 | if (!field_ty.hasRuntimeBitsIgnoreComptime()) continue; | ||
| 5041 | |||
| 5042 | if (!empty) try writer.writeAll(", "); | ||
| 5043 | try writer.writeAll("zig_shlw_"); | ||
| 5044 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); | ||
| 5045 | try writer.writeAll("(("); | ||
| 5046 | try f.renderTypecast(writer, inst_ty); | ||
| 5047 | try writer.writeByte(')'); | ||
| 5048 | try f.writeCValue(writer, try f.resolveInst(element), .Other); | ||
| 5049 | try writer.writeAll(", "); | ||
| 5050 | try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument); | ||
| 5051 | try f.object.dg.renderBuiltinInfo(writer, inst_ty, .Bits); | ||
| 5052 | try writer.writeByte(')'); | ||
| 5053 | if (!empty) try writer.writeByte(')'); | ||
| 5054 | |||
| 5055 | bit_offset_val_pl.data += field_ty.bitSize(target); | ||
| 5056 | empty = false; | ||
| 5057 | } | ||
| 5058 | if (empty) try f.writeCValue(writer, .{ .undef = inst_ty }, .Initializer); | ||
| 5059 | try writer.writeAll(";\n"); | ||
| 5060 | }, | ||
| 4083 | }, | 5061 | }, |
| 4084 | else => |tag| return f.fail("TODO: C backend: implement airAggregateInit for type {s}", .{@tagName(tag)}), | 5062 | .Vector => return f.fail("TODO: C backend: implement airAggregateInit for vectors", .{}), |
| 5063 | else => unreachable, | ||
| 4085 | } | 5064 | } |
| 4086 | try writer.writeAll("};\n"); | ||
| 4087 | 5065 | ||
| 4088 | return local; | 5066 | return local; |
| 4089 | } | 5067 | } |
| ... | @@ -4091,16 +5069,43 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4091,16 +5069,43 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4091 | fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { | 5069 | fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4092 | if (f.liveness.isUnused(inst)) return CValue.none; | 5070 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 4093 | 5071 | ||
| 4094 | const inst_ty = f.air.typeOfIndex(inst); | ||
| 4095 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; | 5072 | const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; |
| 5073 | const extra = f.air.extraData(Air.UnionInit, ty_pl.payload).data; | ||
| 5074 | const union_ty = f.air.typeOfIndex(inst); | ||
| 5075 | const target = f.object.dg.module.getTarget(); | ||
| 5076 | const layout = union_ty.unionGetLayout(target); | ||
| 5077 | const union_obj = union_ty.cast(Type.Payload.Union).?.data; | ||
| 5078 | const field_name = union_obj.fields.keys()[extra.field_index]; | ||
| 5079 | const payload = try f.resolveInst(extra.init); | ||
| 4096 | 5080 | ||
| 4097 | const writer = f.object.writer(); | 5081 | const writer = f.object.writer(); |
| 4098 | const local = try f.allocLocal(inst_ty, .Const); | 5082 | const local = try f.allocLocal(union_ty, .Const); |
| 4099 | try writer.writeAll(" = "); | 5083 | try writer.writeAll(" = {"); |
| 5084 | if (union_ty.unionTagTypeSafety()) |tag_ty| { | ||
| 5085 | if (layout.tag_size != 0) { | ||
| 5086 | const field_index = tag_ty.enumFieldIndex(field_name).?; | ||
| 4100 | 5087 | ||
| 4101 | _ = local; | 5088 | var tag_pl: Value.Payload.U32 = .{ |
| 4102 | _ = ty_pl; | 5089 | .base = .{ .tag = .enum_field_index }, |
| 4103 | return f.fail("TODO: C backend: implement airUnionInit", .{}); | 5090 | .data = @intCast(u32, field_index), |
| 5091 | }; | ||
| 5092 | const tag_val = Value.initPayload(&tag_pl.base); | ||
| 5093 | |||
| 5094 | var int_pl: Value.Payload.U64 = undefined; | ||
| 5095 | const int_val = tag_val.enumToInt(tag_ty, &int_pl); | ||
| 5096 | |||
| 5097 | try writer.print(".tag = {}, ", .{try f.fmtIntLiteral(tag_ty, int_val)}); | ||
| 5098 | } | ||
| 5099 | try writer.writeAll(".payload = {"); | ||
| 5100 | } | ||
| 5101 | |||
| 5102 | try writer.print(".{ } = ", .{fmtIdent(field_name)}); | ||
| 5103 | try f.writeCValue(writer, payload, .Initializer); | ||
| 5104 | |||
| 5105 | if (union_ty.unionTagTypeSafety()) |_| try writer.writeByte('}'); | ||
| 5106 | try writer.writeAll("};\n"); | ||
| 5107 | |||
| 5108 | return local; | ||
| 4104 | } | 5109 | } |
| 4105 | 5110 | ||
| 4106 | fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue { | 5111 | fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue { |
| ... | @@ -4115,7 +5120,7 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4115,7 +5120,7 @@ fn airPrefetch(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4115 | const ptr = try f.resolveInst(prefetch.ptr); | 5120 | const ptr = try f.resolveInst(prefetch.ptr); |
| 4116 | const writer = f.object.writer(); | 5121 | const writer = f.object.writer(); |
| 4117 | try writer.writeAll("zig_prefetch("); | 5122 | try writer.writeAll("zig_prefetch("); |
| 4118 | try f.writeCValue(writer, ptr); | 5123 | try f.writeCValue(writer, ptr, .FunctionArgument); |
| 4119 | try writer.print(", {d}, {d});\n", .{ | 5124 | try writer.print(", {d}, {d});\n", .{ |
| 4120 | @enumToInt(prefetch.rw), prefetch.locality, | 5125 | @enumToInt(prefetch.rw), prefetch.locality, |
| 4121 | }); | 5126 | }); |
| ... | @@ -4147,7 +5152,7 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4147,7 +5152,7 @@ fn airWasmMemoryGrow(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4147 | 5152 | ||
| 4148 | try writer.writeAll(" = "); | 5153 | try writer.writeAll(" = "); |
| 4149 | try writer.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload}); | 5154 | try writer.print("zig_wasm_memory_grow({d}, ", .{pl_op.payload}); |
| 4150 | try f.writeCValue(writer, operand); | 5155 | try f.writeCValue(writer, operand, .FunctionArgument); |
| 4151 | try writer.writeAll(");\n"); | 5156 | try writer.writeAll(");\n"); |
| 4152 | return local; | 5157 | return local; |
| 4153 | } | 5158 | } |
| ... | @@ -4160,12 +5165,49 @@ fn airNeg(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4160,12 +5165,49 @@ fn airNeg(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4160 | const inst_ty = f.air.typeOfIndex(inst); | 5165 | const inst_ty = f.air.typeOfIndex(inst); |
| 4161 | const operand = try f.resolveInst(un_op); | 5166 | const operand = try f.resolveInst(un_op); |
| 4162 | const local = try f.allocLocal(inst_ty, .Const); | 5167 | const local = try f.allocLocal(inst_ty, .Const); |
| 4163 | try writer.writeAll("-"); | 5168 | try writer.writeAll(" = -"); |
| 4164 | try f.writeCValue(writer, operand); | 5169 | try f.writeCValue(writer, operand, .Other); |
| 4165 | try writer.writeAll(";\n"); | 5170 | try writer.writeAll(";\n"); |
| 4166 | return local; | 5171 | return local; |
| 4167 | } | 5172 | } |
| 4168 | 5173 | ||
| 5174 | fn airUnFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue { | ||
| 5175 | if (f.liveness.isUnused(inst)) return CValue.none; | ||
| 5176 | const un_op = f.air.instructions.items(.data)[inst].un_op; | ||
| 5177 | const writer = f.object.writer(); | ||
| 5178 | const inst_ty = f.air.typeOfIndex(inst); | ||
| 5179 | const operand = try f.resolveInst(un_op); | ||
| 5180 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 5181 | try writer.writeAll(" = zig_builtin_"); | ||
| 5182 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); | ||
| 5183 | try writer.writeByte('('); | ||
| 5184 | try writer.writeAll(operation); | ||
| 5185 | try writer.writeAll(")("); | ||
| 5186 | try f.writeCValue(writer, operand, .FunctionArgument); | ||
| 5187 | try writer.writeAll(");\n"); | ||
| 5188 | return local; | ||
| 5189 | } | ||
| 5190 | |||
| 5191 | fn airBinFloatOp(f: *Function, inst: Air.Inst.Index, operation: []const u8) !CValue { | ||
| 5192 | if (f.liveness.isUnused(inst)) return CValue.none; | ||
| 5193 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | ||
| 5194 | const writer = f.object.writer(); | ||
| 5195 | const inst_ty = f.air.typeOfIndex(inst); | ||
| 5196 | const lhs = try f.resolveInst(bin_op.lhs); | ||
| 5197 | const rhs = try f.resolveInst(bin_op.rhs); | ||
| 5198 | const local = try f.allocLocal(inst_ty, .Const); | ||
| 5199 | try writer.writeAll(" = zig_builtin_"); | ||
| 5200 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); | ||
| 5201 | try writer.writeByte('('); | ||
| 5202 | try writer.writeAll(operation); | ||
| 5203 | try writer.writeAll(")("); | ||
| 5204 | try f.writeCValue(writer, lhs, .FunctionArgument); | ||
| 5205 | try writer.writeAll(", "); | ||
| 5206 | try f.writeCValue(writer, rhs, .FunctionArgument); | ||
| 5207 | try writer.writeAll(");\n"); | ||
| 5208 | return local; | ||
| 5209 | } | ||
| 5210 | |||
| 4169 | fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { | 5211 | fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4170 | if (f.liveness.isUnused(inst)) return CValue.none; | 5212 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 4171 | const pl_op = f.air.instructions.items(.data)[inst].pl_op; | 5213 | const pl_op = f.air.instructions.items(.data)[inst].pl_op; |
| ... | @@ -4175,30 +5217,23 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4175,30 +5217,23 @@ fn airMulAdd(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4175 | const mulend2 = try f.resolveInst(extra.rhs); | 5217 | const mulend2 = try f.resolveInst(extra.rhs); |
| 4176 | const addend = try f.resolveInst(pl_op.operand); | 5218 | const addend = try f.resolveInst(pl_op.operand); |
| 4177 | const writer = f.object.writer(); | 5219 | const writer = f.object.writer(); |
| 4178 | const target = f.object.dg.module.getTarget(); | ||
| 4179 | const fn_name = switch (inst_ty.floatBits(target)) { | ||
| 4180 | 16, 32 => "fmaf", | ||
| 4181 | 64 => "fma", | ||
| 4182 | 80 => if (CType.longdouble.sizeInBits(target) == 80) "fmal" else "__fmax", | ||
| 4183 | 128 => if (CType.longdouble.sizeInBits(target) == 128) "fmal" else "fmaq", | ||
| 4184 | else => unreachable, | ||
| 4185 | }; | ||
| 4186 | const local = try f.allocLocal(inst_ty, .Const); | 5220 | const local = try f.allocLocal(inst_ty, .Const); |
| 4187 | try writer.writeAll(" = "); | 5221 | try writer.writeAll(" = zig_builtin_"); |
| 4188 | try writer.print("{s}(", .{fn_name}); | 5222 | try f.object.dg.renderTypeForBuiltinFnName(writer, inst_ty); |
| 4189 | try f.writeCValue(writer, mulend1); | 5223 | try writer.writeAll("(fma)("); |
| 5224 | try f.writeCValue(writer, mulend1, .FunctionArgument); | ||
| 4190 | try writer.writeAll(", "); | 5225 | try writer.writeAll(", "); |
| 4191 | try f.writeCValue(writer, mulend2); | 5226 | try f.writeCValue(writer, mulend2, .FunctionArgument); |
| 4192 | try writer.writeAll(", "); | 5227 | try writer.writeAll(", "); |
| 4193 | try f.writeCValue(writer, addend); | 5228 | try f.writeCValue(writer, addend, .FunctionArgument); |
| 4194 | try writer.writeAll(");\n"); | 5229 | try writer.writeAll(");\n"); |
| 4195 | return local; | 5230 | return local; |
| 4196 | } | 5231 | } |
| 4197 | 5232 | ||
| 4198 | fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 { | 5233 | fn toMemoryOrder(order: std.builtin.AtomicOrder) [:0]const u8 { |
| 4199 | return switch (order) { | 5234 | return switch (order) { |
| 4200 | .Unordered => "memory_order_relaxed", | 5235 | // Note: unordered is actually even less atomic than relaxed |
| 4201 | .Monotonic => "memory_order_consume", | 5236 | .Unordered, .Monotonic => "memory_order_relaxed", |
| 4202 | .Acquire => "memory_order_acquire", | 5237 | .Acquire => "memory_order_acquire", |
| 4203 | .Release => "memory_order_release", | 5238 | .Release => "memory_order_release", |
| 4204 | .AcqRel => "memory_order_acq_rel", | 5239 | .AcqRel => "memory_order_acq_rel", |
| ... | @@ -4293,61 +5328,250 @@ fn signAbbrev(signedness: std.builtin.Signedness) u8 { | ... | @@ -4293,61 +5328,250 @@ fn signAbbrev(signedness: std.builtin.Signedness) u8 { |
| 4293 | }; | 5328 | }; |
| 4294 | } | 5329 | } |
| 4295 | 5330 | ||
| 4296 | fn intMax(ty: Type, target: std.Target, buf: []u8) []const u8 { | 5331 | fn formatStringLiteral( |
| 4297 | switch (ty.tag()) { | 5332 | str: []const u8, |
| 4298 | .c_short => return "SHRT_MAX", | 5333 | comptime fmt: []const u8, |
| 4299 | .c_ushort => return "USHRT_MAX", | 5334 | _: std.fmt.FormatOptions, |
| 4300 | .c_int => return "INT_MAX", | 5335 | writer: anytype, |
| 4301 | .c_uint => return "UINT_MAX", | 5336 | ) @TypeOf(writer).Error!void { |
| 4302 | .c_long => return "LONG_MAX", | 5337 | if (fmt.len != 1 or fmt[0] != 's') @compileError("Invalid fmt: " ++ fmt); |
| 4303 | .c_ulong => return "ULONG_MAX", | 5338 | try writer.writeByte('\"'); |
| 4304 | .c_longlong => return "LLONG_MAX", | 5339 | for (str) |c| switch (c) { |
| 4305 | .c_ulonglong => return "ULLONG_MAX", | 5340 | 7 => try writer.writeAll("\\a"), |
| 4306 | else => { | 5341 | 8 => try writer.writeAll("\\b"), |
| 4307 | const int_info = ty.intInfo(target); | 5342 | '\t' => try writer.writeAll("\\t"), |
| 4308 | const rhs = @intCast(u7, int_info.bits - @boolToInt(int_info.signedness == .signed)); | 5343 | '\n' => try writer.writeAll("\\n"), |
| 4309 | const val = (@as(u128, 1) << rhs) - 1; | 5344 | 11 => try writer.writeAll("\\v"), |
| 4310 | // TODO make this integer literal have a suffix if necessary (such as "ull") | 5345 | 12 => try writer.writeAll("\\f"), |
| 4311 | return std.fmt.bufPrint(buf, "{}", .{val}) catch |err| switch (err) { | 5346 | '\r' => try writer.writeAll("\\r"), |
| 4312 | error.NoSpaceLeft => unreachable, | 5347 | '"', '\'', '?', '\\' => try writer.print("\\{c}", .{c}), |
| 4313 | }; | 5348 | else => switch (c) { |
| 5349 | ' '...'~' => try writer.writeByte(c), | ||
| 5350 | else => try writer.print("\\{o:0>3}", .{c}), | ||
| 4314 | }, | 5351 | }, |
| 4315 | } | 5352 | }; |
| 5353 | try writer.writeByte('\"'); | ||
| 5354 | } | ||
| 5355 | fn fmtStringLiteral(str: []const u8) std.fmt.Formatter(formatStringLiteral) { | ||
| 5356 | return .{ .data = str }; | ||
| 4316 | } | 5357 | } |
| 4317 | 5358 | ||
| 4318 | fn intMin(ty: Type, target: std.Target, buf: []u8) []const u8 { | 5359 | fn undefPattern(comptime T: type) T { |
| 4319 | switch (ty.tag()) { | 5360 | return (1 << (@bitSizeOf(T) | 1)) / 3; |
| 4320 | .c_short => return "SHRT_MIN", | ||
| 4321 | .c_int => return "INT_MIN", | ||
| 4322 | .c_long => return "LONG_MIN", | ||
| 4323 | .c_longlong => return "LLONG_MIN", | ||
| 4324 | else => { | ||
| 4325 | const int_info = ty.intInfo(target); | ||
| 4326 | assert(int_info.signedness == .signed); | ||
| 4327 | const val = v: { | ||
| 4328 | if (int_info.bits == 0) break :v 0; | ||
| 4329 | const rhs = @intCast(u7, (int_info.bits - 1)); | ||
| 4330 | break :v -(@as(i128, 1) << rhs); | ||
| 4331 | }; | ||
| 4332 | return std.fmt.bufPrint(buf, "{d}", .{val}) catch |err| switch (err) { | ||
| 4333 | error.NoSpaceLeft => unreachable, | ||
| 4334 | }; | ||
| 4335 | }, | ||
| 4336 | } | ||
| 4337 | } | 5361 | } |
| 4338 | 5362 | ||
| 4339 | fn loweredFnRetTyHasBits(fn_ty: Type) bool { | 5363 | const FormatIntLiteralContext = struct { |
| 4340 | const ret_ty = fn_ty.fnReturnType(); | 5364 | ty: Type, |
| 4341 | if (ret_ty.hasRuntimeBitsIgnoreComptime()) { | 5365 | val: Value, |
| 4342 | return true; | 5366 | mod: *Module, |
| 5367 | }; | ||
| 5368 | fn formatIntLiteral( | ||
| 5369 | data: FormatIntLiteralContext, | ||
| 5370 | comptime fmt: []const u8, | ||
| 5371 | options: std.fmt.FormatOptions, | ||
| 5372 | writer: anytype, | ||
| 5373 | ) @TypeOf(writer).Error!void { | ||
| 5374 | const target = data.mod.getTarget(); | ||
| 5375 | const int_info = data.ty.intInfo(target); | ||
| 5376 | |||
| 5377 | const Limb = std.math.big.Limb; | ||
| 5378 | const ExpectedContents = struct { | ||
| 5379 | const base = 10; | ||
| 5380 | const limbs_count_128 = BigInt.calcTwosCompLimbCount(128); | ||
| 5381 | const expected_needed_limbs_count = BigInt.calcToStringLimbsBufferLen(limbs_count_128, base); | ||
| 5382 | const worst_case_int = BigInt.Const{ | ||
| 5383 | .limbs = &([1]Limb{std.math.maxInt(Limb)} ** expected_needed_limbs_count), | ||
| 5384 | .positive = false, | ||
| 5385 | }; | ||
| 5386 | |||
| 5387 | undef_limbs: [limbs_count_128]Limb, | ||
| 5388 | wrap_limbs: [limbs_count_128]Limb, | ||
| 5389 | }; | ||
| 5390 | var stack align(@alignOf(ExpectedContents)) = | ||
| 5391 | std.heap.stackFallback(@sizeOf(ExpectedContents), data.mod.gpa); | ||
| 5392 | const allocator = stack.get(); | ||
| 5393 | |||
| 5394 | var undef_limbs: []Limb = &.{}; | ||
| 5395 | defer allocator.free(undef_limbs); | ||
| 5396 | |||
| 5397 | var int_buf: Value.BigIntSpace = undefined; | ||
| 5398 | const int = if (data.val.isUndefDeep()) blk: { | ||
| 5399 | undef_limbs = try allocator.alloc(Limb, BigInt.calcTwosCompLimbCount(int_info.bits)); | ||
| 5400 | std.mem.set(Limb, undef_limbs, undefPattern(Limb)); | ||
| 5401 | |||
| 5402 | var undef_int = BigInt.Mutable{ | ||
| 5403 | .limbs = undef_limbs, | ||
| 5404 | .len = undef_limbs.len, | ||
| 5405 | .positive = true, | ||
| 5406 | }; | ||
| 5407 | undef_int.truncate(undef_int.toConst(), int_info.signedness, int_info.bits); | ||
| 5408 | break :blk undef_int.toConst(); | ||
| 5409 | } else data.val.toBigInt(&int_buf, target); | ||
| 5410 | assert(int.fitsInTwosComp(int_info.signedness, int_info.bits)); | ||
| 5411 | |||
| 5412 | const c_bits = toCIntBits(int_info.bits) orelse unreachable; | ||
| 5413 | var one_limbs: [BigInt.calcLimbLen(1)]Limb = undefined; | ||
| 5414 | const one = BigInt.Mutable.init(&one_limbs, 1).toConst(); | ||
| 5415 | |||
| 5416 | const wrap_limbs = try allocator.alloc(Limb, BigInt.calcTwosCompLimbCount(c_bits)); | ||
| 5417 | defer allocator.free(wrap_limbs); | ||
| 5418 | var wrap = BigInt.Mutable{ .limbs = wrap_limbs, .len = undefined, .positive = undefined }; | ||
| 5419 | if (wrap.addWrap(int, one, int_info.signedness, c_bits) or | ||
| 5420 | int_info.signedness == .signed and wrap.subWrap(int, one, int_info.signedness, c_bits)) | ||
| 5421 | { | ||
| 5422 | const abbrev = switch (data.ty.tag()) { | ||
| 5423 | .c_short, .c_ushort => "SHRT", | ||
| 5424 | .c_int, .c_uint => "INT", | ||
| 5425 | .c_long, .c_ulong => "LONG", | ||
| 5426 | .c_longlong, .c_ulonglong => "LLONG", | ||
| 5427 | .isize, .usize => "INTPTR", | ||
| 5428 | else => return writer.print("zig_{s}Int_{c}{d}", .{ | ||
| 5429 | if (int.positive) "max" else "min", signAbbrev(int_info.signedness), c_bits, | ||
| 5430 | }), | ||
| 5431 | }; | ||
| 5432 | if (int_info.signedness == .unsigned) try writer.writeByte('U'); | ||
| 5433 | return writer.print("{s}_{s}", .{ abbrev, if (int.positive) "MAX" else "MIN" }); | ||
| 4343 | } | 5434 | } |
| 4344 | if (ret_ty.isError()) { | 5435 | |
| 4345 | return true; | 5436 | if (!int.positive) try writer.writeByte('-'); |
| 5437 | switch (data.ty.tag()) { | ||
| 5438 | .c_short, .c_ushort, .c_int, .c_uint, .c_long, .c_ulong, .c_longlong, .c_ulonglong => {}, | ||
| 5439 | else => try writer.print("zig_as_{c}{d}(", .{ signAbbrev(int_info.signedness), c_bits }), | ||
| 5440 | } | ||
| 5441 | |||
| 5442 | const limbs_count_64 = @divExact(64, @bitSizeOf(Limb)); | ||
| 5443 | if (c_bits <= 64) { | ||
| 5444 | var base: u8 = undefined; | ||
| 5445 | var case: std.fmt.Case = undefined; | ||
| 5446 | switch (fmt.len) { | ||
| 5447 | 0 => base = 10, | ||
| 5448 | 1 => switch (fmt[0]) { | ||
| 5449 | 'b' => { | ||
| 5450 | base = 2; | ||
| 5451 | try writer.writeAll("0b"); | ||
| 5452 | }, | ||
| 5453 | 'o' => { | ||
| 5454 | base = 8; | ||
| 5455 | try writer.writeByte('0'); | ||
| 5456 | }, | ||
| 5457 | 'd' => base = 10, | ||
| 5458 | 'x' => { | ||
| 5459 | base = 16; | ||
| 5460 | case = .lower; | ||
| 5461 | try writer.writeAll("0x"); | ||
| 5462 | }, | ||
| 5463 | 'X' => { | ||
| 5464 | base = 16; | ||
| 5465 | case = .upper; | ||
| 5466 | try writer.writeAll("0x"); | ||
| 5467 | }, | ||
| 5468 | else => @compileError("Invalid fmt: " ++ fmt), | ||
| 5469 | }, | ||
| 5470 | else => @compileError("Invalid fmt: " ++ fmt), | ||
| 5471 | } | ||
| 5472 | |||
| 5473 | var str: [64]u8 = undefined; | ||
| 5474 | var limbs_buf: [BigInt.calcToStringLimbsBufferLen(limbs_count_64, 10)]Limb = undefined; | ||
| 5475 | try writer.writeAll(str[0..int.abs().toString(&str, base, case, &limbs_buf)]); | ||
| 5476 | } else { | ||
| 5477 | assert(c_bits == 128); | ||
| 5478 | const split = std.math.min(int.limbs.len, limbs_count_64); | ||
| 5479 | |||
| 5480 | var upper_pl = Value.Payload.BigInt{ | ||
| 5481 | .base = .{ .tag = .int_big_positive }, | ||
| 5482 | .data = int.limbs[split..], | ||
| 5483 | }; | ||
| 5484 | const upper_val = Value.initPayload(&upper_pl.base); | ||
| 5485 | try formatIntLiteral(.{ | ||
| 5486 | .ty = switch (int_info.signedness) { | ||
| 5487 | .unsigned => Type.u64, | ||
| 5488 | .signed => Type.i64, | ||
| 5489 | }, | ||
| 5490 | .val = upper_val, | ||
| 5491 | .mod = data.mod, | ||
| 5492 | }, fmt, options, writer); | ||
| 5493 | |||
| 5494 | try writer.writeAll(", "); | ||
| 5495 | |||
| 5496 | var lower_pl = Value.Payload.BigInt{ | ||
| 5497 | .base = .{ .tag = .int_big_positive }, | ||
| 5498 | .data = int.limbs[0..split], | ||
| 5499 | }; | ||
| 5500 | const lower_val = Value.initPayload(&lower_pl.base); | ||
| 5501 | try formatIntLiteral(.{ | ||
| 5502 | .ty = Type.u64, | ||
| 5503 | .val = lower_val, | ||
| 5504 | .mod = data.mod, | ||
| 5505 | }, fmt, options, writer); | ||
| 5506 | |||
| 5507 | return writer.writeByte(')'); | ||
| 5508 | } | ||
| 5509 | |||
| 5510 | switch (data.ty.tag()) { | ||
| 5511 | .c_short, .c_ushort, .c_int => {}, | ||
| 5512 | .c_uint => try writer.writeAll("u"), | ||
| 5513 | .c_long => try writer.writeAll("l"), | ||
| 5514 | .c_ulong => try writer.writeAll("ul"), | ||
| 5515 | .c_longlong => try writer.writeAll("ll"), | ||
| 5516 | .c_ulonglong => try writer.writeAll("ull"), | ||
| 5517 | else => try writer.writeByte(')'), | ||
| 4346 | } | 5518 | } |
| 4347 | return false; | ||
| 4348 | } | 5519 | } |
| 4349 | 5520 | ||
| 4350 | fn isByRef(ty: Type) bool { | 5521 | fn isByRef(ty: Type) bool { |
| 4351 | _ = ty; | 5522 | _ = ty; |
| 4352 | return false; | 5523 | return false; |
| 4353 | } | 5524 | } |
| 5525 | |||
| 5526 | const LowerFnRetTyBuffer = struct { | ||
| 5527 | const names = [1][]const u8{"array"}; | ||
| 5528 | types: [1]Type, | ||
| 5529 | values: [1]Value, | ||
| 5530 | payload: Type.Payload.AnonStruct, | ||
| 5531 | }; | ||
| 5532 | fn lowerFnRetTy(ret_ty: Type, buffer: *LowerFnRetTyBuffer, target: std.Target) Type { | ||
| 5533 | if (ret_ty.zigTypeTag() == .NoReturn) return Type.initTag(.noreturn); | ||
| 5534 | |||
| 5535 | if (lowersToArray(ret_ty, target)) { | ||
| 5536 | buffer.types = [1]Type{ret_ty}; | ||
| 5537 | buffer.values = [1]Value{Value.initTag(.unreachable_value)}; | ||
| 5538 | buffer.payload = .{ .data = .{ | ||
| 5539 | .names = &LowerFnRetTyBuffer.names, | ||
| 5540 | .types = &buffer.types, | ||
| 5541 | .values = &buffer.values, | ||
| 5542 | } }; | ||
| 5543 | return Type.initPayload(&buffer.payload.base); | ||
| 5544 | } | ||
| 5545 | |||
| 5546 | return if (ret_ty.hasRuntimeBitsIgnoreComptime()) ret_ty else Type.void; | ||
| 5547 | } | ||
| 5548 | |||
| 5549 | fn lowersToArray(ty: Type, target: std.Target) bool { | ||
| 5550 | return switch (ty.zigTypeTag()) { | ||
| 5551 | .Array => return true, | ||
| 5552 | else => return ty.isAbiInt() and toCIntBits(@intCast(u32, ty.bitSize(target))) == null, | ||
| 5553 | }; | ||
| 5554 | } | ||
| 5555 | |||
| 5556 | fn loweredArrayInfo(ty: Type, target: std.Target) ?Type.ArrayInfo { | ||
| 5557 | if (!lowersToArray(ty, target)) return null; | ||
| 5558 | |||
| 5559 | switch (ty.zigTypeTag()) { | ||
| 5560 | .Array => return ty.arrayInfo(), | ||
| 5561 | else => { | ||
| 5562 | const abi_size = ty.abiSize(target); | ||
| 5563 | const abi_align = ty.abiAlignment(target); | ||
| 5564 | return Type.ArrayInfo{ | ||
| 5565 | .elem_type = switch (abi_align) { | ||
| 5566 | 1 => Type.u8, | ||
| 5567 | 2 => Type.u16, | ||
| 5568 | 4 => Type.u32, | ||
| 5569 | 8 => Type.u64, | ||
| 5570 | 16 => Type.initTag(.u128), | ||
| 5571 | else => unreachable, | ||
| 5572 | }, | ||
| 5573 | .len = @divExact(abi_size, abi_align), | ||
| 5574 | }; | ||
| 5575 | }, | ||
| 5576 | } | ||
| 5577 | } |
src/link/C.zig+114-101| ... | @@ -108,10 +108,8 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes | ... | @@ -108,10 +108,8 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes |
| 108 | const typedefs = &gop.value_ptr.typedefs; | 108 | const typedefs = &gop.value_ptr.typedefs; |
| 109 | const code = &gop.value_ptr.code; | 109 | const code = &gop.value_ptr.code; |
| 110 | fwd_decl.shrinkRetainingCapacity(0); | 110 | fwd_decl.shrinkRetainingCapacity(0); |
| 111 | { | 111 | for (typedefs.values()) |typedef| { |
| 112 | for (typedefs.values()) |value| { | 112 | module.gpa.free(typedef.rendered); |
| 113 | module.gpa.free(value.rendered); | ||
| 114 | } | ||
| 115 | } | 113 | } |
| 116 | typedefs.clearRetainingCapacity(); | 114 | typedefs.clearRetainingCapacity(); |
| 117 | code.shrinkRetainingCapacity(0); | 115 | code.shrinkRetainingCapacity(0); |
| ... | @@ -139,14 +137,14 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes | ... | @@ -139,14 +137,14 @@ pub fn updateFunc(self: *C, module: *Module, func: *Module.Fn, air: Air, livenes |
| 139 | 137 | ||
| 140 | function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() }; | 138 | function.object.indent_writer = .{ .underlying_writer = function.object.code.writer() }; |
| 141 | defer { | 139 | defer { |
| 142 | function.value_map.deinit(); | ||
| 143 | function.blocks.deinit(module.gpa); | 140 | function.blocks.deinit(module.gpa); |
| 141 | function.value_map.deinit(); | ||
| 144 | function.object.code.deinit(); | 142 | function.object.code.deinit(); |
| 145 | function.object.dg.fwd_decl.deinit(); | 143 | for (function.object.dg.typedefs.values()) |typedef| { |
| 146 | for (function.object.dg.typedefs.values()) |value| { | 144 | module.gpa.free(typedef.rendered); |
| 147 | module.gpa.free(value.rendered); | ||
| 148 | } | 145 | } |
| 149 | function.object.dg.typedefs.deinit(); | 146 | function.object.dg.typedefs.deinit(); |
| 147 | function.object.dg.fwd_decl.deinit(); | ||
| 150 | } | 148 | } |
| 151 | 149 | ||
| 152 | codegen.genFunc(&function) catch |err| switch (err) { | 150 | codegen.genFunc(&function) catch |err| switch (err) { |
| ... | @@ -179,10 +177,8 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi | ... | @@ -179,10 +177,8 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi |
| 179 | const typedefs = &gop.value_ptr.typedefs; | 177 | const typedefs = &gop.value_ptr.typedefs; |
| 180 | const code = &gop.value_ptr.code; | 178 | const code = &gop.value_ptr.code; |
| 181 | fwd_decl.shrinkRetainingCapacity(0); | 179 | fwd_decl.shrinkRetainingCapacity(0); |
| 182 | { | 180 | for (typedefs.values()) |value| { |
| 183 | for (typedefs.values()) |value| { | 181 | module.gpa.free(value.rendered); |
| 184 | module.gpa.free(value.rendered); | ||
| 185 | } | ||
| 186 | } | 182 | } |
| 187 | typedefs.clearRetainingCapacity(); | 183 | typedefs.clearRetainingCapacity(); |
| 188 | code.shrinkRetainingCapacity(0); | 184 | code.shrinkRetainingCapacity(0); |
| ... | @@ -206,11 +202,11 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi | ... | @@ -206,11 +202,11 @@ pub fn updateDecl(self: *C, module: *Module, decl_index: Module.Decl.Index) !voi |
| 206 | object.indent_writer = .{ .underlying_writer = object.code.writer() }; | 202 | object.indent_writer = .{ .underlying_writer = object.code.writer() }; |
| 207 | defer { | 203 | defer { |
| 208 | object.code.deinit(); | 204 | object.code.deinit(); |
| 209 | object.dg.fwd_decl.deinit(); | 205 | for (object.dg.typedefs.values()) |typedef| { |
| 210 | for (object.dg.typedefs.values()) |value| { | 206 | module.gpa.free(typedef.rendered); |
| 211 | module.gpa.free(value.rendered); | ||
| 212 | } | 207 | } |
| 213 | object.dg.typedefs.deinit(); | 208 | object.dg.typedefs.deinit(); |
| 209 | object.dg.fwd_decl.deinit(); | ||
| 214 | } | 210 | } |
| 215 | 211 | ||
| 216 | codegen.genDecl(&object) catch |err| switch (err) { | 212 | codegen.genDecl(&object) catch |err| switch (err) { |
| ... | @@ -260,30 +256,26 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) | ... | @@ -260,30 +256,26 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) |
| 260 | var f: Flush = .{}; | 256 | var f: Flush = .{}; |
| 261 | defer f.deinit(gpa); | 257 | defer f.deinit(gpa); |
| 262 | 258 | ||
| 263 | // Covers zig.h and err_typedef_item. | 259 | // Covers zig.h, typedef, and asm. |
| 264 | try f.all_buffers.ensureUnusedCapacity(gpa, 2); | 260 | try f.all_buffers.ensureUnusedCapacity(gpa, 2); |
| 265 | 261 | ||
| 266 | if (zig_h.len != 0) { | 262 | f.appendBufAssumeCapacity(zig_h); |
| 267 | f.all_buffers.appendAssumeCapacity(.{ | ||
| 268 | .iov_base = zig_h, | ||
| 269 | .iov_len = zig_h.len, | ||
| 270 | }); | ||
| 271 | f.file_size += zig_h.len; | ||
| 272 | } | ||
| 273 | 263 | ||
| 274 | const err_typedef_writer = f.err_typedef_buf.writer(gpa); | 264 | const typedef_index = f.all_buffers.items.len; |
| 275 | const err_typedef_index = f.all_buffers.items.len; | ||
| 276 | f.all_buffers.items.len += 1; | 265 | f.all_buffers.items.len += 1; |
| 277 | 266 | ||
| 278 | render_errors: { | 267 | { |
| 279 | if (module.global_error_set.size == 0) break :render_errors; | 268 | var asm_buf = f.asm_buf.toManaged(module.gpa); |
| 280 | var it = module.global_error_set.iterator(); | 269 | defer asm_buf.deinit(); |
| 281 | while (it.next()) |entry| { | 270 | |
| 282 | try err_typedef_writer.print("#define zig_error_{s} {d}\n", .{ entry.key_ptr.*, entry.value_ptr.* }); | 271 | try codegen.genGlobalAsm(module, &asm_buf); |
| 283 | } | 272 | |
| 284 | try err_typedef_writer.writeByte('\n'); | 273 | f.asm_buf = asm_buf.moveToUnmanaged(); |
| 274 | f.appendBufAssumeCapacity(f.asm_buf.items); | ||
| 285 | } | 275 | } |
| 286 | 276 | ||
| 277 | try self.flushErrDecls(&f); | ||
| 278 | |||
| 287 | // Typedefs, forward decls, and non-functions first. | 279 | // Typedefs, forward decls, and non-functions first. |
| 288 | // Unlike other backends, the .c code we are emitting is order-dependent. Therefore | 280 | // Unlike other backends, the .c code we are emitting is order-dependent. Therefore |
| 289 | // we must traverse the set of Decls that we are emitting according to their dependencies. | 281 | // we must traverse the set of Decls that we are emitting according to their dependencies. |
| ... | @@ -300,38 +292,19 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) | ... | @@ -300,38 +292,19 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) |
| 300 | 292 | ||
| 301 | while (f.remaining_decls.popOrNull()) |kv| { | 293 | while (f.remaining_decls.popOrNull()) |kv| { |
| 302 | const decl_index = kv.key; | 294 | const decl_index = kv.key; |
| 303 | try flushDecl(self, &f, decl_index); | 295 | try self.flushDecl(&f, decl_index); |
| 304 | } | 296 | } |
| 305 | 297 | ||
| 306 | if (f.err_typedef_buf.items.len == 0) { | 298 | f.all_buffers.items[typedef_index] = .{ |
| 307 | f.all_buffers.items[err_typedef_index] = .{ | 299 | .iov_base = if (f.typedef_buf.items.len > 0) f.typedef_buf.items.ptr else "", |
| 308 | .iov_base = "", | 300 | .iov_len = f.typedef_buf.items.len, |
| 309 | .iov_len = 0, | 301 | }; |
| 310 | }; | 302 | f.file_size += f.typedef_buf.items.len; |
| 311 | } else { | ||
| 312 | f.all_buffers.items[err_typedef_index] = .{ | ||
| 313 | .iov_base = f.err_typedef_buf.items.ptr, | ||
| 314 | .iov_len = f.err_typedef_buf.items.len, | ||
| 315 | }; | ||
| 316 | f.file_size += f.err_typedef_buf.items.len; | ||
| 317 | } | ||
| 318 | 303 | ||
| 319 | // Now the function bodies. | 304 | // Now the code. |
| 320 | try f.all_buffers.ensureUnusedCapacity(gpa, f.fn_count); | 305 | try f.all_buffers.ensureUnusedCapacity(gpa, decl_values.len); |
| 321 | for (decl_keys) |decl_index, i| { | 306 | for (decl_values) |decl| |
| 322 | const decl = module.declPtr(decl_index); | 307 | f.appendBufAssumeCapacity(decl.code.items); |
| 323 | if (decl.getFunction() != null) { | ||
| 324 | const decl_block = &decl_values[i]; | ||
| 325 | const buf = decl_block.code.items; | ||
| 326 | if (buf.len != 0) { | ||
| 327 | f.all_buffers.appendAssumeCapacity(.{ | ||
| 328 | .iov_base = buf.ptr, | ||
| 329 | .iov_len = buf.len, | ||
| 330 | }); | ||
| 331 | f.file_size += buf.len; | ||
| 332 | } | ||
| 333 | } | ||
| 334 | } | ||
| 335 | 308 | ||
| 336 | const file = self.base.file.?; | 309 | const file = self.base.file.?; |
| 337 | try file.setEndPos(f.file_size); | 310 | try file.setEndPos(f.file_size); |
| ... | @@ -339,14 +312,15 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) | ... | @@ -339,14 +312,15 @@ pub fn flushModule(self: *C, comp: *Compilation, prog_node: *std.Progress.Node) |
| 339 | } | 312 | } |
| 340 | 313 | ||
| 341 | const Flush = struct { | 314 | const Flush = struct { |
| 315 | err_decls: DeclBlock = .{}, | ||
| 342 | remaining_decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, void) = .{}, | 316 | remaining_decls: std.AutoArrayHashMapUnmanaged(Module.Decl.Index, void) = .{}, |
| 343 | typedefs: Typedefs = .{}, | 317 | typedefs: Typedefs = .{}, |
| 344 | err_typedef_buf: std.ArrayListUnmanaged(u8) = .{}, | 318 | typedef_buf: std.ArrayListUnmanaged(u8) = .{}, |
| 319 | asm_buf: std.ArrayListUnmanaged(u8) = .{}, | ||
| 345 | /// We collect a list of buffers to write, and write them all at once with pwritev 😎 | 320 | /// We collect a list of buffers to write, and write them all at once with pwritev 😎 |
| 346 | all_buffers: std.ArrayListUnmanaged(std.os.iovec_const) = .{}, | 321 | all_buffers: std.ArrayListUnmanaged(std.os.iovec_const) = .{}, |
| 347 | /// Keeps track of the total bytes of `all_buffers`. | 322 | /// Keeps track of the total bytes of `all_buffers`. |
| 348 | file_size: u64 = 0, | 323 | file_size: u64 = 0, |
| 349 | fn_count: usize = 0, | ||
| 350 | 324 | ||
| 351 | const Typedefs = std.HashMapUnmanaged( | 325 | const Typedefs = std.HashMapUnmanaged( |
| 352 | Type, | 326 | Type, |
| ... | @@ -355,11 +329,18 @@ const Flush = struct { | ... | @@ -355,11 +329,18 @@ const Flush = struct { |
| 355 | std.hash_map.default_max_load_percentage, | 329 | std.hash_map.default_max_load_percentage, |
| 356 | ); | 330 | ); |
| 357 | 331 | ||
| 332 | fn appendBufAssumeCapacity(f: *Flush, buf: []const u8) void { | ||
| 333 | if (buf.len == 0) return; | ||
| 334 | f.all_buffers.appendAssumeCapacity(.{ .iov_base = buf.ptr, .iov_len = buf.len }); | ||
| 335 | f.file_size += buf.len; | ||
| 336 | } | ||
| 337 | |||
| 358 | fn deinit(f: *Flush, gpa: Allocator) void { | 338 | fn deinit(f: *Flush, gpa: Allocator) void { |
| 359 | f.all_buffers.deinit(gpa); | 339 | f.all_buffers.deinit(gpa); |
| 360 | f.err_typedef_buf.deinit(gpa); | 340 | f.typedef_buf.deinit(gpa); |
| 361 | f.typedefs.deinit(gpa); | 341 | f.typedefs.deinit(gpa); |
| 362 | f.remaining_decls.deinit(gpa); | 342 | f.remaining_decls.deinit(gpa); |
| 343 | f.err_decls.deinit(gpa); | ||
| 363 | } | 344 | } |
| 364 | }; | 345 | }; |
| 365 | 346 | ||
| ... | @@ -367,6 +348,72 @@ const FlushDeclError = error{ | ... | @@ -367,6 +348,72 @@ const FlushDeclError = error{ |
| 367 | OutOfMemory, | 348 | OutOfMemory, |
| 368 | }; | 349 | }; |
| 369 | 350 | ||
| 351 | fn flushTypedefs(self: *C, f: *Flush, typedefs: codegen.TypedefMap.Unmanaged) FlushDeclError!void { | ||
| 352 | if (typedefs.count() == 0) return; | ||
| 353 | const gpa = self.base.allocator; | ||
| 354 | const module = self.base.options.module.?; | ||
| 355 | |||
| 356 | try f.typedefs.ensureUnusedCapacityContext(gpa, @intCast(u32, typedefs.count()), .{ | ||
| 357 | .mod = module, | ||
| 358 | }); | ||
| 359 | var it = typedefs.iterator(); | ||
| 360 | while (it.next()) |new| { | ||
| 361 | const gop = f.typedefs.getOrPutAssumeCapacityContext(new.key_ptr.*, .{ | ||
| 362 | .mod = module, | ||
| 363 | }); | ||
| 364 | if (!gop.found_existing) { | ||
| 365 | try f.typedef_buf.appendSlice(gpa, new.value_ptr.rendered); | ||
| 366 | } | ||
| 367 | } | ||
| 368 | } | ||
| 369 | |||
| 370 | fn flushErrDecls(self: *C, f: *Flush) FlushDeclError!void { | ||
| 371 | const module = self.base.options.module.?; | ||
| 372 | |||
| 373 | const fwd_decl = &f.err_decls.fwd_decl; | ||
| 374 | const typedefs = &f.err_decls.typedefs; | ||
| 375 | const code = &f.err_decls.code; | ||
| 376 | |||
| 377 | var object = codegen.Object{ | ||
| 378 | .dg = .{ | ||
| 379 | .gpa = module.gpa, | ||
| 380 | .module = module, | ||
| 381 | .error_msg = null, | ||
| 382 | .decl_index = undefined, | ||
| 383 | .decl = undefined, | ||
| 384 | .fwd_decl = fwd_decl.toManaged(module.gpa), | ||
| 385 | .typedefs = typedefs.promoteContext(module.gpa, .{ .mod = module }), | ||
| 386 | .typedefs_arena = self.arena.allocator(), | ||
| 387 | }, | ||
| 388 | .code = code.toManaged(module.gpa), | ||
| 389 | .indent_writer = undefined, // set later so we can get a pointer to object.code | ||
| 390 | }; | ||
| 391 | object.indent_writer = .{ .underlying_writer = object.code.writer() }; | ||
| 392 | defer { | ||
| 393 | object.code.deinit(); | ||
| 394 | for (object.dg.typedefs.values()) |typedef| { | ||
| 395 | module.gpa.free(typedef.rendered); | ||
| 396 | } | ||
| 397 | object.dg.typedefs.deinit(); | ||
| 398 | object.dg.fwd_decl.deinit(); | ||
| 399 | } | ||
| 400 | |||
| 401 | codegen.genErrDecls(&object) catch |err| switch (err) { | ||
| 402 | error.AnalysisFail => unreachable, | ||
| 403 | else => |e| return e, | ||
| 404 | }; | ||
| 405 | |||
| 406 | fwd_decl.* = object.dg.fwd_decl.moveToUnmanaged(); | ||
| 407 | typedefs.* = object.dg.typedefs.unmanaged; | ||
| 408 | object.dg.typedefs.unmanaged = .{}; | ||
| 409 | code.* = object.code.moveToUnmanaged(); | ||
| 410 | |||
| 411 | try self.flushTypedefs(f, typedefs.*); | ||
| 412 | try f.all_buffers.ensureUnusedCapacity(self.base.allocator, 1); | ||
| 413 | f.appendBufAssumeCapacity(fwd_decl.items); | ||
| 414 | f.appendBufAssumeCapacity(code.items); | ||
| 415 | } | ||
| 416 | |||
| 370 | /// Assumes `decl` was in the `remaining_decls` set, and has already been removed. | 417 | /// Assumes `decl` was in the `remaining_decls` set, and has already been removed. |
| 371 | fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError!void { | 418 | fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError!void { |
| 372 | const module = self.base.options.module.?; | 419 | const module = self.base.options.module.?; |
| ... | @@ -383,43 +430,9 @@ fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError! | ... | @@ -383,43 +430,9 @@ fn flushDecl(self: *C, f: *Flush, decl_index: Module.Decl.Index) FlushDeclError! |
| 383 | const decl_block = self.decl_table.getPtr(decl_index).?; | 430 | const decl_block = self.decl_table.getPtr(decl_index).?; |
| 384 | const gpa = self.base.allocator; | 431 | const gpa = self.base.allocator; |
| 385 | 432 | ||
| 386 | if (decl_block.typedefs.count() != 0) { | 433 | try self.flushTypedefs(f, decl_block.typedefs); |
| 387 | try f.typedefs.ensureUnusedCapacityContext(gpa, @intCast(u32, decl_block.typedefs.count()), .{ | 434 | try f.all_buffers.ensureUnusedCapacity(gpa, 2); |
| 388 | .mod = module, | 435 | f.appendBufAssumeCapacity(decl_block.fwd_decl.items); |
| 389 | }); | ||
| 390 | var it = decl_block.typedefs.iterator(); | ||
| 391 | while (it.next()) |new| { | ||
| 392 | const gop = f.typedefs.getOrPutAssumeCapacityContext(new.key_ptr.*, .{ | ||
| 393 | .mod = module, | ||
| 394 | }); | ||
| 395 | if (!gop.found_existing) { | ||
| 396 | try f.err_typedef_buf.appendSlice(gpa, new.value_ptr.rendered); | ||
| 397 | } | ||
| 398 | } | ||
| 399 | } | ||
| 400 | |||
| 401 | if (decl_block.fwd_decl.items.len != 0) { | ||
| 402 | const buf = decl_block.fwd_decl.items; | ||
| 403 | if (buf.len != 0) { | ||
| 404 | try f.all_buffers.append(gpa, .{ | ||
| 405 | .iov_base = buf.ptr, | ||
| 406 | .iov_len = buf.len, | ||
| 407 | }); | ||
| 408 | f.file_size += buf.len; | ||
| 409 | } | ||
| 410 | } | ||
| 411 | if (decl.getFunction() != null) { | ||
| 412 | f.fn_count += 1; | ||
| 413 | } else if (decl_block.code.items.len != 0) { | ||
| 414 | const buf = decl_block.code.items; | ||
| 415 | if (buf.len != 0) { | ||
| 416 | try f.all_buffers.append(gpa, .{ | ||
| 417 | .iov_base = buf.ptr, | ||
| 418 | .iov_len = buf.len, | ||
| 419 | }); | ||
| 420 | f.file_size += buf.len; | ||
| 421 | } | ||
| 422 | } | ||
| 423 | } | 436 | } |
| 424 | 437 | ||
| 425 | pub fn flushEmitH(module: *Module) !void { | 438 | pub fn flushEmitH(module: *Module) !void { |
src/main.zig+4-1| ... | @@ -3018,7 +3018,10 @@ fn buildOutputType( | ... | @@ -3018,7 +3018,10 @@ fn buildOutputType( |
| 3018 | const c_code_path = try fs.path.join(arena, &[_][]const u8{ | 3018 | const c_code_path = try fs.path.join(arena, &[_][]const u8{ |
| 3019 | c_code_directory.path orelse ".", c_code_loc.basename, | 3019 | c_code_directory.path orelse ".", c_code_loc.basename, |
| 3020 | }); | 3020 | }); |
| 3021 | try test_exec_args.appendSlice(&.{ self_exe_path, "run", "-lc", c_code_path }); | 3021 | try test_exec_args.append(self_exe_path); |
| 3022 | try test_exec_args.append("run"); | ||
| 3023 | if (link_libc) try test_exec_args.append("-lc"); | ||
| 3024 | try test_exec_args.append(c_code_path); | ||
| 3022 | } | 3025 | } |
| 3023 | 3026 | ||
| 3024 | const run_or_test = switch (arg_mode) { | 3027 | const run_or_test = switch (arg_mode) { |
src/test.zig+1| ... | @@ -791,6 +791,7 @@ pub const TestContext = struct { | ... | @@ -791,6 +791,7 @@ pub const TestContext = struct { |
| 791 | .updates = std.ArrayList(Update).init(ctx.cases.allocator), | 791 | .updates = std.ArrayList(Update).init(ctx.cases.allocator), |
| 792 | .output_mode = .Exe, | 792 | .output_mode = .Exe, |
| 793 | .files = std.ArrayList(File).init(ctx.arena), | 793 | .files = std.ArrayList(File).init(ctx.arena), |
| 794 | .link_libc = true, | ||
| 794 | }) catch @panic("out of memory"); | 795 | }) catch @panic("out of memory"); |
| 795 | return &ctx.cases.items[ctx.cases.items.len - 1]; | 796 | return &ctx.cases.items[ctx.cases.items.len - 1]; |
| 796 | } | 797 | } |
src/type.zig+20-6| ... | @@ -5282,7 +5282,7 @@ pub const Type = extern union { | ... | @@ -5282,7 +5282,7 @@ pub const Type = extern union { |
| 5282 | // Works for vectors and vectors of integers. | 5282 | // Works for vectors and vectors of integers. |
| 5283 | pub fn minInt(ty: Type, arena: Allocator, target: Target) !Value { | 5283 | pub fn minInt(ty: Type, arena: Allocator, target: Target) !Value { |
| 5284 | const scalar = try minIntScalar(ty.scalarType(), arena, target); | 5284 | const scalar = try minIntScalar(ty.scalarType(), arena, target); |
| 5285 | if (ty.zigTypeTag() == .Vector) { | 5285 | if (ty.zigTypeTag() == .Vector and scalar.tag() != .the_only_possible_value) { |
| 5286 | return Value.Tag.repeated.create(arena, scalar); | 5286 | return Value.Tag.repeated.create(arena, scalar); |
| 5287 | } else { | 5287 | } else { |
| 5288 | return scalar; | 5288 | return scalar; |
| ... | @@ -5294,12 +5294,16 @@ pub const Type = extern union { | ... | @@ -5294,12 +5294,16 @@ pub const Type = extern union { |
| 5294 | assert(ty.zigTypeTag() == .Int); | 5294 | assert(ty.zigTypeTag() == .Int); |
| 5295 | const info = ty.intInfo(target); | 5295 | const info = ty.intInfo(target); |
| 5296 | 5296 | ||
| 5297 | if (info.bits == 0) { | ||
| 5298 | return Value.initTag(.the_only_possible_value); | ||
| 5299 | } | ||
| 5300 | |||
| 5297 | if (info.signedness == .unsigned) { | 5301 | if (info.signedness == .unsigned) { |
| 5298 | return Value.zero; | 5302 | return Value.zero; |
| 5299 | } | 5303 | } |
| 5300 | 5304 | ||
| 5301 | if (info.bits <= 6) { | 5305 | if (std.math.cast(u6, info.bits - 1)) |shift| { |
| 5302 | const n: i64 = -(@as(i64, 1) << @truncate(u6, info.bits - 1)); | 5306 | const n = @as(i64, std.math.minInt(i64)) >> (63 - shift); |
| 5303 | return Value.Tag.int_i64.create(arena, n); | 5307 | return Value.Tag.int_i64.create(arena, n); |
| 5304 | } | 5308 | } |
| 5305 | 5309 | ||
| ... | @@ -5319,13 +5323,23 @@ pub const Type = extern union { | ... | @@ -5319,13 +5323,23 @@ pub const Type = extern union { |
| 5319 | assert(self.zigTypeTag() == .Int); | 5323 | assert(self.zigTypeTag() == .Int); |
| 5320 | const info = self.intInfo(target); | 5324 | const info = self.intInfo(target); |
| 5321 | 5325 | ||
| 5322 | if (info.bits <= 6) switch (info.signedness) { | 5326 | if (info.bits == 0) { |
| 5327 | return Value.initTag(.the_only_possible_value); | ||
| 5328 | } | ||
| 5329 | |||
| 5330 | switch (info.bits - @boolToInt(info.signedness == .signed)) { | ||
| 5331 | 0 => return Value.zero, | ||
| 5332 | 1 => return Value.one, | ||
| 5333 | else => {}, | ||
| 5334 | } | ||
| 5335 | |||
| 5336 | if (std.math.cast(u6, info.bits - 1)) |shift| switch (info.signedness) { | ||
| 5323 | .signed => { | 5337 | .signed => { |
| 5324 | const n: i64 = (@as(i64, 1) << @truncate(u6, info.bits - 1)) - 1; | 5338 | const n = @as(i64, std.math.maxInt(i64)) >> (63 - shift); |
| 5325 | return Value.Tag.int_i64.create(arena, n); | 5339 | return Value.Tag.int_i64.create(arena, n); |
| 5326 | }, | 5340 | }, |
| 5327 | .unsigned => { | 5341 | .unsigned => { |
| 5328 | const n: u64 = (@as(u64, 1) << @truncate(u6, info.bits)) - 1; | 5342 | const n = @as(u64, std.math.maxInt(u64)) >> (63 - shift); |
| 5329 | return Value.Tag.int_u64.create(arena, n); | 5343 | return Value.Tag.int_u64.create(arena, n); |
| 5330 | }, | 5344 | }, |
| 5331 | }; | 5345 | }; |
test/behavior.zig+1-7| ... | @@ -213,13 +213,7 @@ test { | ... | @@ -213,13 +213,7 @@ test { |
| 213 | _ = @import("behavior/export.zig"); | 213 | _ = @import("behavior/export.zig"); |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | if (builtin.zig_backend != .stage2_arm and | 216 | if (builtin.zig_backend != .stage2_wasm) { |
| 217 | builtin.zig_backend != .stage2_x86_64 and | ||
| 218 | builtin.zig_backend != .stage2_aarch64 and | ||
| 219 | builtin.zig_backend != .stage2_wasm and | ||
| 220 | builtin.zig_backend != .stage2_c and | ||
| 221 | builtin.zig_backend != .stage1) | ||
| 222 | { | ||
| 223 | _ = @import("behavior/export_self_referential_type_info.zig"); | 217 | _ = @import("behavior/export_self_referential_type_info.zig"); |
| 224 | } | 218 | } |
| 225 | } | 219 | } |
test/behavior/align.zig-12| ... | @@ -7,8 +7,6 @@ const assert = std.debug.assert; | ... | @@ -7,8 +7,6 @@ const assert = std.debug.assert; |
| 7 | var foo: u8 align(4) = 100; | 7 | var foo: u8 align(4) = 100; |
| 8 | 8 | ||
| 9 | test "global variable alignment" { | 9 | test "global variable alignment" { |
| 10 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 11 | |||
| 12 | comptime try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4); | 10 | comptime try expect(@typeInfo(@TypeOf(&foo)).Pointer.alignment == 4); |
| 13 | comptime try expect(@TypeOf(&foo) == *align(4) u8); | 11 | comptime try expect(@TypeOf(&foo) == *align(4) u8); |
| 14 | { | 12 | { |
| ... | @@ -223,7 +221,6 @@ fn fnWithAlignedStack() i32 { | ... | @@ -223,7 +221,6 @@ fn fnWithAlignedStack() i32 { |
| 223 | } | 221 | } |
| 224 | 222 | ||
| 225 | test "implicitly decreasing slice alignment" { | 223 | test "implicitly decreasing slice alignment" { |
| 226 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 227 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 224 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 228 | 225 | ||
| 229 | const a: u32 align(4) = 3; | 226 | const a: u32 align(4) = 3; |
| ... | @@ -235,7 +232,6 @@ fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { | ... | @@ -235,7 +232,6 @@ fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { |
| 235 | } | 232 | } |
| 236 | 233 | ||
| 237 | test "specifying alignment allows pointer cast" { | 234 | test "specifying alignment allows pointer cast" { |
| 238 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 239 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 235 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 240 | 236 | ||
| 241 | try testBytesAlign(0x33); | 237 | try testBytesAlign(0x33); |
| ... | @@ -247,7 +243,6 @@ fn testBytesAlign(b: u8) !void { | ... | @@ -247,7 +243,6 @@ fn testBytesAlign(b: u8) !void { |
| 247 | } | 243 | } |
| 248 | 244 | ||
| 249 | test "@alignCast slices" { | 245 | test "@alignCast slices" { |
| 250 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 251 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 246 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 252 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 247 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 253 | 248 | ||
| ... | @@ -301,7 +296,6 @@ fn noop4() align(4) void {} | ... | @@ -301,7 +296,6 @@ fn noop4() align(4) void {} |
| 301 | 296 | ||
| 302 | test "function alignment" { | 297 | test "function alignment" { |
| 303 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 298 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 304 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 305 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 299 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 306 | 300 | ||
| 307 | // function alignment is a compile error on wasm32/wasm64 | 301 | // function alignment is a compile error on wasm32/wasm64 |
| ... | @@ -316,7 +310,6 @@ test "function alignment" { | ... | @@ -316,7 +310,6 @@ test "function alignment" { |
| 316 | 310 | ||
| 317 | test "implicitly decreasing fn alignment" { | 311 | test "implicitly decreasing fn alignment" { |
| 318 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 312 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 319 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 320 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 313 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 321 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 314 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 322 | 315 | ||
| ... | @@ -341,7 +334,6 @@ fn alignedBig() align(16) i32 { | ... | @@ -341,7 +334,6 @@ fn alignedBig() align(16) i32 { |
| 341 | test "@alignCast functions" { | 334 | test "@alignCast functions" { |
| 342 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 335 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 343 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 336 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 344 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 345 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 337 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 346 | 338 | ||
| 347 | // function alignment is a compile error on wasm32/wasm64 | 339 | // function alignment is a compile error on wasm32/wasm64 |
| ... | @@ -401,8 +393,6 @@ test "function callconv expression depends on generic parameter" { | ... | @@ -401,8 +393,6 @@ test "function callconv expression depends on generic parameter" { |
| 401 | } | 393 | } |
| 402 | 394 | ||
| 403 | test "runtime-known array index has best alignment possible" { | 395 | test "runtime-known array index has best alignment possible" { |
| 404 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 405 | |||
| 406 | // take full advantage of over-alignment | 396 | // take full advantage of over-alignment |
| 407 | var array align(4) = [_]u8{ 1, 2, 3, 4 }; | 397 | var array align(4) = [_]u8{ 1, 2, 3, 4 }; |
| 408 | comptime assert(@TypeOf(&array[0]) == *align(4) u8); | 398 | comptime assert(@TypeOf(&array[0]) == *align(4) u8); |
| ... | @@ -482,7 +472,6 @@ test "read 128-bit field from default aligned struct in global memory" { | ... | @@ -482,7 +472,6 @@ test "read 128-bit field from default aligned struct in global memory" { |
| 482 | } | 472 | } |
| 483 | 473 | ||
| 484 | test "struct field explicit alignment" { | 474 | test "struct field explicit alignment" { |
| 485 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 486 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 475 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 487 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 476 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 488 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 477 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| ... | @@ -546,7 +535,6 @@ test "comptime alloc alignment" { | ... | @@ -546,7 +535,6 @@ test "comptime alloc alignment" { |
| 546 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 535 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 547 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 536 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 548 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 537 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 549 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 550 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 538 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 551 | 539 | ||
| 552 | comptime var bytes1 = [_]u8{0}; | 540 | comptime var bytes1 = [_]u8{0}; |
test/behavior/alignof.zig-2| ... | @@ -12,7 +12,6 @@ const Foo = struct { | ... | @@ -12,7 +12,6 @@ const Foo = struct { |
| 12 | 12 | ||
| 13 | test "@alignOf(T) before referencing T" { | 13 | test "@alignOf(T) before referencing T" { |
| 14 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 14 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 15 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 16 | comptime try expect(@alignOf(Foo) != maxInt(usize)); | 15 | comptime try expect(@alignOf(Foo) != maxInt(usize)); |
| 17 | if (native_arch == .x86_64) { | 16 | if (native_arch == .x86_64) { |
| 18 | comptime try expect(@alignOf(Foo) == 4); | 17 | comptime try expect(@alignOf(Foo) == 4); |
| ... | @@ -20,7 +19,6 @@ test "@alignOf(T) before referencing T" { | ... | @@ -20,7 +19,6 @@ test "@alignOf(T) before referencing T" { |
| 20 | } | 19 | } |
| 21 | 20 | ||
| 22 | test "comparison of @alignOf(T) against zero" { | 21 | test "comparison of @alignOf(T) against zero" { |
| 23 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 24 | { | 22 | { |
| 25 | const T = struct { x: u32 }; | 23 | const T = struct { x: u32 }; |
| 26 | try expect(!(@alignOf(T) == 0)); | 24 | try expect(!(@alignOf(T) == 0)); |
test/behavior/array.zig-6| ... | @@ -6,8 +6,6 @@ const expect = testing.expect; | ... | @@ -6,8 +6,6 @@ const expect = testing.expect; |
| 6 | const expectEqual = testing.expectEqual; | 6 | const expectEqual = testing.expectEqual; |
| 7 | 7 | ||
| 8 | test "array to slice" { | 8 | test "array to slice" { |
| 9 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 10 | |||
| 11 | const a: u32 align(4) = 3; | 9 | const a: u32 align(4) = 3; |
| 12 | const b: u32 align(8) = 4; | 10 | const b: u32 align(8) = 4; |
| 13 | const a_slice: []align(1) const u32 = @as(*const [1]u32, &a)[0..]; | 11 | const a_slice: []align(1) const u32 = @as(*const [1]u32, &a)[0..]; |
| ... | @@ -160,7 +158,6 @@ test "nested arrays of strings" { | ... | @@ -160,7 +158,6 @@ test "nested arrays of strings" { |
| 160 | 158 | ||
| 161 | test "nested arrays of integers" { | 159 | test "nested arrays of integers" { |
| 162 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 160 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 163 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 164 | 161 | ||
| 165 | const array_of_numbers = [_][2]u8{ | 162 | const array_of_numbers = [_][2]u8{ |
| 166 | [2]u8{ 1, 2 }, | 163 | [2]u8{ 1, 2 }, |
| ... | @@ -479,7 +476,6 @@ test "sentinel element count towards the ABI size calculation" { | ... | @@ -479,7 +476,6 @@ test "sentinel element count towards the ABI size calculation" { |
| 479 | 476 | ||
| 480 | test "zero-sized array with recursive type definition" { | 477 | test "zero-sized array with recursive type definition" { |
| 481 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 478 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 482 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 483 | 479 | ||
| 484 | const U = struct { | 480 | const U = struct { |
| 485 | fn foo(comptime T: type, comptime n: usize) type { | 481 | fn foo(comptime T: type, comptime n: usize) type { |
| ... | @@ -501,7 +497,6 @@ test "zero-sized array with recursive type definition" { | ... | @@ -501,7 +497,6 @@ test "zero-sized array with recursive type definition" { |
| 501 | test "type coercion of anon struct literal to array" { | 497 | test "type coercion of anon struct literal to array" { |
| 502 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 498 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 503 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 499 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 504 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 505 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 500 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 506 | 501 | ||
| 507 | const S = struct { | 502 | const S = struct { |
| ... | @@ -532,7 +527,6 @@ test "type coercion of anon struct literal to array" { | ... | @@ -532,7 +527,6 @@ test "type coercion of anon struct literal to array" { |
| 532 | } | 527 | } |
| 533 | 528 | ||
| 534 | test "type coercion of pointer to anon struct literal to pointer to array" { | 529 | test "type coercion of pointer to anon struct literal to pointer to array" { |
| 535 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 536 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 530 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 537 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 531 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 538 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 532 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
test/behavior/asm.zig-4| ... | @@ -18,7 +18,6 @@ comptime { | ... | @@ -18,7 +18,6 @@ comptime { |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | test "module level assembly" { | 20 | test "module level assembly" { |
| 21 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 22 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 21 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 23 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 22 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 24 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 23 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -30,7 +29,6 @@ test "module level assembly" { | ... | @@ -30,7 +29,6 @@ test "module level assembly" { |
| 30 | } | 29 | } |
| 31 | 30 | ||
| 32 | test "output constraint modifiers" { | 31 | test "output constraint modifiers" { |
| 33 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 34 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 32 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 35 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 33 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 36 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 34 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -51,7 +49,6 @@ test "output constraint modifiers" { | ... | @@ -51,7 +49,6 @@ test "output constraint modifiers" { |
| 51 | } | 49 | } |
| 52 | 50 | ||
| 53 | test "alternative constraints" { | 51 | test "alternative constraints" { |
| 54 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 55 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 52 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 56 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 53 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 57 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 54 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -115,7 +112,6 @@ test "sized integer/float in asm input" { | ... | @@ -115,7 +112,6 @@ test "sized integer/float in asm input" { |
| 115 | } | 112 | } |
| 116 | 113 | ||
| 117 | test "struct/array/union types as input values" { | 114 | test "struct/array/union types as input values" { |
| 118 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 119 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 115 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 120 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 116 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 121 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 117 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
test/behavior/atomics.zig-14| ... | @@ -4,7 +4,6 @@ const expect = std.testing.expect; | ... | @@ -4,7 +4,6 @@ const expect = std.testing.expect; |
| 4 | const expectEqual = std.testing.expectEqual; | 4 | const expectEqual = std.testing.expectEqual; |
| 5 | 5 | ||
| 6 | test "cmpxchg" { | 6 | test "cmpxchg" { |
| 7 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 8 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 7 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 9 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 8 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 10 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -33,7 +32,6 @@ fn testCmpxchg() !void { | ... | @@ -33,7 +32,6 @@ fn testCmpxchg() !void { |
| 33 | } | 32 | } |
| 34 | 33 | ||
| 35 | test "fence" { | 34 | test "fence" { |
| 36 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 37 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 35 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 38 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 36 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 39 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 37 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -45,7 +43,6 @@ test "fence" { | ... | @@ -45,7 +43,6 @@ test "fence" { |
| 45 | } | 43 | } |
| 46 | 44 | ||
| 47 | test "atomicrmw and atomicload" { | 45 | test "atomicrmw and atomicload" { |
| 48 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 49 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 46 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 50 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 47 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 51 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 48 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -75,7 +72,6 @@ fn testAtomicLoad(ptr: *u8) !void { | ... | @@ -75,7 +72,6 @@ fn testAtomicLoad(ptr: *u8) !void { |
| 75 | } | 72 | } |
| 76 | 73 | ||
| 77 | test "cmpxchg with ptr" { | 74 | test "cmpxchg with ptr" { |
| 78 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 79 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 75 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 80 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 76 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 81 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 77 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -102,7 +98,6 @@ test "cmpxchg with ptr" { | ... | @@ -102,7 +98,6 @@ test "cmpxchg with ptr" { |
| 102 | } | 98 | } |
| 103 | 99 | ||
| 104 | test "cmpxchg with ignored result" { | 100 | test "cmpxchg with ignored result" { |
| 105 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 106 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 101 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 107 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 102 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 108 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 103 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -117,7 +112,6 @@ test "cmpxchg with ignored result" { | ... | @@ -117,7 +112,6 @@ test "cmpxchg with ignored result" { |
| 117 | } | 112 | } |
| 118 | 113 | ||
| 119 | test "128-bit cmpxchg" { | 114 | test "128-bit cmpxchg" { |
| 120 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 121 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 115 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 122 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 116 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 123 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 117 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -151,7 +145,6 @@ fn test_u128_cmpxchg() !void { | ... | @@ -151,7 +145,6 @@ fn test_u128_cmpxchg() !void { |
| 151 | var a_global_variable = @as(u32, 1234); | 145 | var a_global_variable = @as(u32, 1234); |
| 152 | 146 | ||
| 153 | test "cmpxchg on a global variable" { | 147 | test "cmpxchg on a global variable" { |
| 154 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 155 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 148 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 156 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 149 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 157 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 150 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -170,7 +163,6 @@ test "cmpxchg on a global variable" { | ... | @@ -170,7 +163,6 @@ test "cmpxchg on a global variable" { |
| 170 | } | 163 | } |
| 171 | 164 | ||
| 172 | test "atomic load and rmw with enum" { | 165 | test "atomic load and rmw with enum" { |
| 173 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 174 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 166 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 175 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 167 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 176 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 168 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -189,7 +181,6 @@ test "atomic load and rmw with enum" { | ... | @@ -189,7 +181,6 @@ test "atomic load and rmw with enum" { |
| 189 | } | 181 | } |
| 190 | 182 | ||
| 191 | test "atomic store" { | 183 | test "atomic store" { |
| 192 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 193 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 184 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 194 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 185 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 195 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 186 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -204,7 +195,6 @@ test "atomic store" { | ... | @@ -204,7 +195,6 @@ test "atomic store" { |
| 204 | } | 195 | } |
| 205 | 196 | ||
| 206 | test "atomic store comptime" { | 197 | test "atomic store comptime" { |
| 207 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 208 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 198 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 209 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 199 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 210 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 200 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -224,7 +214,6 @@ fn testAtomicStore() !void { | ... | @@ -224,7 +214,6 @@ fn testAtomicStore() !void { |
| 224 | } | 214 | } |
| 225 | 215 | ||
| 226 | test "atomicrmw with floats" { | 216 | test "atomicrmw with floats" { |
| 227 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 228 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 217 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 229 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 218 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 230 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 219 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -253,7 +242,6 @@ fn testAtomicRmwFloat() !void { | ... | @@ -253,7 +242,6 @@ fn testAtomicRmwFloat() !void { |
| 253 | } | 242 | } |
| 254 | 243 | ||
| 255 | test "atomicrmw with ints" { | 244 | test "atomicrmw with ints" { |
| 256 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 257 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 245 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 258 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 246 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 259 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 247 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -288,7 +276,6 @@ fn testAtomicRmwInt() !void { | ... | @@ -288,7 +276,6 @@ fn testAtomicRmwInt() !void { |
| 288 | } | 276 | } |
| 289 | 277 | ||
| 290 | test "atomics with different types" { | 278 | test "atomics with different types" { |
| 291 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 292 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 279 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 293 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 280 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 294 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 281 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -319,7 +306,6 @@ fn testAtomicsWithType(comptime T: type, a: T, b: T) !void { | ... | @@ -319,7 +306,6 @@ fn testAtomicsWithType(comptime T: type, a: T, b: T) !void { |
| 319 | } | 306 | } |
| 320 | 307 | ||
| 321 | test "return @atomicStore, using it as a void value" { | 308 | test "return @atomicStore, using it as a void value" { |
| 322 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 323 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 309 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 324 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 310 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 325 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 311 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
test/behavior/basic.zig-7| ... | @@ -333,7 +333,6 @@ test "call result of if else expression" { | ... | @@ -333,7 +333,6 @@ test "call result of if else expression" { |
| 333 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 333 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 334 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 334 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 335 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 335 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 336 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 337 | 336 | ||
| 338 | try expect(mem.eql(u8, f2(true), "a")); | 337 | try expect(mem.eql(u8, f2(true), "a")); |
| 339 | try expect(mem.eql(u8, f2(false), "b")); | 338 | try expect(mem.eql(u8, f2(false), "b")); |
| ... | @@ -364,8 +363,6 @@ fn testMemcpyMemset() !void { | ... | @@ -364,8 +363,6 @@ fn testMemcpyMemset() !void { |
| 364 | } | 363 | } |
| 365 | 364 | ||
| 366 | test "variable is allowed to be a pointer to an opaque type" { | 365 | test "variable is allowed to be a pointer to an opaque type" { |
| 367 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 368 | |||
| 369 | var x: i32 = 1234; | 366 | var x: i32 = 1234; |
| 370 | _ = hereIsAnOpaqueType(@ptrCast(*OpaqueA, &x)); | 367 | _ = hereIsAnOpaqueType(@ptrCast(*OpaqueA, &x)); |
| 371 | } | 368 | } |
| ... | @@ -386,8 +383,6 @@ fn testTakeAddressOfParameter(f: f32) !void { | ... | @@ -386,8 +383,6 @@ fn testTakeAddressOfParameter(f: f32) !void { |
| 386 | } | 383 | } |
| 387 | 384 | ||
| 388 | test "pointer to void return type" { | 385 | test "pointer to void return type" { |
| 389 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 390 | |||
| 391 | try testPointerToVoidReturnType(); | 386 | try testPointerToVoidReturnType(); |
| 392 | } | 387 | } |
| 393 | fn testPointerToVoidReturnType() anyerror!void { | 388 | fn testPointerToVoidReturnType() anyerror!void { |
| ... | @@ -593,7 +588,6 @@ test "equality compare fn ptrs" { | ... | @@ -593,7 +588,6 @@ test "equality compare fn ptrs" { |
| 593 | 588 | ||
| 594 | test "self reference through fn ptr field" { | 589 | test "self reference through fn ptr field" { |
| 595 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 590 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 596 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 597 | 591 | ||
| 598 | const S = struct { | 592 | const S = struct { |
| 599 | const A = struct { | 593 | const A = struct { |
| ... | @@ -881,7 +875,6 @@ test "labeled block implicitly ends in a break" { | ... | @@ -881,7 +875,6 @@ test "labeled block implicitly ends in a break" { |
| 881 | } | 875 | } |
| 882 | 876 | ||
| 883 | test "catch in block has correct result location" { | 877 | test "catch in block has correct result location" { |
| 884 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 885 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 878 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 886 | 879 | ||
| 887 | const S = struct { | 880 | const S = struct { |
test/behavior/bitcast.zig-8| ... | @@ -161,7 +161,6 @@ test "@bitCast packed structs at runtime and comptime" { | ... | @@ -161,7 +161,6 @@ test "@bitCast packed structs at runtime and comptime" { |
| 161 | return error.SkipZigTest; | 161 | return error.SkipZigTest; |
| 162 | } | 162 | } |
| 163 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 163 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 164 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 165 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 164 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 166 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 165 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 167 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 166 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | @@ -189,7 +188,6 @@ test "@bitCast packed structs at runtime and comptime" { | ... | @@ -189,7 +188,6 @@ test "@bitCast packed structs at runtime and comptime" { |
| 189 | 188 | ||
| 190 | test "@bitCast extern structs at runtime and comptime" { | 189 | test "@bitCast extern structs at runtime and comptime" { |
| 191 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 190 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 192 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 193 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 191 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 194 | 192 | ||
| 195 | const Full = extern struct { | 193 | const Full = extern struct { |
| ... | @@ -221,7 +219,6 @@ test "@bitCast extern structs at runtime and comptime" { | ... | @@ -221,7 +219,6 @@ test "@bitCast extern structs at runtime and comptime" { |
| 221 | 219 | ||
| 222 | test "bitcast packed struct to integer and back" { | 220 | test "bitcast packed struct to integer and back" { |
| 223 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 221 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 224 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 225 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 222 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 226 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 223 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 227 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 224 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | @@ -261,7 +258,6 @@ test "implicit cast to error union by returning" { | ... | @@ -261,7 +258,6 @@ test "implicit cast to error union by returning" { |
| 261 | 258 | ||
| 262 | test "bitcast packed struct literal to byte" { | 259 | test "bitcast packed struct literal to byte" { |
| 263 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 260 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 264 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 265 | 261 | ||
| 266 | const Foo = packed struct { | 262 | const Foo = packed struct { |
| 267 | value: u8, | 263 | value: u8, |
| ... | @@ -271,8 +267,6 @@ test "bitcast packed struct literal to byte" { | ... | @@ -271,8 +267,6 @@ test "bitcast packed struct literal to byte" { |
| 271 | } | 267 | } |
| 272 | 268 | ||
| 273 | test "comptime bitcast used in expression has the correct type" { | 269 | test "comptime bitcast used in expression has the correct type" { |
| 274 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 275 | |||
| 276 | const Foo = packed struct { | 270 | const Foo = packed struct { |
| 277 | value: u8, | 271 | value: u8, |
| 278 | }; | 272 | }; |
| ... | @@ -290,8 +284,6 @@ test "bitcast passed as tuple element" { | ... | @@ -290,8 +284,6 @@ test "bitcast passed as tuple element" { |
| 290 | } | 284 | } |
| 291 | 285 | ||
| 292 | test "triple level result location with bitcast sandwich passed as tuple element" { | 286 | test "triple level result location with bitcast sandwich passed as tuple element" { |
| 293 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 294 | |||
| 295 | const S = struct { | 287 | const S = struct { |
| 296 | fn foo(args: anytype) !void { | 288 | fn foo(args: anytype) !void { |
| 297 | comptime try expect(@TypeOf(args[0]) == f64); | 289 | comptime try expect(@TypeOf(args[0]) == f64); |
test/behavior/bugs/10970.zig-1| ... | @@ -7,7 +7,6 @@ test "breaking from a loop in an if statement" { | ... | @@ -7,7 +7,6 @@ test "breaking from a loop in an if statement" { |
| 7 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 7 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 8 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 8 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 9 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 9 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 10 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 11 | 10 | ||
| 12 | var cond = true; | 11 | var cond = true; |
| 13 | const opt = while (cond) { | 12 | const opt = while (cond) { |
test/behavior/bugs/11159.zig-1| ... | @@ -9,7 +9,6 @@ test { | ... | @@ -9,7 +9,6 @@ test { |
| 9 | 9 | ||
| 10 | test { | 10 | test { |
| 11 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; // TODO | 11 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; // TODO |
| 12 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 13 | 12 | ||
| 14 | const S = struct { | 13 | const S = struct { |
| 15 | comptime x: i32 = 0, | 14 | comptime x: i32 = 0, |
test/behavior/bugs/11181.zig-4| ... | @@ -1,8 +1,6 @@ | ... | @@ -1,8 +1,6 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | 2 | ||
| 3 | test "const inferred array of slices" { | 3 | test "const inferred array of slices" { |
| 4 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 5 | |||
| 6 | const T = struct { v: bool }; | 4 | const T = struct { v: bool }; |
| 7 | 5 | ||
| 8 | const decls = [_][]const T{ | 6 | const decls = [_][]const T{ |
| ... | @@ -14,8 +12,6 @@ test "const inferred array of slices" { | ... | @@ -14,8 +12,6 @@ test "const inferred array of slices" { |
| 14 | } | 12 | } |
| 15 | 13 | ||
| 16 | test "var inferred array of slices" { | 14 | test "var inferred array of slices" { |
| 17 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 18 | |||
| 19 | const T = struct { v: bool }; | 15 | const T = struct { v: bool }; |
| 20 | 16 | ||
| 21 | var decls = [_][]const T{ | 17 | var decls = [_][]const T{ |
test/behavior/bugs/11213.zig-2| ... | @@ -3,8 +3,6 @@ const builtin = @import("builtin"); | ... | @@ -3,8 +3,6 @@ const builtin = @import("builtin"); |
| 3 | const testing = std.testing; | 3 | const testing = std.testing; |
| 4 | 4 | ||
| 5 | test { | 5 | test { |
| 6 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 7 | |||
| 8 | const g: error{Test}!void = error.Test; | 6 | const g: error{Test}!void = error.Test; |
| 9 | 7 | ||
| 10 | var v: u32 = 0; | 8 | var v: u32 = 0; |
test/behavior/bugs/12776.zig-1| ... | @@ -31,7 +31,6 @@ const CPU = packed struct { | ... | @@ -31,7 +31,6 @@ const CPU = packed struct { |
| 31 | test { | 31 | test { |
| 32 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 32 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 33 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 33 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 34 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 35 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 34 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 36 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 35 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 37 | 36 |
test/behavior/bugs/12891.zig-1| ... | @@ -8,7 +8,6 @@ test "issue12891" { | ... | @@ -8,7 +8,6 @@ test "issue12891" { |
| 8 | } | 8 | } |
| 9 | test "nan" { | 9 | test "nan" { |
| 10 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 12 | 11 | ||
| 13 | const f = comptime std.math.nan(f64); | 12 | const f = comptime std.math.nan(f64); |
| 14 | var i: usize = 0; | 13 | var i: usize = 0; |
test/behavior/bugs/12972.zig-1| ... | @@ -5,7 +5,6 @@ pub fn f(_: [:null]const ?u8) void {} | ... | @@ -5,7 +5,6 @@ pub fn f(_: [:null]const ?u8) void {} |
| 5 | test { | 5 | test { |
| 6 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 6 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 7 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 7 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 8 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 9 | 8 | ||
| 10 | const c: u8 = 42; | 9 | const c: u8 = 42; |
| 11 | f(&[_:null]?u8{c}); | 10 | f(&[_:null]?u8{c}); |
test/behavior/bugs/12984.zig-1| ... | @@ -14,7 +14,6 @@ pub const CustomDraw = DeleagateWithContext(fn (?OnConfirm) void); | ... | @@ -14,7 +14,6 @@ pub const CustomDraw = DeleagateWithContext(fn (?OnConfirm) void); |
| 14 | test "simple test" { | 14 | test "simple test" { |
| 15 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 15 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 16 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 16 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 17 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 18 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 17 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 19 | 18 | ||
| 20 | var c: CustomDraw = undefined; | 19 | var c: CustomDraw = undefined; |
test/behavior/bugs/13068.zig-1| ... | @@ -7,7 +7,6 @@ var list = std.ArrayList(u32).init(allocator); | ... | @@ -7,7 +7,6 @@ var list = std.ArrayList(u32).init(allocator); |
| 7 | test { | 7 | test { |
| 8 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 8 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 9 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 9 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 10 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 11 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 12 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 11 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 13 | 12 |
test/behavior/bugs/1310.zig-1| ... | @@ -24,6 +24,5 @@ fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 { | ... | @@ -24,6 +24,5 @@ fn agent_callback(_vm: [*]VM, options: [*]u8) callconv(.C) i32 { |
| 24 | 24 | ||
| 25 | test "fixed" { | 25 | test "fixed" { |
| 26 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 26 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 27 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 28 | try expect(agent_callback(undefined, undefined) == 11); | 27 | try expect(agent_callback(undefined, undefined) == 11); |
| 29 | } | 28 | } |
test/behavior/bugs/13128.zig-1| ... | @@ -12,7 +12,6 @@ fn foo(val: U) !void { | ... | @@ -12,7 +12,6 @@ fn foo(val: U) !void { |
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | test "runtime union init, most-aligned field != largest" { | 14 | test "runtime union init, most-aligned field != largest" { |
| 15 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 16 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 15 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 17 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 16 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 18 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 17 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
test/behavior/bugs/1421.zig-1| ... | @@ -10,7 +10,6 @@ const S = struct { | ... | @@ -10,7 +10,6 @@ const S = struct { |
| 10 | 10 | ||
| 11 | test "functions with return type required to be comptime are generic" { | 11 | test "functions with return type required to be comptime are generic" { |
| 12 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 12 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 13 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 14 | const ti = S.method(); | 13 | const ti = S.method(); |
| 15 | try expect(@as(std.builtin.TypeId, ti) == std.builtin.TypeId.Struct); | 14 | try expect(@as(std.builtin.TypeId, ti) == std.builtin.TypeId.Struct); |
| 16 | } | 15 | } |
test/behavior/bugs/1442.zig-1| ... | @@ -10,7 +10,6 @@ test "const error union field alignment" { | ... | @@ -10,7 +10,6 @@ test "const error union field alignment" { |
| 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 11 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 11 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 12 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 12 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 13 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 14 | var union_or_err: anyerror!Union = Union{ .Color = 1234 }; | 13 | var union_or_err: anyerror!Union = Union{ .Color = 1234 }; |
| 15 | try std.testing.expect((union_or_err catch unreachable).Color == 1234); | 14 | try std.testing.expect((union_or_err catch unreachable).Color == 1234); |
| 16 | } | 15 | } |
test/behavior/bugs/1500.zig-1| ... | @@ -6,7 +6,6 @@ const A = struct { | ... | @@ -6,7 +6,6 @@ const A = struct { |
| 6 | const B = *const fn (A) void; | 6 | const B = *const fn (A) void; |
| 7 | 7 | ||
| 8 | test "allow these dependencies" { | 8 | test "allow these dependencies" { |
| 9 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 10 | var a: A = undefined; | 9 | var a: A = undefined; |
| 11 | var b: B = undefined; | 10 | var b: B = undefined; |
| 12 | if (false) { | 11 | if (false) { |
test/behavior/bugs/1607.zig-1| ... | @@ -14,7 +14,6 @@ test "slices pointing at the same address as global array." { | ... | @@ -14,7 +14,6 @@ test "slices pointing at the same address as global array." { |
| 14 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 14 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 15 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 15 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 16 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 16 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 17 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 18 | try checkAddress(&a); | 17 | try checkAddress(&a); |
| 19 | comptime try checkAddress(&a); | 18 | comptime try checkAddress(&a); |
| 20 | } | 19 | } |
test/behavior/bugs/1735.zig-1| ... | @@ -43,7 +43,6 @@ const a = struct { | ... | @@ -43,7 +43,6 @@ const a = struct { |
| 43 | 43 | ||
| 44 | test "initialization" { | 44 | test "initialization" { |
| 45 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 45 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 46 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 47 | var t = a.init(); | 46 | var t = a.init(); |
| 48 | try std.testing.expect(t.foo.len == 0); | 47 | try std.testing.expect(t.foo.len == 0); |
| 49 | } | 48 | } |
test/behavior/bugs/1914.zig-2| ... | @@ -12,7 +12,6 @@ const b_list: []B = &[_]B{}; | ... | @@ -12,7 +12,6 @@ const b_list: []B = &[_]B{}; |
| 12 | const a = A{ .b_list_pointer = &b_list }; | 12 | const a = A{ .b_list_pointer = &b_list }; |
| 13 | 13 | ||
| 14 | test "segfault bug" { | 14 | test "segfault bug" { |
| 15 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 16 | const assert = std.debug.assert; | 15 | const assert = std.debug.assert; |
| 17 | const obj = B{ .a_pointer = &a }; | 16 | const obj = B{ .a_pointer = &a }; |
| 18 | assert(obj.a_pointer == &a); // this makes zig crash | 17 | assert(obj.a_pointer == &a); // this makes zig crash |
| ... | @@ -29,6 +28,5 @@ pub const B2 = struct { | ... | @@ -29,6 +28,5 @@ pub const B2 = struct { |
| 29 | var b_value = B2{ .pointer_array = &[_]*A2{} }; | 28 | var b_value = B2{ .pointer_array = &[_]*A2{} }; |
| 30 | 29 | ||
| 31 | test "basic stuff" { | 30 | test "basic stuff" { |
| 32 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 33 | std.debug.assert(&b_value == &b_value); | 31 | std.debug.assert(&b_value == &b_value); |
| 34 | } | 32 | } |
test/behavior/bugs/2006.zig-1| ... | @@ -6,7 +6,6 @@ const S = struct { | ... | @@ -6,7 +6,6 @@ const S = struct { |
| 6 | p: *S, | 6 | p: *S, |
| 7 | }; | 7 | }; |
| 8 | test "bug 2006" { | 8 | test "bug 2006" { |
| 9 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 10 | var a: S = undefined; | 9 | var a: S = undefined; |
| 11 | a = S{ .p = undefined }; | 10 | a = S{ .p = undefined }; |
| 12 | try expect(@sizeOf(S) != 0); | 11 | try expect(@sizeOf(S) != 0); |
test/behavior/bugs/2114.zig-1| ... | @@ -12,7 +12,6 @@ test "fixed" { | ... | @@ -12,7 +12,6 @@ test "fixed" { |
| 12 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 12 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 13 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 13 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 14 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 14 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 15 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 16 | 15 | ||
| 17 | try testCtz(); | 16 | try testCtz(); |
| 18 | comptime try testCtz(); | 17 | comptime try testCtz(); |
test/behavior/bugs/2578.zig-1| ... | @@ -15,7 +15,6 @@ test "fixed" { | ... | @@ -15,7 +15,6 @@ test "fixed" { |
| 15 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 15 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 16 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 16 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 17 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 17 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 18 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 19 | 18 | ||
| 20 | bar(t); | 19 | bar(t); |
| 21 | } | 20 | } |
test/behavior/bugs/2692.zig-1| ... | @@ -5,7 +5,6 @@ fn foo(a: []u8) void { | ... | @@ -5,7 +5,6 @@ fn foo(a: []u8) void { |
| 5 | } | 5 | } |
| 6 | 6 | ||
| 7 | test "address of 0 length array" { | 7 | test "address of 0 length array" { |
| 8 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 8 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 10 | 9 | ||
| 11 | var pt: [0]u8 = undefined; | 10 | var pt: [0]u8 = undefined; |
test/behavior/bugs/3007.zig-1| ... | @@ -22,7 +22,6 @@ test "fixed" { | ... | @@ -22,7 +22,6 @@ test "fixed" { |
| 22 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 22 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 23 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 23 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 24 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 24 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 25 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 26 | 25 | ||
| 27 | default_foo = get_foo() catch null; // This Line | 26 | default_foo = get_foo() catch null; // This Line |
| 28 | try std.testing.expect(!default_foo.?.free); | 27 | try std.testing.expect(!default_foo.?.free); |
test/behavior/bugs/3046.zig-1| ... | @@ -15,7 +15,6 @@ var some_struct: SomeStruct = undefined; | ... | @@ -15,7 +15,6 @@ var some_struct: SomeStruct = undefined; |
| 15 | test "fixed" { | 15 | test "fixed" { |
| 16 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 16 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 17 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 17 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 18 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 19 | 18 | ||
| 20 | some_struct = SomeStruct{ | 19 | some_struct = SomeStruct{ |
| 21 | .field = couldFail() catch @as(i32, 0), | 20 | .field = couldFail() catch @as(i32, 0), |
test/behavior/bugs/3367.zig-1| ... | @@ -10,7 +10,6 @@ const Mixin = struct { | ... | @@ -10,7 +10,6 @@ const Mixin = struct { |
| 10 | }; | 10 | }; |
| 11 | 11 | ||
| 12 | test "container member access usingnamespace decls" { | 12 | test "container member access usingnamespace decls" { |
| 13 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 14 | var foo = Foo{}; | 13 | var foo = Foo{}; |
| 15 | foo.two(); | 14 | foo.two(); |
| 16 | } | 15 | } |
test/behavior/bugs/3742.zig-1| ... | @@ -38,6 +38,5 @@ test "fixed" { | ... | @@ -38,6 +38,5 @@ test "fixed" { |
| 38 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 38 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 39 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 39 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 40 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 40 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 41 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 42 | ArgSerializer.serializeCommand(GET.init("banana")); | 41 | ArgSerializer.serializeCommand(GET.init("banana")); |
| 43 | } | 42 | } |
test/behavior/bugs/4328.zig+8-8| ... | @@ -5,10 +5,10 @@ const FILE = extern struct { | ... | @@ -5,10 +5,10 @@ const FILE = extern struct { |
| 5 | dummy_field: u8, | 5 | dummy_field: u8, |
| 6 | }; | 6 | }; |
| 7 | 7 | ||
| 8 | extern fn printf([*c]const u8, ...) c_int; | 8 | extern fn c_printf([*c]const u8, ...) c_int; |
| 9 | extern fn fputs([*c]const u8, noalias [*c]FILE) c_int; | 9 | extern fn c_fputs([*c]const u8, noalias [*c]FILE) c_int; |
| 10 | extern fn ftell([*c]FILE) c_long; | 10 | extern fn c_ftell([*c]FILE) c_long; |
| 11 | extern fn fopen([*c]const u8, [*c]const u8) [*c]FILE; | 11 | extern fn c_fopen([*c]const u8, [*c]const u8) [*c]FILE; |
| 12 | 12 | ||
| 13 | const S = extern struct { | 13 | const S = extern struct { |
| 14 | state: c_short, | 14 | state: c_short, |
| ... | @@ -18,7 +18,7 @@ const S = extern struct { | ... | @@ -18,7 +18,7 @@ const S = extern struct { |
| 18 | 18 | ||
| 19 | test "Extern function calls in @TypeOf" { | 19 | test "Extern function calls in @TypeOf" { |
| 20 | const Test = struct { | 20 | const Test = struct { |
| 21 | fn test_fn_1(a: anytype, b: anytype) @TypeOf(printf("%d %s\n", a, b)) { | 21 | fn test_fn_1(a: anytype, b: anytype) @TypeOf(c_printf("%d %s\n", a, b)) { |
| 22 | return 0; | 22 | return 0; |
| 23 | } | 23 | } |
| 24 | 24 | ||
| ... | @@ -38,7 +38,7 @@ test "Extern function calls in @TypeOf" { | ... | @@ -38,7 +38,7 @@ test "Extern function calls in @TypeOf" { |
| 38 | 38 | ||
| 39 | test "Peer resolution of extern function calls in @TypeOf" { | 39 | test "Peer resolution of extern function calls in @TypeOf" { |
| 40 | const Test = struct { | 40 | const Test = struct { |
| 41 | fn test_fn() @TypeOf(ftell(null), fputs(null, null)) { | 41 | fn test_fn() @TypeOf(c_ftell(null), c_fputs(null, null)) { |
| 42 | return 0; | 42 | return 0; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| ... | @@ -55,12 +55,12 @@ test "Extern function calls, dereferences and field access in @TypeOf" { | ... | @@ -55,12 +55,12 @@ test "Extern function calls, dereferences and field access in @TypeOf" { |
| 55 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 55 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 56 | 56 | ||
| 57 | const Test = struct { | 57 | const Test = struct { |
| 58 | fn test_fn_1(a: c_long) @TypeOf(fopen("test", "r").*) { | 58 | fn test_fn_1(a: c_long) @TypeOf(c_fopen("test", "r").*) { |
| 59 | _ = a; | 59 | _ = a; |
| 60 | return .{ .dummy_field = 0 }; | 60 | return .{ .dummy_field = 0 }; |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | fn test_fn_2(a: anytype) @TypeOf(fopen("test", "r").*.dummy_field) { | 63 | fn test_fn_2(a: anytype) @TypeOf(c_fopen("test", "r").*.dummy_field) { |
| 64 | _ = a; | 64 | _ = a; |
| 65 | return 255; | 65 | return 255; |
| 66 | } | 66 | } |
test/behavior/bugs/4954.zig-1| ... | @@ -5,7 +5,6 @@ fn f(buf: []u8) void { | ... | @@ -5,7 +5,6 @@ fn f(buf: []u8) void { |
| 5 | } | 5 | } |
| 6 | 6 | ||
| 7 | test "crash" { | 7 | test "crash" { |
| 8 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 9 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 8 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 10 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 11 | 10 |
test/behavior/bugs/5398.zig-1| ... | @@ -22,7 +22,6 @@ test "assignment of field with padding" { | ... | @@ -22,7 +22,6 @@ test "assignment of field with padding" { |
| 22 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 22 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 23 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 23 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 24 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 24 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 25 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 26 | 25 | ||
| 27 | renderable = Renderable{ | 26 | renderable = Renderable{ |
| 28 | .mesh = Mesh{ .id = 0 }, | 27 | .mesh = Mesh{ .id = 0 }, |
test/behavior/bugs/5487.zig-1| ... | @@ -13,6 +13,5 @@ test "crash" { | ... | @@ -13,6 +13,5 @@ test "crash" { |
| 13 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 13 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 14 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 14 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 15 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 15 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 16 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 17 | _ = io.multiWriter(.{writer()}); | 16 | _ = io.multiWriter(.{writer()}); |
| 18 | } | 17 | } |
test/behavior/bugs/726.zig-2| ... | @@ -5,7 +5,6 @@ test "@ptrCast from const to nullable" { | ... | @@ -5,7 +5,6 @@ test "@ptrCast from const to nullable" { |
| 5 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 5 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 6 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 6 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 7 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 7 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 8 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 9 | 8 | ||
| 10 | const c: u8 = 4; | 9 | const c: u8 = 4; |
| 11 | var x: ?*const u8 = @ptrCast(?*const u8, &c); | 10 | var x: ?*const u8 = @ptrCast(?*const u8, &c); |
| ... | @@ -16,7 +15,6 @@ test "@ptrCast from var in empty struct to nullable" { | ... | @@ -16,7 +15,6 @@ test "@ptrCast from var in empty struct to nullable" { |
| 16 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 15 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 17 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 16 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 18 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 17 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 19 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 20 | 18 | ||
| 21 | const container = struct { | 19 | const container = struct { |
| 22 | var c: u8 = 4; | 20 | var c: u8 = 4; |
test/behavior/bugs/920.zig-1| ... | @@ -67,7 +67,6 @@ const NormalDist = blk: { | ... | @@ -67,7 +67,6 @@ const NormalDist = blk: { |
| 67 | 67 | ||
| 68 | test "bug 920 fixed" { | 68 | test "bug 920 fixed" { |
| 69 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 69 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 70 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 71 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 70 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 72 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 71 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 73 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 72 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
test/behavior/bugs/9584.zig-1| ... | @@ -49,7 +49,6 @@ test { | ... | @@ -49,7 +49,6 @@ test { |
| 49 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 49 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 50 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 50 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 51 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 51 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 52 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 53 | 52 | ||
| 54 | var flags = A{ | 53 | var flags = A{ |
| 55 | .a = false, | 54 | .a = false, |
test/behavior/call.zig-2| ... | @@ -58,7 +58,6 @@ test "basic invocations" { | ... | @@ -58,7 +58,6 @@ test "basic invocations" { |
| 58 | test "tuple parameters" { | 58 | test "tuple parameters" { |
| 59 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 59 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 60 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 60 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 61 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 62 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 61 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 63 | 62 | ||
| 64 | const add = struct { | 63 | const add = struct { |
| ... | @@ -87,7 +86,6 @@ test "tuple parameters" { | ... | @@ -87,7 +86,6 @@ test "tuple parameters" { |
| 87 | } | 86 | } |
| 88 | 87 | ||
| 89 | test "result location of function call argument through runtime condition and struct init" { | 88 | test "result location of function call argument through runtime condition and struct init" { |
| 90 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 91 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 89 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 92 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 90 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 93 | 91 |
test/behavior/cast.zig-39| ... | @@ -119,7 +119,6 @@ test "@intToFloat(f80)" { | ... | @@ -119,7 +119,6 @@ test "@intToFloat(f80)" { |
| 119 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 119 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 120 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 120 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 121 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 121 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 122 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 123 | 122 | ||
| 124 | const S = struct { | 123 | const S = struct { |
| 125 | fn doTheTest(comptime Int: type) !void { | 124 | fn doTheTest(comptime Int: type) !void { |
| ... | @@ -395,7 +394,6 @@ test "expected [*c]const u8, found [*:0]const u8" { | ... | @@ -395,7 +394,6 @@ test "expected [*c]const u8, found [*:0]const u8" { |
| 395 | test "explicit cast from integer to error type" { | 394 | test "explicit cast from integer to error type" { |
| 396 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 395 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 397 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 396 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 398 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 399 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 397 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 400 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 398 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 401 | 399 | ||
| ... | @@ -410,7 +408,6 @@ fn testCastIntToErr(err: anyerror) !void { | ... | @@ -410,7 +408,6 @@ fn testCastIntToErr(err: anyerror) !void { |
| 410 | 408 | ||
| 411 | test "peer resolve array and const slice" { | 409 | test "peer resolve array and const slice" { |
| 412 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 410 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 413 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 414 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 411 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 415 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 412 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 416 | 413 | ||
| ... | @@ -451,7 +448,6 @@ fn castToOptionalTypeError(z: i32) !void { | ... | @@ -451,7 +448,6 @@ fn castToOptionalTypeError(z: i32) !void { |
| 451 | 448 | ||
| 452 | test "implicitly cast from [0]T to anyerror![]T" { | 449 | test "implicitly cast from [0]T to anyerror![]T" { |
| 453 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 450 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 454 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 455 | 451 | ||
| 456 | try testCastZeroArrayToErrSliceMut(); | 452 | try testCastZeroArrayToErrSliceMut(); |
| 457 | comptime try testCastZeroArrayToErrSliceMut(); | 453 | comptime try testCastZeroArrayToErrSliceMut(); |
| ... | @@ -467,7 +463,6 @@ fn gimmeErrOrSlice() anyerror![]u8 { | ... | @@ -467,7 +463,6 @@ fn gimmeErrOrSlice() anyerror![]u8 { |
| 467 | 463 | ||
| 468 | test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" { | 464 | test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" { |
| 469 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 465 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 470 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 471 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 466 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 472 | 467 | ||
| 473 | const S = struct { | 468 | const S = struct { |
| ... | @@ -546,7 +541,6 @@ fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 { | ... | @@ -546,7 +541,6 @@ fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 { |
| 546 | 541 | ||
| 547 | test "single-item pointer of array to slice to unknown length pointer" { | 542 | test "single-item pointer of array to slice to unknown length pointer" { |
| 548 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 543 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 549 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 550 | 544 | ||
| 551 | try testCastPtrOfArrayToSliceAndPtr(); | 545 | try testCastPtrOfArrayToSliceAndPtr(); |
| 552 | comptime try testCastPtrOfArrayToSliceAndPtr(); | 546 | comptime try testCastPtrOfArrayToSliceAndPtr(); |
| ... | @@ -575,7 +569,6 @@ fn testCastPtrOfArrayToSliceAndPtr() !void { | ... | @@ -575,7 +569,6 @@ fn testCastPtrOfArrayToSliceAndPtr() !void { |
| 575 | 569 | ||
| 576 | test "cast *[1][*]const u8 to [*]const ?[*]const u8" { | 570 | test "cast *[1][*]const u8 to [*]const ?[*]const u8" { |
| 577 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 571 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 578 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 579 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 572 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 580 | 573 | ||
| 581 | const window_name = [1][*]const u8{"window name"}; | 574 | const window_name = [1][*]const u8{"window name"}; |
| ... | @@ -813,7 +806,6 @@ test "peer type resolution: error union after non-error" { | ... | @@ -813,7 +806,6 @@ test "peer type resolution: error union after non-error" { |
| 813 | test "peer cast *[0]T to E![]const T" { | 806 | test "peer cast *[0]T to E![]const T" { |
| 814 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 807 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 815 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 808 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 816 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 817 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 809 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 818 | 810 | ||
| 819 | var buffer: [5]u8 = "abcde".*; | 811 | var buffer: [5]u8 = "abcde".*; |
| ... | @@ -828,7 +820,6 @@ test "peer cast *[0]T to E![]const T" { | ... | @@ -828,7 +820,6 @@ test "peer cast *[0]T to E![]const T" { |
| 828 | test "peer cast *[0]T to []const T" { | 820 | test "peer cast *[0]T to []const T" { |
| 829 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 821 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 830 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 822 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 831 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 832 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 823 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 833 | 824 | ||
| 834 | var buffer: [5]u8 = "abcde".*; | 825 | var buffer: [5]u8 = "abcde".*; |
| ... | @@ -839,8 +830,6 @@ test "peer cast *[0]T to []const T" { | ... | @@ -839,8 +830,6 @@ test "peer cast *[0]T to []const T" { |
| 839 | } | 830 | } |
| 840 | 831 | ||
| 841 | test "peer cast *[N]T to [*]T" { | 832 | test "peer cast *[N]T to [*]T" { |
| 842 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 843 | |||
| 844 | var array = [4:99]i32{ 1, 2, 3, 4 }; | 833 | var array = [4:99]i32{ 1, 2, 3, 4 }; |
| 845 | var dest: [*]i32 = undefined; | 834 | var dest: [*]i32 = undefined; |
| 846 | try expect(@TypeOf(&array, dest) == [*]i32); | 835 | try expect(@TypeOf(&array, dest) == [*]i32); |
| ... | @@ -849,7 +838,6 @@ test "peer cast *[N]T to [*]T" { | ... | @@ -849,7 +838,6 @@ test "peer cast *[N]T to [*]T" { |
| 849 | 838 | ||
| 850 | test "peer resolution of string literals" { | 839 | test "peer resolution of string literals" { |
| 851 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 840 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 852 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 853 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 841 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 854 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 842 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 855 | 843 | ||
| ... | @@ -872,7 +860,6 @@ test "peer resolution of string literals" { | ... | @@ -872,7 +860,6 @@ test "peer resolution of string literals" { |
| 872 | 860 | ||
| 873 | test "peer cast [:x]T to []T" { | 861 | test "peer cast [:x]T to []T" { |
| 874 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 862 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 875 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 876 | 863 | ||
| 877 | const S = struct { | 864 | const S = struct { |
| 878 | fn doTheTest() !void { | 865 | fn doTheTest() !void { |
| ... | @@ -888,7 +875,6 @@ test "peer cast [:x]T to []T" { | ... | @@ -888,7 +875,6 @@ test "peer cast [:x]T to []T" { |
| 888 | 875 | ||
| 889 | test "peer cast [N:x]T to [N]T" { | 876 | test "peer cast [N:x]T to [N]T" { |
| 890 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 877 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 891 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 892 | 878 | ||
| 893 | const S = struct { | 879 | const S = struct { |
| 894 | fn doTheTest() !void { | 880 | fn doTheTest() !void { |
| ... | @@ -903,7 +889,6 @@ test "peer cast [N:x]T to [N]T" { | ... | @@ -903,7 +889,6 @@ test "peer cast [N:x]T to [N]T" { |
| 903 | 889 | ||
| 904 | test "peer cast *[N:x]T to *[N]T" { | 890 | test "peer cast *[N:x]T to *[N]T" { |
| 905 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 891 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 906 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 907 | 892 | ||
| 908 | const S = struct { | 893 | const S = struct { |
| 909 | fn doTheTest() !void { | 894 | fn doTheTest() !void { |
| ... | @@ -937,7 +922,6 @@ test "peer cast [*:x]T to [*]T" { | ... | @@ -937,7 +922,6 @@ test "peer cast [*:x]T to [*]T" { |
| 937 | 922 | ||
| 938 | test "peer cast [:x]T to [*:x]T" { | 923 | test "peer cast [:x]T to [*:x]T" { |
| 939 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 924 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 940 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 941 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 925 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 942 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 926 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 943 | 927 | ||
| ... | @@ -1018,7 +1002,6 @@ test "cast between C pointer with different but compatible types" { | ... | @@ -1018,7 +1002,6 @@ test "cast between C pointer with different but compatible types" { |
| 1018 | 1002 | ||
| 1019 | test "peer type resolve string lit with sentinel-terminated mutable slice" { | 1003 | test "peer type resolve string lit with sentinel-terminated mutable slice" { |
| 1020 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1004 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1021 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1022 | 1005 | ||
| 1023 | var array: [4:0]u8 = undefined; | 1006 | var array: [4:0]u8 = undefined; |
| 1024 | array[4] = 0; // TODO remove this when #4372 is solved | 1007 | array[4] = 0; // TODO remove this when #4372 is solved |
| ... | @@ -1035,8 +1018,6 @@ test "peer type resolve array pointers, one of them const" { | ... | @@ -1035,8 +1018,6 @@ test "peer type resolve array pointers, one of them const" { |
| 1035 | } | 1018 | } |
| 1036 | 1019 | ||
| 1037 | test "peer type resolve array pointer and unknown pointer" { | 1020 | test "peer type resolve array pointer and unknown pointer" { |
| 1038 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1039 | |||
| 1040 | const const_array: [4]u8 = undefined; | 1021 | const const_array: [4]u8 = undefined; |
| 1041 | var array: [4]u8 = undefined; | 1022 | var array: [4]u8 = undefined; |
| 1042 | var const_ptr: [*]const u8 = undefined; | 1023 | var const_ptr: [*]const u8 = undefined; |
| ... | @@ -1069,7 +1050,6 @@ test "comptime float casts" { | ... | @@ -1069,7 +1050,6 @@ test "comptime float casts" { |
| 1069 | 1050 | ||
| 1070 | test "pointer reinterpret const float to int" { | 1051 | test "pointer reinterpret const float to int" { |
| 1071 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1052 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1072 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1073 | 1053 | ||
| 1074 | // The hex representation is 0x3fe3333333333303. | 1054 | // The hex representation is 0x3fe3333333333303. |
| 1075 | const float: f64 = 5.99999999999994648725e-01; | 1055 | const float: f64 = 5.99999999999994648725e-01; |
| ... | @@ -1084,7 +1064,6 @@ test "pointer reinterpret const float to int" { | ... | @@ -1084,7 +1064,6 @@ test "pointer reinterpret const float to int" { |
| 1084 | 1064 | ||
| 1085 | test "implicit cast from [*]T to ?*anyopaque" { | 1065 | test "implicit cast from [*]T to ?*anyopaque" { |
| 1086 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1066 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1087 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1088 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1067 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1089 | 1068 | ||
| 1090 | var a = [_]u8{ 3, 2, 1 }; | 1069 | var a = [_]u8{ 3, 2, 1 }; |
| ... | @@ -1102,8 +1081,6 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void { | ... | @@ -1102,8 +1081,6 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void { |
| 1102 | 1081 | ||
| 1103 | test "compile time int to ptr of function" { | 1082 | test "compile time int to ptr of function" { |
| 1104 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 1083 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 1105 | |||
| 1106 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1107 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1084 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1108 | 1085 | ||
| 1109 | try foobar(FUNCTION_CONSTANT); | 1086 | try foobar(FUNCTION_CONSTANT); |
| ... | @@ -1120,7 +1097,6 @@ fn foobar(func: PFN_void) !void { | ... | @@ -1120,7 +1097,6 @@ fn foobar(func: PFN_void) !void { |
| 1120 | 1097 | ||
| 1121 | test "implicit ptr to *anyopaque" { | 1098 | test "implicit ptr to *anyopaque" { |
| 1122 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1099 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1123 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1124 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1100 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1125 | 1101 | ||
| 1126 | var a: u32 = 1; | 1102 | var a: u32 = 1; |
| ... | @@ -1149,7 +1125,6 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A { | ... | @@ -1149,7 +1125,6 @@ fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A { |
| 1149 | 1125 | ||
| 1150 | test "peer type resolution: [0]u8 and []const u8" { | 1126 | test "peer type resolution: [0]u8 and []const u8" { |
| 1151 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1127 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1152 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1153 | 1128 | ||
| 1154 | try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); | 1129 | try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); |
| 1155 | try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); | 1130 | try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); |
| ... | @@ -1168,7 +1143,6 @@ fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 { | ... | @@ -1168,7 +1143,6 @@ fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 { |
| 1168 | 1143 | ||
| 1169 | test "implicitly cast from [N]T to ?[]const T" { | 1144 | test "implicitly cast from [N]T to ?[]const T" { |
| 1170 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1145 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1171 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1172 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1146 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1173 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1147 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1174 | 1148 | ||
| ... | @@ -1182,7 +1156,6 @@ fn castToOptionalSlice() ?[]const u8 { | ... | @@ -1182,7 +1156,6 @@ fn castToOptionalSlice() ?[]const u8 { |
| 1182 | 1156 | ||
| 1183 | test "cast u128 to f128 and back" { | 1157 | test "cast u128 to f128 and back" { |
| 1184 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1158 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1185 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1186 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1159 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1187 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1160 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1188 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1161 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| ... | @@ -1221,7 +1194,6 @@ test "implicit cast from *[N]T to ?[*]T" { | ... | @@ -1221,7 +1194,6 @@ test "implicit cast from *[N]T to ?[*]T" { |
| 1221 | 1194 | ||
| 1222 | test "implicit cast from *T to ?*anyopaque" { | 1195 | test "implicit cast from *T to ?*anyopaque" { |
| 1223 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1196 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1224 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1225 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1197 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1226 | 1198 | ||
| 1227 | var a: u8 = 1; | 1199 | var a: u8 = 1; |
| ... | @@ -1235,7 +1207,6 @@ fn incrementVoidPtrValue(value: ?*anyopaque) void { | ... | @@ -1235,7 +1207,6 @@ fn incrementVoidPtrValue(value: ?*anyopaque) void { |
| 1235 | 1207 | ||
| 1236 | test "implicit cast *[0]T to E![]const u8" { | 1208 | test "implicit cast *[0]T to E![]const u8" { |
| 1237 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1209 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1238 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1239 | 1210 | ||
| 1240 | var x = @as(anyerror![]const u8, &[0]u8{}); | 1211 | var x = @as(anyerror![]const u8, &[0]u8{}); |
| 1241 | try expect((x catch unreachable).len == 0); | 1212 | try expect((x catch unreachable).len == 0); |
| ... | @@ -1247,15 +1218,12 @@ test "cast from array reference to fn: comptime fn ptr" { | ... | @@ -1247,15 +1218,12 @@ test "cast from array reference to fn: comptime fn ptr" { |
| 1247 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); | 1218 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); |
| 1248 | } | 1219 | } |
| 1249 | test "cast from array reference to fn: runtime fn ptr" { | 1220 | test "cast from array reference to fn: runtime fn ptr" { |
| 1250 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1251 | |||
| 1252 | var f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array); | 1221 | var f = @ptrCast(*align(1) const fn () callconv(.C) void, &global_array); |
| 1253 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); | 1222 | try expect(@ptrToInt(f) == @ptrToInt(&global_array)); |
| 1254 | } | 1223 | } |
| 1255 | 1224 | ||
| 1256 | test "*const [N]null u8 to ?[]const u8" { | 1225 | test "*const [N]null u8 to ?[]const u8" { |
| 1257 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1226 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1258 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1259 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1227 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1260 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1228 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1261 | 1229 | ||
| ... | @@ -1291,7 +1259,6 @@ test "cast between [*c]T and ?[*:0]T on fn parameter" { | ... | @@ -1291,7 +1259,6 @@ test "cast between [*c]T and ?[*:0]T on fn parameter" { |
| 1291 | var global_struct: struct { f0: usize } = undefined; | 1259 | var global_struct: struct { f0: usize } = undefined; |
| 1292 | test "assignment to optional pointer result loc" { | 1260 | test "assignment to optional pointer result loc" { |
| 1293 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1261 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1294 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1295 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1262 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1296 | 1263 | ||
| 1297 | var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct }; | 1264 | var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct }; |
| ... | @@ -1318,7 +1285,6 @@ fn boolToStr(b: bool) []const u8 { | ... | @@ -1318,7 +1285,6 @@ fn boolToStr(b: bool) []const u8 { |
| 1318 | 1285 | ||
| 1319 | test "cast f16 to wider types" { | 1286 | test "cast f16 to wider types" { |
| 1320 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1287 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1321 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1322 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1288 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1323 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1289 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1324 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1290 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| ... | @@ -1337,7 +1303,6 @@ test "cast f16 to wider types" { | ... | @@ -1337,7 +1303,6 @@ test "cast f16 to wider types" { |
| 1337 | 1303 | ||
| 1338 | test "cast f128 to narrower types" { | 1304 | test "cast f128 to narrower types" { |
| 1339 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1305 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1340 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1341 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1306 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1342 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1307 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1343 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1308 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| ... | @@ -1356,7 +1321,6 @@ test "cast f128 to narrower types" { | ... | @@ -1356,7 +1321,6 @@ test "cast f128 to narrower types" { |
| 1356 | 1321 | ||
| 1357 | test "peer type resolution: unreachable, null, slice" { | 1322 | test "peer type resolution: unreachable, null, slice" { |
| 1358 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1323 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1359 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1360 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1324 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1361 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1325 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1362 | 1326 | ||
| ... | @@ -1396,7 +1360,6 @@ test "cast i8 fn call peers to i32 result" { | ... | @@ -1396,7 +1360,6 @@ test "cast i8 fn call peers to i32 result" { |
| 1396 | test "cast compatible optional types" { | 1360 | test "cast compatible optional types" { |
| 1397 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1361 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1398 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1362 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1399 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1400 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1363 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1401 | 1364 | ||
| 1402 | var a: ?[:0]const u8 = null; | 1365 | var a: ?[:0]const u8 = null; |
| ... | @@ -1414,13 +1377,11 @@ test "coerce undefined single-item pointer of array to error union of slice" { | ... | @@ -1414,13 +1377,11 @@ test "coerce undefined single-item pointer of array to error union of slice" { |
| 1414 | } | 1377 | } |
| 1415 | 1378 | ||
| 1416 | test "pointer to empty struct literal to mutable slice" { | 1379 | test "pointer to empty struct literal to mutable slice" { |
| 1417 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1418 | var x: []i32 = &.{}; | 1380 | var x: []i32 = &.{}; |
| 1419 | try expect(x.len == 0); | 1381 | try expect(x.len == 0); |
| 1420 | } | 1382 | } |
| 1421 | 1383 | ||
| 1422 | test "coerce between pointers of compatible differently-named floats" { | 1384 | test "coerce between pointers of compatible differently-named floats" { |
| 1423 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1424 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1385 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1425 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1386 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1426 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1387 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
test/behavior/cast_int.zig-1| ... | @@ -8,7 +8,6 @@ test "@intCast i32 to u7" { | ... | @@ -8,7 +8,6 @@ test "@intCast i32 to u7" { |
| 8 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 8 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 12 | 11 | ||
| 13 | var x: u128 = maxInt(u128); | 12 | var x: u128 = maxInt(u128); |
| 14 | var y: i32 = 120; | 13 | var y: i32 = 120; |
test/behavior/defer.zig-1| ... | @@ -108,7 +108,6 @@ test "mixing normal and error defers" { | ... | @@ -108,7 +108,6 @@ test "mixing normal and error defers" { |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | test "errdefer with payload" { | 110 | test "errdefer with payload" { |
| 111 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 112 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 111 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 113 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 112 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 114 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 113 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
test/behavior/empty_union.zig-4| ... | @@ -3,7 +3,6 @@ const std = @import("std"); | ... | @@ -3,7 +3,6 @@ const std = @import("std"); |
| 3 | const expect = std.testing.expect; | 3 | const expect = std.testing.expect; |
| 4 | 4 | ||
| 5 | test "switch on empty enum" { | 5 | test "switch on empty enum" { |
| 6 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 7 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 6 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 8 | 7 | ||
| 9 | const E = enum {}; | 8 | const E = enum {}; |
| ... | @@ -12,7 +11,6 @@ test "switch on empty enum" { | ... | @@ -12,7 +11,6 @@ test "switch on empty enum" { |
| 12 | } | 11 | } |
| 13 | 12 | ||
| 14 | test "switch on empty enum with a specified tag type" { | 13 | test "switch on empty enum with a specified tag type" { |
| 15 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 16 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 14 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 17 | 15 | ||
| 18 | const E = enum(u8) {}; | 16 | const E = enum(u8) {}; |
| ... | @@ -21,7 +19,6 @@ test "switch on empty enum with a specified tag type" { | ... | @@ -21,7 +19,6 @@ test "switch on empty enum with a specified tag type" { |
| 21 | } | 19 | } |
| 22 | 20 | ||
| 23 | test "switch on empty auto numbered tagged union" { | 21 | test "switch on empty auto numbered tagged union" { |
| 24 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 25 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 22 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 26 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 23 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 27 | 24 | ||
| ... | @@ -31,7 +28,6 @@ test "switch on empty auto numbered tagged union" { | ... | @@ -31,7 +28,6 @@ test "switch on empty auto numbered tagged union" { |
| 31 | } | 28 | } |
| 32 | 29 | ||
| 33 | test "switch on empty tagged union" { | 30 | test "switch on empty tagged union" { |
| 34 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 35 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 31 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 36 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 32 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 37 | 33 |
test/behavior/enum.zig-4| ... | @@ -972,7 +972,6 @@ fn test3_2(f: Test3Foo) !void { | ... | @@ -972,7 +972,6 @@ fn test3_2(f: Test3Foo) !void { |
| 972 | } | 972 | } |
| 973 | 973 | ||
| 974 | test "@tagName" { | 974 | test "@tagName" { |
| 975 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 976 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 975 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 977 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 976 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 978 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 977 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | @@ -989,7 +988,6 @@ fn testEnumTagNameBare(n: anytype) []const u8 { | ... | @@ -989,7 +988,6 @@ fn testEnumTagNameBare(n: anytype) []const u8 { |
| 989 | const BareNumber = enum { One, Two, Three }; | 988 | const BareNumber = enum { One, Two, Three }; |
| 990 | 989 | ||
| 991 | test "@tagName non-exhaustive enum" { | 990 | test "@tagName non-exhaustive enum" { |
| 992 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 993 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 991 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 994 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 992 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 995 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 993 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | @@ -1001,7 +999,6 @@ test "@tagName non-exhaustive enum" { | ... | @@ -1001,7 +999,6 @@ test "@tagName non-exhaustive enum" { |
| 1001 | const NonExhaustive = enum(u8) { A, B, _ }; | 999 | const NonExhaustive = enum(u8) { A, B, _ }; |
| 1002 | 1000 | ||
| 1003 | test "@tagName is null-terminated" { | 1001 | test "@tagName is null-terminated" { |
| 1004 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1005 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1002 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1006 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 1003 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 1007 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 1004 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | @@ -1017,7 +1014,6 @@ test "@tagName is null-terminated" { | ... | @@ -1017,7 +1014,6 @@ test "@tagName is null-terminated" { |
| 1017 | } | 1014 | } |
| 1018 | 1015 | ||
| 1019 | test "tag name with assigned enum values" { | 1016 | test "tag name with assigned enum values" { |
| 1020 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1021 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1017 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1022 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 1018 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 1023 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 1019 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
test/behavior/error.zig+16-4| ... | @@ -258,7 +258,6 @@ fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) !void { | ... | @@ -258,7 +258,6 @@ fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) !void { |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | test "comptime err to int of error set with only 1 possible value" { | 260 | test "comptime err to int of error set with only 1 possible value" { |
| 261 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 262 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 261 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 263 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 262 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 264 | 263 | ||
| ... | @@ -471,7 +470,6 @@ test "function pointer with return type that is error union with payload which i | ... | @@ -471,7 +470,6 @@ test "function pointer with return type that is error union with payload which i |
| 471 | return error.SkipZigTest; | 470 | return error.SkipZigTest; |
| 472 | } | 471 | } |
| 473 | 472 | ||
| 474 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 475 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 473 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 476 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 474 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 477 | 475 | ||
| ... | @@ -556,7 +554,6 @@ test "error union comptime caching" { | ... | @@ -556,7 +554,6 @@ test "error union comptime caching" { |
| 556 | } | 554 | } |
| 557 | 555 | ||
| 558 | test "@errorName" { | 556 | test "@errorName" { |
| 559 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 560 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 557 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 561 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 558 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 562 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 559 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| ... | @@ -570,7 +567,6 @@ fn gimmeItBroke() anyerror { | ... | @@ -570,7 +567,6 @@ fn gimmeItBroke() anyerror { |
| 570 | } | 567 | } |
| 571 | 568 | ||
| 572 | test "@errorName sentinel length matches slice length" { | 569 | test "@errorName sentinel length matches slice length" { |
| 573 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 574 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 570 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 575 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 571 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 576 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 572 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| ... | @@ -843,3 +839,19 @@ fn non_errorable() void { | ... | @@ -843,3 +839,19 @@ fn non_errorable() void { |
| 843 | test "catch within a function that calls no errorable functions" { | 839 | test "catch within a function that calls no errorable functions" { |
| 844 | non_errorable(); | 840 | non_errorable(); |
| 845 | } | 841 | } |
| 842 | |||
| 843 | test "error from comptime string" { | ||
| 844 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | ||
| 845 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | ||
| 846 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | ||
| 847 | |||
| 848 | const name = "Weird error name!"; | ||
| 849 | const S = struct { | ||
| 850 | fn foo() !void { | ||
| 851 | return @field(anyerror, name); | ||
| 852 | } | ||
| 853 | }; | ||
| 854 | if (S.foo()) unreachable else |err| { | ||
| 855 | try expect(mem.eql(u8, name, @errorName(err))); | ||
| 856 | } | ||
| 857 | } |
test/behavior/eval.zig-9| ... | @@ -531,7 +531,6 @@ test "@tagName of @typeInfo" { | ... | @@ -531,7 +531,6 @@ test "@tagName of @typeInfo" { |
| 531 | } | 531 | } |
| 532 | 532 | ||
| 533 | test "static eval list init" { | 533 | test "static eval list init" { |
| 534 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 535 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 534 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 536 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 535 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 537 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 536 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -719,7 +718,6 @@ test "*align(1) u16 is the same as *align(1:0:2) u16" { | ... | @@ -719,7 +718,6 @@ test "*align(1) u16 is the same as *align(1:0:2) u16" { |
| 719 | } | 718 | } |
| 720 | 719 | ||
| 721 | test "array concatenation of function calls" { | 720 | test "array concatenation of function calls" { |
| 722 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 723 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 721 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 724 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 722 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 725 | 723 | ||
| ... | @@ -728,7 +726,6 @@ test "array concatenation of function calls" { | ... | @@ -728,7 +726,6 @@ test "array concatenation of function calls" { |
| 728 | } | 726 | } |
| 729 | 727 | ||
| 730 | test "array multiplication of function calls" { | 728 | test "array multiplication of function calls" { |
| 731 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 732 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 729 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 733 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 730 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 734 | 731 | ||
| ... | @@ -746,7 +743,6 @@ fn scalar(x: u32) u32 { | ... | @@ -746,7 +743,6 @@ fn scalar(x: u32) u32 { |
| 746 | 743 | ||
| 747 | test "array concatenation peer resolves element types - value" { | 744 | test "array concatenation peer resolves element types - value" { |
| 748 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 745 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 749 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 750 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 746 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 751 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 747 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 752 | 748 | ||
| ... | @@ -763,7 +759,6 @@ test "array concatenation peer resolves element types - value" { | ... | @@ -763,7 +759,6 @@ test "array concatenation peer resolves element types - value" { |
| 763 | 759 | ||
| 764 | test "array concatenation peer resolves element types - pointer" { | 760 | test "array concatenation peer resolves element types - pointer" { |
| 765 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 761 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 766 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 767 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 762 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 768 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 763 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 769 | 764 | ||
| ... | @@ -782,7 +777,6 @@ test "array concatenation sets the sentinel - value" { | ... | @@ -782,7 +777,6 @@ test "array concatenation sets the sentinel - value" { |
| 782 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 777 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 783 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 778 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 784 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 779 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 785 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 786 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 780 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 787 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 781 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 788 | 782 | ||
| ... | @@ -801,7 +795,6 @@ test "array concatenation sets the sentinel - value" { | ... | @@ -801,7 +795,6 @@ test "array concatenation sets the sentinel - value" { |
| 801 | 795 | ||
| 802 | test "array concatenation sets the sentinel - pointer" { | 796 | test "array concatenation sets the sentinel - pointer" { |
| 803 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 797 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 804 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 805 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 798 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 806 | 799 | ||
| 807 | var a = [2]u3{ 1, 7 }; | 800 | var a = [2]u3{ 1, 7 }; |
| ... | @@ -821,7 +814,6 @@ test "array multiplication sets the sentinel - value" { | ... | @@ -821,7 +814,6 @@ test "array multiplication sets the sentinel - value" { |
| 821 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 814 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 822 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 815 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 823 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 816 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 824 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 825 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 817 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 826 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 818 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 827 | 819 | ||
| ... | @@ -838,7 +830,6 @@ test "array multiplication sets the sentinel - value" { | ... | @@ -838,7 +830,6 @@ test "array multiplication sets the sentinel - value" { |
| 838 | 830 | ||
| 839 | test "array multiplication sets the sentinel - pointer" { | 831 | test "array multiplication sets the sentinel - pointer" { |
| 840 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 832 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 841 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 842 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 833 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 843 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 834 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 844 | 835 |
test/behavior/export_self_referential_type_info.zig+1-1| ... | @@ -1 +1 @@ | ... | @@ -1 +1 @@ |
| 1 | export const foo: c_int = @boolToInt(@typeInfo(@This()).Struct.is_tuple); | 1 | export const self_referential_type_info: c_int = @boolToInt(@typeInfo(@This()).Struct.is_tuple); |
test/behavior/field_parent_ptr.zig-2| ... | @@ -4,7 +4,6 @@ const builtin = @import("builtin"); | ... | @@ -4,7 +4,6 @@ const builtin = @import("builtin"); |
| 4 | test "@fieldParentPtr non-first field" { | 4 | test "@fieldParentPtr non-first field" { |
| 5 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 5 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 6 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 6 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 7 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 8 | try testParentFieldPtr(&foo.c); | 7 | try testParentFieldPtr(&foo.c); |
| 9 | comptime try testParentFieldPtr(&foo.c); | 8 | comptime try testParentFieldPtr(&foo.c); |
| 10 | } | 9 | } |
| ... | @@ -12,7 +11,6 @@ test "@fieldParentPtr non-first field" { | ... | @@ -12,7 +11,6 @@ test "@fieldParentPtr non-first field" { |
| 12 | test "@fieldParentPtr first field" { | 11 | test "@fieldParentPtr first field" { |
| 13 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 12 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 14 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 13 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 15 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 16 | try testParentFieldPtrFirst(&foo.a); | 14 | try testParentFieldPtrFirst(&foo.a); |
| 17 | comptime try testParentFieldPtrFirst(&foo.a); | 15 | comptime try testParentFieldPtrFirst(&foo.a); |
| 18 | } | 16 | } |
test/behavior/floatop.zig-15| ... | @@ -21,7 +21,6 @@ fn epsForType(comptime T: type) T { | ... | @@ -21,7 +21,6 @@ fn epsForType(comptime T: type) T { |
| 21 | 21 | ||
| 22 | test "floating point comparisons" { | 22 | test "floating point comparisons" { |
| 23 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 23 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 24 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 25 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 24 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 26 | 25 | ||
| 27 | try testFloatComparisons(); | 26 | try testFloatComparisons(); |
| ... | @@ -55,7 +54,6 @@ fn testFloatComparisons() !void { | ... | @@ -55,7 +54,6 @@ fn testFloatComparisons() !void { |
| 55 | 54 | ||
| 56 | test "different sized float comparisons" { | 55 | test "different sized float comparisons" { |
| 57 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 56 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 58 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 59 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 57 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 60 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 58 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 61 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 59 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -91,7 +89,6 @@ fn testDifferentSizedFloatComparisons() !void { | ... | @@ -91,7 +89,6 @@ fn testDifferentSizedFloatComparisons() !void { |
| 91 | 89 | ||
| 92 | test "negative f128 floatToInt at compile-time" { | 90 | test "negative f128 floatToInt at compile-time" { |
| 93 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 91 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 94 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 95 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 92 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 96 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 93 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 97 | 94 | ||
| ... | @@ -150,7 +147,6 @@ fn testSqrt() !void { | ... | @@ -150,7 +147,6 @@ fn testSqrt() !void { |
| 150 | 147 | ||
| 151 | test "more @sqrt f16 tests" { | 148 | test "more @sqrt f16 tests" { |
| 152 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 149 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 153 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 154 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 150 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 155 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 151 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 156 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 152 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -305,7 +301,6 @@ test "@log" { | ... | @@ -305,7 +301,6 @@ test "@log" { |
| 305 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 301 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 306 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 302 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 307 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 303 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 308 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 309 | 304 | ||
| 310 | comptime try testLog(); | 305 | comptime try testLog(); |
| 311 | try testLog(); | 306 | try testLog(); |
| ... | @@ -545,7 +540,6 @@ fn testTrunc() !void { | ... | @@ -545,7 +540,6 @@ fn testTrunc() !void { |
| 545 | 540 | ||
| 546 | test "negation f16" { | 541 | test "negation f16" { |
| 547 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 542 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 548 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 549 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 543 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 550 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 544 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 551 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 545 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -573,7 +567,6 @@ test "negation f32" { | ... | @@ -573,7 +567,6 @@ test "negation f32" { |
| 573 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 567 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 574 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 568 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 575 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 569 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 576 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 577 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 570 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 578 | 571 | ||
| 579 | const S = struct { | 572 | const S = struct { |
| ... | @@ -595,7 +588,6 @@ test "negation f64" { | ... | @@ -595,7 +588,6 @@ test "negation f64" { |
| 595 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 588 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 596 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 589 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 597 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 590 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 598 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 599 | 591 | ||
| 600 | const S = struct { | 592 | const S = struct { |
| 601 | fn doTheTest() !void { | 593 | fn doTheTest() !void { |
| ... | @@ -615,7 +607,6 @@ test "negation f80" { | ... | @@ -615,7 +607,6 @@ test "negation f80" { |
| 615 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 607 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 616 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 608 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 617 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 609 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 618 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 619 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 610 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 620 | 611 | ||
| 621 | const S = struct { | 612 | const S = struct { |
| ... | @@ -636,7 +627,6 @@ test "negation f128" { | ... | @@ -636,7 +627,6 @@ test "negation f128" { |
| 636 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 627 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 637 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 628 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 638 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 629 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 639 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 640 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 630 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 641 | 631 | ||
| 642 | const S = struct { | 632 | const S = struct { |
| ... | @@ -680,7 +670,6 @@ test "comptime fixed-width float zero divided by zero produces NaN" { | ... | @@ -680,7 +670,6 @@ test "comptime fixed-width float zero divided by zero produces NaN" { |
| 680 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 670 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 681 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 671 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 682 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 672 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 683 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 684 | 673 | ||
| 685 | inline for (.{ f16, f32, f64, f80, f128 }) |F| { | 674 | inline for (.{ f16, f32, f64, f80, f128 }) |F| { |
| 686 | try expect(math.isNan(@as(F, 0) / @as(F, 0))); | 675 | try expect(math.isNan(@as(F, 0) / @as(F, 0))); |
| ... | @@ -716,7 +705,6 @@ test "nan negation f16" { | ... | @@ -716,7 +705,6 @@ test "nan negation f16" { |
| 716 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 705 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 717 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 706 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 718 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 707 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 719 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 720 | 708 | ||
| 721 | const nan_comptime = comptime math.nan(f16); | 709 | const nan_comptime = comptime math.nan(f16); |
| 722 | const neg_nan_comptime = -nan_comptime; | 710 | const neg_nan_comptime = -nan_comptime; |
| ... | @@ -736,7 +724,6 @@ test "nan negation f32" { | ... | @@ -736,7 +724,6 @@ test "nan negation f32" { |
| 736 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 724 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 737 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 725 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 738 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 726 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 739 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 740 | 727 | ||
| 741 | const nan_comptime = comptime math.nan(f32); | 728 | const nan_comptime = comptime math.nan(f32); |
| 742 | const neg_nan_comptime = -nan_comptime; | 729 | const neg_nan_comptime = -nan_comptime; |
| ... | @@ -756,7 +743,6 @@ test "nan negation f64" { | ... | @@ -756,7 +743,6 @@ test "nan negation f64" { |
| 756 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 743 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 757 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 744 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 758 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 745 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 759 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 760 | 746 | ||
| 761 | const nan_comptime = comptime math.nan(f64); | 747 | const nan_comptime = comptime math.nan(f64); |
| 762 | const neg_nan_comptime = -nan_comptime; | 748 | const neg_nan_comptime = -nan_comptime; |
| ... | @@ -776,7 +762,6 @@ test "nan negation f128" { | ... | @@ -776,7 +762,6 @@ test "nan negation f128" { |
| 776 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 762 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 777 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 763 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 778 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 764 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 779 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 780 | 765 | ||
| 781 | const nan_comptime = comptime math.nan(f128); | 766 | const nan_comptime = comptime math.nan(f128); |
| 782 | const neg_nan_comptime = -nan_comptime; | 767 | const neg_nan_comptime = -nan_comptime; |
test/behavior/fn.zig-8| ... | @@ -97,7 +97,6 @@ test "discard the result of a function that returns a struct" { | ... | @@ -97,7 +97,6 @@ test "discard the result of a function that returns a struct" { |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" { | 99 | test "inline function call that calls optional function pointer, return pointer at callsite interacts correctly with callsite return type" { |
| 100 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 101 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 100 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 102 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 101 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 103 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 102 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | @@ -146,7 +145,6 @@ fn fnWithUnreachable() noreturn { | ... | @@ -146,7 +145,6 @@ fn fnWithUnreachable() noreturn { |
| 146 | } | 145 | } |
| 147 | 146 | ||
| 148 | test "extern struct with stdcallcc fn pointer" { | 147 | test "extern struct with stdcallcc fn pointer" { |
| 149 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 150 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 148 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 151 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 149 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 152 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 150 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| ... | @@ -274,7 +272,6 @@ test "void parameters" { | ... | @@ -274,7 +272,6 @@ test "void parameters" { |
| 274 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 272 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 275 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 273 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 276 | 274 | ||
| 277 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 278 | try voidFun(1, void{}, 2, {}); | 275 | try voidFun(1, void{}, 2, {}); |
| 279 | } | 276 | } |
| 280 | fn voidFun(a: i32, b: void, c: i32, d: void) !void { | 277 | fn voidFun(a: i32, b: void, c: i32, d: void) !void { |
| ... | @@ -286,7 +283,6 @@ fn voidFun(a: i32, b: void, c: i32, d: void) !void { | ... | @@ -286,7 +283,6 @@ fn voidFun(a: i32, b: void, c: i32, d: void) !void { |
| 286 | } | 283 | } |
| 287 | 284 | ||
| 288 | test "call function with empty string" { | 285 | test "call function with empty string" { |
| 289 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 290 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 286 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 291 | 287 | ||
| 292 | acceptsString(""); | 288 | acceptsString(""); |
| ... | @@ -305,7 +301,6 @@ test "function pointers" { | ... | @@ -305,7 +301,6 @@ test "function pointers" { |
| 305 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 301 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 306 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 302 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 307 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 303 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 308 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 309 | 304 | ||
| 310 | const fns = [_]*const @TypeOf(fn1){ | 305 | const fns = [_]*const @TypeOf(fn1){ |
| 311 | &fn1, | 306 | &fn1, |
| ... | @@ -399,8 +394,6 @@ test "ability to give comptime types and non comptime types to same parameter" { | ... | @@ -399,8 +394,6 @@ test "ability to give comptime types and non comptime types to same parameter" { |
| 399 | } | 394 | } |
| 400 | 395 | ||
| 401 | test "function with inferred error set but returning no error" { | 396 | test "function with inferred error set but returning no error" { |
| 402 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 403 | |||
| 404 | const S = struct { | 397 | const S = struct { |
| 405 | fn foo() !void {} | 398 | fn foo() !void {} |
| 406 | }; | 399 | }; |
| ... | @@ -410,7 +403,6 @@ test "function with inferred error set but returning no error" { | ... | @@ -410,7 +403,6 @@ test "function with inferred error set but returning no error" { |
| 410 | } | 403 | } |
| 411 | 404 | ||
| 412 | test "import passed byref to function in return type" { | 405 | test "import passed byref to function in return type" { |
| 413 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 414 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 406 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 415 | 407 | ||
| 416 | const S = struct { | 408 | const S = struct { |
test/behavior/for.zig-1| ... | @@ -195,7 +195,6 @@ test "for on slice with allowzero ptr" { | ... | @@ -195,7 +195,6 @@ test "for on slice with allowzero ptr" { |
| 195 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 195 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 196 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 196 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 197 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 197 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 198 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 199 | 198 | ||
| 200 | const S = struct { | 199 | const S = struct { |
| 201 | fn doTheTest(slice: []const u8) !void { | 200 | fn doTheTest(slice: []const u8) !void { |
test/behavior/generics.zig+5-5| ... | @@ -204,7 +204,6 @@ fn foo2(arg: anytype) bool { | ... | @@ -204,7 +204,6 @@ fn foo2(arg: anytype) bool { |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | test "generic struct" { | 206 | test "generic struct" { |
| 207 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 208 | var a1 = GenNode(i32){ | 207 | var a1 = GenNode(i32){ |
| 209 | .value = 13, | 208 | .value = 13, |
| 210 | .next = null, | 209 | .next = null, |
| ... | @@ -361,13 +360,14 @@ test "nested generic function" { | ... | @@ -361,13 +360,14 @@ test "nested generic function" { |
| 361 | 360 | ||
| 362 | test "extern function used as generic parameter" { | 361 | test "extern function used as generic parameter" { |
| 363 | const S = struct { | 362 | const S = struct { |
| 364 | extern fn foo() void; | 363 | extern fn usedAsGenericParameterFoo() void; |
| 365 | extern fn bar() void; | 364 | extern fn usedAsGenericParameterBar() void; |
| 366 | inline fn baz(comptime _: anytype) type { | 365 | inline fn usedAsGenericParameterBaz(comptime _: anytype) type { |
| 367 | return struct {}; | 366 | return struct {}; |
| 368 | } | 367 | } |
| 369 | }; | 368 | }; |
| 370 | try expect(S.baz(S.foo) != S.baz(S.bar)); | 369 | try expect(S.usedAsGenericParameterBaz(S.usedAsGenericParameterFoo) != |
| 370 | S.usedAsGenericParameterBaz(S.usedAsGenericParameterBar)); | ||
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | test "generic struct as parameter type" { | 373 | test "generic struct as parameter type" { |
test/behavior/int128.zig-1| ... | @@ -43,7 +43,6 @@ test "int128" { | ... | @@ -43,7 +43,6 @@ test "int128" { |
| 43 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 43 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 44 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 44 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 45 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 45 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 46 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 47 | 46 | ||
| 48 | var buff: i128 = -1; | 47 | var buff: i128 = -1; |
| 49 | try expect(buff < 0 and (buff + 1) == 0); | 48 | try expect(buff < 0 and (buff + 1) == 0); |
test/behavior/math.zig-41| ... | @@ -376,7 +376,6 @@ fn testBinaryNot(x: u16) !void { | ... | @@ -376,7 +376,6 @@ fn testBinaryNot(x: u16) !void { |
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | test "division" { | 378 | test "division" { |
| 379 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 380 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 379 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 381 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 380 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 382 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 381 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -453,7 +452,6 @@ fn testDivision() !void { | ... | @@ -453,7 +452,6 @@ fn testDivision() !void { |
| 453 | } | 452 | } |
| 454 | 453 | ||
| 455 | test "division half-precision floats" { | 454 | test "division half-precision floats" { |
| 456 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 457 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 455 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 458 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 456 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 459 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 457 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -603,7 +601,6 @@ fn should_not_be_zero(x: f128) !void { | ... | @@ -603,7 +601,6 @@ fn should_not_be_zero(x: f128) !void { |
| 603 | } | 601 | } |
| 604 | 602 | ||
| 605 | test "128-bit multiplication" { | 603 | test "128-bit multiplication" { |
| 606 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 607 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 604 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 608 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 605 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 609 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 606 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -616,8 +613,6 @@ test "128-bit multiplication" { | ... | @@ -616,8 +613,6 @@ test "128-bit multiplication" { |
| 616 | } | 613 | } |
| 617 | 614 | ||
| 618 | test "@addWithOverflow" { | 615 | test "@addWithOverflow" { |
| 619 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 620 | |||
| 621 | { | 616 | { |
| 622 | var result: u8 = undefined; | 617 | var result: u8 = undefined; |
| 623 | try expect(@addWithOverflow(u8, 250, 100, &result)); | 618 | try expect(@addWithOverflow(u8, 250, 100, &result)); |
| ... | @@ -652,8 +647,6 @@ test "@addWithOverflow" { | ... | @@ -652,8 +647,6 @@ test "@addWithOverflow" { |
| 652 | } | 647 | } |
| 653 | 648 | ||
| 654 | test "small int addition" { | 649 | test "small int addition" { |
| 655 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 656 | |||
| 657 | var x: u2 = 0; | 650 | var x: u2 = 0; |
| 658 | try expect(x == 0); | 651 | try expect(x == 0); |
| 659 | 652 | ||
| ... | @@ -673,8 +666,6 @@ test "small int addition" { | ... | @@ -673,8 +666,6 @@ test "small int addition" { |
| 673 | } | 666 | } |
| 674 | 667 | ||
| 675 | test "basic @mulWithOverflow" { | 668 | test "basic @mulWithOverflow" { |
| 676 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 677 | |||
| 678 | var result: u8 = undefined; | 669 | var result: u8 = undefined; |
| 679 | try expect(@mulWithOverflow(u8, 86, 3, &result)); | 670 | try expect(@mulWithOverflow(u8, 86, 3, &result)); |
| 680 | try expect(result == 2); | 671 | try expect(result == 2); |
| ... | @@ -693,7 +684,6 @@ test "basic @mulWithOverflow" { | ... | @@ -693,7 +684,6 @@ test "basic @mulWithOverflow" { |
| 693 | 684 | ||
| 694 | // TODO migrate to this for all backends once they handle more cases | 685 | // TODO migrate to this for all backends once they handle more cases |
| 695 | test "extensive @mulWithOverflow" { | 686 | test "extensive @mulWithOverflow" { |
| 696 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 697 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 687 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 698 | 688 | ||
| 699 | { | 689 | { |
| ... | @@ -843,7 +833,6 @@ test "extensive @mulWithOverflow" { | ... | @@ -843,7 +833,6 @@ test "extensive @mulWithOverflow" { |
| 843 | } | 833 | } |
| 844 | 834 | ||
| 845 | test "@mulWithOverflow bitsize > 32" { | 835 | test "@mulWithOverflow bitsize > 32" { |
| 846 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 847 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 836 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 848 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 837 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 849 | 838 | ||
| ... | @@ -897,8 +886,6 @@ test "@mulWithOverflow bitsize > 32" { | ... | @@ -897,8 +886,6 @@ test "@mulWithOverflow bitsize > 32" { |
| 897 | } | 886 | } |
| 898 | 887 | ||
| 899 | test "@subWithOverflow" { | 888 | test "@subWithOverflow" { |
| 900 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 901 | |||
| 902 | { | 889 | { |
| 903 | var result: u8 = undefined; | 890 | var result: u8 = undefined; |
| 904 | try expect(@subWithOverflow(u8, 1, 2, &result)); | 891 | try expect(@subWithOverflow(u8, 1, 2, &result)); |
| ... | @@ -933,8 +920,6 @@ test "@subWithOverflow" { | ... | @@ -933,8 +920,6 @@ test "@subWithOverflow" { |
| 933 | } | 920 | } |
| 934 | 921 | ||
| 935 | test "@shlWithOverflow" { | 922 | test "@shlWithOverflow" { |
| 936 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 937 | |||
| 938 | { | 923 | { |
| 939 | var result: u4 = undefined; | 924 | var result: u4 = undefined; |
| 940 | var a: u4 = 2; | 925 | var a: u4 = 2; |
| ... | @@ -977,8 +962,6 @@ test "@shlWithOverflow" { | ... | @@ -977,8 +962,6 @@ test "@shlWithOverflow" { |
| 977 | } | 962 | } |
| 978 | 963 | ||
| 979 | test "overflow arithmetic with u0 values" { | 964 | test "overflow arithmetic with u0 values" { |
| 980 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 981 | |||
| 982 | var result: u0 = undefined; | 965 | var result: u0 = undefined; |
| 983 | try expect(!@addWithOverflow(u0, 0, 0, &result)); | 966 | try expect(!@addWithOverflow(u0, 0, 0, &result)); |
| 984 | try expect(result == 0); | 967 | try expect(result == 0); |
| ... | @@ -1007,7 +990,6 @@ test "allow signed integer division/remainder when values are comptime-known and | ... | @@ -1007,7 +990,6 @@ test "allow signed integer division/remainder when values are comptime-known and |
| 1007 | } | 990 | } |
| 1008 | 991 | ||
| 1009 | test "quad hex float literal parsing accurate" { | 992 | test "quad hex float literal parsing accurate" { |
| 1010 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1011 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 993 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1012 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 994 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1013 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 995 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -1163,7 +1145,6 @@ test "comptime float rem int" { | ... | @@ -1163,7 +1145,6 @@ test "comptime float rem int" { |
| 1163 | 1145 | ||
| 1164 | test "remainder division" { | 1146 | test "remainder division" { |
| 1165 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1147 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1166 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1167 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1148 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1168 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1149 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1169 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1150 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1196,7 +1177,6 @@ fn remdivOne(comptime T: type, a: T, b: T, c: T) !void { | ... | @@ -1196,7 +1177,6 @@ fn remdivOne(comptime T: type, a: T, b: T, c: T) !void { |
| 1196 | 1177 | ||
| 1197 | test "float remainder division using @rem" { | 1178 | test "float remainder division using @rem" { |
| 1198 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1179 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1199 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1200 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1180 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1201 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1181 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1202 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1182 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1240,7 +1220,6 @@ fn fremOne(comptime T: type, a: T, b: T, c: T, epsilon: T) !void { | ... | @@ -1240,7 +1220,6 @@ fn fremOne(comptime T: type, a: T, b: T, c: T, epsilon: T) !void { |
| 1240 | 1220 | ||
| 1241 | test "float modulo division using @mod" { | 1221 | test "float modulo division using @mod" { |
| 1242 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1222 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1243 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1244 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1223 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1245 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1224 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1246 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1225 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| ... | @@ -1286,7 +1265,6 @@ test "@sqrt" { | ... | @@ -1286,7 +1265,6 @@ test "@sqrt" { |
| 1286 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1265 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1287 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1266 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1288 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1267 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1289 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1290 | 1268 | ||
| 1291 | try testSqrt(f64, 12.0); | 1269 | try testSqrt(f64, 12.0); |
| 1292 | comptime try testSqrt(f64, 12.0); | 1270 | comptime try testSqrt(f64, 12.0); |
| ... | @@ -1312,7 +1290,6 @@ test "@fabs" { | ... | @@ -1312,7 +1290,6 @@ test "@fabs" { |
| 1312 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1290 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1313 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1291 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1314 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1292 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1315 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1316 | 1293 | ||
| 1317 | try testFabs(f128, 12.0); | 1294 | try testFabs(f128, 12.0); |
| 1318 | comptime try testFabs(f128, 12.0); | 1295 | comptime try testFabs(f128, 12.0); |
| ... | @@ -1334,7 +1311,6 @@ test "@fabs f80" { | ... | @@ -1334,7 +1311,6 @@ test "@fabs f80" { |
| 1334 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1311 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1335 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1312 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1336 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1313 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1337 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1338 | 1314 | ||
| 1339 | try testFabs(f80, 12.0); | 1315 | try testFabs(f80, 12.0); |
| 1340 | comptime try testFabs(f80, 12.0); | 1316 | comptime try testFabs(f80, 12.0); |
| ... | @@ -1351,7 +1327,6 @@ test "@floor" { | ... | @@ -1351,7 +1327,6 @@ test "@floor" { |
| 1351 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1327 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1352 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1328 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1353 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1329 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1354 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1355 | 1330 | ||
| 1356 | try testFloor(f64, 12.0); | 1331 | try testFloor(f64, 12.0); |
| 1357 | comptime try testFloor(f64, 12.0); | 1332 | comptime try testFloor(f64, 12.0); |
| ... | @@ -1371,7 +1346,6 @@ test "@floor f80" { | ... | @@ -1371,7 +1346,6 @@ test "@floor f80" { |
| 1371 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1346 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1372 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1347 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1373 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1348 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1374 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1375 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 | 1349 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 |
| 1376 | 1350 | ||
| 1377 | try testFloor(f80, 12.0); | 1351 | try testFloor(f80, 12.0); |
| ... | @@ -1383,7 +1357,6 @@ test "@floor f128" { | ... | @@ -1383,7 +1357,6 @@ test "@floor f128" { |
| 1383 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1357 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1384 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1358 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1385 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1359 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1386 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1387 | 1360 | ||
| 1388 | try testFloor(f128, 12.0); | 1361 | try testFloor(f128, 12.0); |
| 1389 | comptime try testFloor(f128, 12.0); | 1362 | comptime try testFloor(f128, 12.0); |
| ... | @@ -1400,7 +1373,6 @@ test "@ceil" { | ... | @@ -1400,7 +1373,6 @@ test "@ceil" { |
| 1400 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1373 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1401 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1374 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1402 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1375 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1403 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1404 | 1376 | ||
| 1405 | try testCeil(f64, 12.0); | 1377 | try testCeil(f64, 12.0); |
| 1406 | comptime try testCeil(f64, 12.0); | 1378 | comptime try testCeil(f64, 12.0); |
| ... | @@ -1420,7 +1392,6 @@ test "@ceil f80" { | ... | @@ -1420,7 +1392,6 @@ test "@ceil f80" { |
| 1420 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1392 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1421 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1393 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1422 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1394 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1423 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1424 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 | 1395 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 |
| 1425 | 1396 | ||
| 1426 | try testCeil(f80, 12.0); | 1397 | try testCeil(f80, 12.0); |
| ... | @@ -1432,7 +1403,6 @@ test "@ceil f128" { | ... | @@ -1432,7 +1403,6 @@ test "@ceil f128" { |
| 1432 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1403 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1433 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1404 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1434 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1405 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1435 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1436 | 1406 | ||
| 1437 | try testCeil(f128, 12.0); | 1407 | try testCeil(f128, 12.0); |
| 1438 | comptime try testCeil(f128, 12.0); | 1408 | comptime try testCeil(f128, 12.0); |
| ... | @@ -1449,7 +1419,6 @@ test "@trunc" { | ... | @@ -1449,7 +1419,6 @@ test "@trunc" { |
| 1449 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1419 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1450 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1420 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1451 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1421 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1452 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1453 | 1422 | ||
| 1454 | try testTrunc(f64, 12.0); | 1423 | try testTrunc(f64, 12.0); |
| 1455 | comptime try testTrunc(f64, 12.0); | 1424 | comptime try testTrunc(f64, 12.0); |
| ... | @@ -1469,7 +1438,6 @@ test "@trunc f80" { | ... | @@ -1469,7 +1438,6 @@ test "@trunc f80" { |
| 1469 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1438 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1470 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1439 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1471 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1440 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1472 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1473 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 | 1441 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 |
| 1474 | 1442 | ||
| 1475 | try testTrunc(f80, 12.0); | 1443 | try testTrunc(f80, 12.0); |
| ... | @@ -1487,7 +1455,6 @@ test "@trunc f128" { | ... | @@ -1487,7 +1455,6 @@ test "@trunc f128" { |
| 1487 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1455 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1488 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1456 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1489 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1457 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1490 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1491 | 1458 | ||
| 1492 | try testTrunc(f128, 12.0); | 1459 | try testTrunc(f128, 12.0); |
| 1493 | comptime try testTrunc(f128, 12.0); | 1460 | comptime try testTrunc(f128, 12.0); |
| ... | @@ -1512,7 +1479,6 @@ test "@round" { | ... | @@ -1512,7 +1479,6 @@ test "@round" { |
| 1512 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1479 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1513 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1480 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1514 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1481 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1515 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1516 | 1482 | ||
| 1517 | try testRound(f64, 12.0); | 1483 | try testRound(f64, 12.0); |
| 1518 | comptime try testRound(f64, 12.0); | 1484 | comptime try testRound(f64, 12.0); |
| ... | @@ -1532,7 +1498,6 @@ test "@round f80" { | ... | @@ -1532,7 +1498,6 @@ test "@round f80" { |
| 1532 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1498 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1533 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1499 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1534 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1500 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1535 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1536 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 | 1501 | if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/12602 |
| 1537 | 1502 | ||
| 1538 | try testRound(f80, 12.0); | 1503 | try testRound(f80, 12.0); |
| ... | @@ -1544,7 +1509,6 @@ test "@round f128" { | ... | @@ -1544,7 +1509,6 @@ test "@round f128" { |
| 1544 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1509 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1545 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1510 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1546 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1511 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1547 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1548 | 1512 | ||
| 1549 | try testRound(f128, 12.0); | 1513 | try testRound(f128, 12.0); |
| 1550 | comptime try testRound(f128, 12.0); | 1514 | comptime try testRound(f128, 12.0); |
| ... | @@ -1578,7 +1542,6 @@ test "vector integer addition" { | ... | @@ -1578,7 +1542,6 @@ test "vector integer addition" { |
| 1578 | } | 1542 | } |
| 1579 | 1543 | ||
| 1580 | test "NaN comparison" { | 1544 | test "NaN comparison" { |
| 1581 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1582 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1545 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1583 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1546 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1584 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1547 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -1595,7 +1558,6 @@ test "NaN comparison" { | ... | @@ -1595,7 +1558,6 @@ test "NaN comparison" { |
| 1595 | } | 1558 | } |
| 1596 | 1559 | ||
| 1597 | test "NaN comparison f80" { | 1560 | test "NaN comparison f80" { |
| 1598 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1599 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1561 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1600 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1562 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1601 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1563 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -1647,7 +1609,6 @@ test "compare undefined literal with comptime_int" { | ... | @@ -1647,7 +1609,6 @@ test "compare undefined literal with comptime_int" { |
| 1647 | } | 1609 | } |
| 1648 | 1610 | ||
| 1649 | test "signed zeros are represented properly" { | 1611 | test "signed zeros are represented properly" { |
| 1650 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1651 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1612 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1652 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1613 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1653 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1614 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -1688,7 +1649,6 @@ test "fabs" { | ... | @@ -1688,7 +1649,6 @@ test "fabs" { |
| 1688 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1649 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1689 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1650 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1690 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1651 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1691 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1692 | 1652 | ||
| 1693 | inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| { | 1653 | inline for ([_]type{ f16, f32, f64, f80, f128, c_longdouble }) |T| { |
| 1694 | // normals | 1654 | // normals |
| ... | @@ -1717,7 +1677,6 @@ test "absFloat" { | ... | @@ -1717,7 +1677,6 @@ test "absFloat" { |
| 1717 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1677 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1718 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1678 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1719 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1679 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1720 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1721 | 1680 | ||
| 1722 | try testAbsFloat(); | 1681 | try testAbsFloat(); |
| 1723 | comptime try testAbsFloat(); | 1682 | comptime try testAbsFloat(); |
test/behavior/maximum_minimum.zig-2| ... | @@ -6,7 +6,6 @@ const expectEqual = std.testing.expectEqual; | ... | @@ -6,7 +6,6 @@ const expectEqual = std.testing.expectEqual; |
| 6 | 6 | ||
| 7 | test "@max" { | 7 | test "@max" { |
| 8 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 8 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 9 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 9 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 12 | 11 | ||
| ... | @@ -55,7 +54,6 @@ test "@min" { | ... | @@ -55,7 +54,6 @@ test "@min" { |
| 55 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 54 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 56 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 55 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 57 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 56 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 58 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 59 | 57 | ||
| 60 | const S = struct { | 58 | const S = struct { |
| 61 | fn doTheTest() !void { | 59 | fn doTheTest() !void { |
test/behavior/muladd.zig-4| ... | @@ -2,7 +2,6 @@ const builtin = @import("builtin"); | ... | @@ -2,7 +2,6 @@ const builtin = @import("builtin"); |
| 2 | const expect = @import("std").testing.expect; | 2 | const expect = @import("std").testing.expect; |
| 3 | 3 | ||
| 4 | test "@mulAdd" { | 4 | test "@mulAdd" { |
| 5 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 6 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 5 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 7 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 6 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 8 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 7 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -28,7 +27,6 @@ fn testMulAdd() !void { | ... | @@ -28,7 +27,6 @@ fn testMulAdd() !void { |
| 28 | 27 | ||
| 29 | test "@mulAdd f16" { | 28 | test "@mulAdd f16" { |
| 30 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 29 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 31 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 32 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 30 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 33 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 31 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 34 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 32 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -46,7 +44,6 @@ fn testMulAdd16() !void { | ... | @@ -46,7 +44,6 @@ fn testMulAdd16() !void { |
| 46 | 44 | ||
| 47 | test "@mulAdd f80" { | 45 | test "@mulAdd f80" { |
| 48 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 46 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 49 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 50 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 47 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 51 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 48 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 52 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 49 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -65,7 +62,6 @@ fn testMulAdd80() !void { | ... | @@ -65,7 +62,6 @@ fn testMulAdd80() !void { |
| 65 | } | 62 | } |
| 66 | 63 | ||
| 67 | test "@mulAdd f128" { | 64 | test "@mulAdd f128" { |
| 68 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 69 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 65 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 70 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 66 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 71 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 67 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
test/behavior/optional.zig-3| ... | @@ -66,7 +66,6 @@ test "optional with void type" { | ... | @@ -66,7 +66,6 @@ test "optional with void type" { |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | test "address of unwrap optional" { | 68 | test "address of unwrap optional" { |
| 69 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 70 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 69 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 71 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 70 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 72 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 71 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| ... | @@ -270,7 +269,6 @@ test "0-bit child type coerced to optional return ptr result location" { | ... | @@ -270,7 +269,6 @@ test "0-bit child type coerced to optional return ptr result location" { |
| 270 | } | 269 | } |
| 271 | 270 | ||
| 272 | test "0-bit child type coerced to optional" { | 271 | test "0-bit child type coerced to optional" { |
| 273 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 274 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 272 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 275 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 273 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 276 | 274 | ||
| ... | @@ -333,7 +331,6 @@ test "array of optional unaligned types" { | ... | @@ -333,7 +331,6 @@ test "array of optional unaligned types" { |
| 333 | } | 331 | } |
| 334 | 332 | ||
| 335 | test "optional pointer to zero bit optional payload" { | 333 | test "optional pointer to zero bit optional payload" { |
| 336 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 337 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 334 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 338 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 335 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 339 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 336 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
test/behavior/packed-struct.zig-6| ... | @@ -150,7 +150,6 @@ test "consistent size of packed structs" { | ... | @@ -150,7 +150,6 @@ test "consistent size of packed structs" { |
| 150 | 150 | ||
| 151 | test "correct sizeOf and offsets in packed structs" { | 151 | test "correct sizeOf and offsets in packed structs" { |
| 152 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 152 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 153 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 154 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 153 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 155 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 154 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 156 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 155 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -221,7 +220,6 @@ test "correct sizeOf and offsets in packed structs" { | ... | @@ -221,7 +220,6 @@ test "correct sizeOf and offsets in packed structs" { |
| 221 | 220 | ||
| 222 | test "nested packed structs" { | 221 | test "nested packed structs" { |
| 223 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 222 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 224 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 225 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 223 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 226 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 224 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 227 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 225 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -270,7 +268,6 @@ test "nested packed structs" { | ... | @@ -270,7 +268,6 @@ test "nested packed structs" { |
| 270 | 268 | ||
| 271 | test "regular in irregular packed struct" { | 269 | test "regular in irregular packed struct" { |
| 272 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 270 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 273 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 274 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 271 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 275 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 272 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 276 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 273 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | @@ -293,7 +290,6 @@ test "regular in irregular packed struct" { | ... | @@ -293,7 +290,6 @@ test "regular in irregular packed struct" { |
| 293 | test "byte-aligned field pointer offsets" { | 290 | test "byte-aligned field pointer offsets" { |
| 294 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 291 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 295 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 292 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 296 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 297 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 293 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 298 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 294 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 299 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 295 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | @@ -396,7 +392,6 @@ test "byte-aligned field pointer offsets" { | ... | @@ -396,7 +392,6 @@ test "byte-aligned field pointer offsets" { |
| 396 | 392 | ||
| 397 | test "load pointer from packed struct" { | 393 | test "load pointer from packed struct" { |
| 398 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 394 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 399 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 400 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 395 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 401 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 396 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 402 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 397 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | @@ -418,7 +413,6 @@ test "load pointer from packed struct" { | ... | @@ -418,7 +413,6 @@ test "load pointer from packed struct" { |
| 418 | } | 413 | } |
| 419 | 414 | ||
| 420 | test "@ptrToInt on a packed struct field" { | 415 | test "@ptrToInt on a packed struct field" { |
| 421 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 422 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; | 416 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; |
| 423 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 417 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 424 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 418 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
test/behavior/packed_struct_explicit_backing_int.zig-1| ... | @@ -6,7 +6,6 @@ const native_endian = builtin.cpu.arch.endian(); | ... | @@ -6,7 +6,6 @@ const native_endian = builtin.cpu.arch.endian(); |
| 6 | 6 | ||
| 7 | test "packed struct explicit backing integer" { | 7 | test "packed struct explicit backing integer" { |
| 8 | assert(builtin.zig_backend != .stage1); | 8 | assert(builtin.zig_backend != .stage1); |
| 9 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 10 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 9 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 12 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 11 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
test/behavior/pointers.zig-4| ... | @@ -157,7 +157,6 @@ test "implicit casting between C pointer and optional non-C pointer" { | ... | @@ -157,7 +157,6 @@ test "implicit casting between C pointer and optional non-C pointer" { |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | test "implicit cast error unions with non-optional to optional pointer" { | 159 | test "implicit cast error unions with non-optional to optional pointer" { |
| 160 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 161 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 160 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 162 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 161 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 163 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 162 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -205,7 +204,6 @@ test "allowzero pointer and slice" { | ... | @@ -205,7 +204,6 @@ test "allowzero pointer and slice" { |
| 205 | } | 204 | } |
| 206 | 205 | ||
| 207 | test "assign null directly to C pointer and test null equality" { | 206 | test "assign null directly to C pointer and test null equality" { |
| 208 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 209 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 207 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 210 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 208 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 211 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 209 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -337,7 +335,6 @@ test "pointer sentinel with optional element" { | ... | @@ -337,7 +335,6 @@ test "pointer sentinel with optional element" { |
| 337 | 335 | ||
| 338 | test "pointer sentinel with +inf" { | 336 | test "pointer sentinel with +inf" { |
| 339 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 337 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 340 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 341 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 338 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 342 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 339 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 343 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 340 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| ... | @@ -404,7 +401,6 @@ test "@ptrToInt on null optional at comptime" { | ... | @@ -404,7 +401,6 @@ test "@ptrToInt on null optional at comptime" { |
| 404 | } | 401 | } |
| 405 | 402 | ||
| 406 | test "indexing array with sentinel returns correct type" { | 403 | test "indexing array with sentinel returns correct type" { |
| 407 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 408 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 404 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 409 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 405 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 410 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 406 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
test/behavior/ptrcast.zig-1| ... | @@ -133,7 +133,6 @@ test "lower reinterpreted comptime field ptr (with under-aligned fields)" { | ... | @@ -133,7 +133,6 @@ test "lower reinterpreted comptime field ptr (with under-aligned fields)" { |
| 133 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 133 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 134 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 134 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 135 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 135 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 136 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO: CBE does not yet support under-aligned fields | ||
| 137 | 136 | ||
| 138 | // Test lowering a field ptr | 137 | // Test lowering a field ptr |
| 139 | comptime var bytes align(2) = [_]u8{ 1, 2, 3, 4, 5, 6 }; | 138 | comptime var bytes align(2) = [_]u8{ 1, 2, 3, 4, 5, 6 }; |
test/behavior/saturating_arithmetic.zig-7| ... | @@ -8,7 +8,6 @@ test "saturating add" { | ... | @@ -8,7 +8,6 @@ test "saturating add" { |
| 8 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 8 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 12 | 11 | ||
| 13 | const S = struct { | 12 | const S = struct { |
| 14 | fn doTheTest() !void { | 13 | fn doTheTest() !void { |
| ... | @@ -55,7 +54,6 @@ test "saturating add 128bit" { | ... | @@ -55,7 +54,6 @@ test "saturating add 128bit" { |
| 55 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 54 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 56 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 55 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 57 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 56 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 58 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 59 | const S = struct { | 57 | const S = struct { |
| 60 | fn doTheTest() !void { | 58 | fn doTheTest() !void { |
| 61 | try testSatAdd(i128, maxInt(i128), -maxInt(i128), 0); | 59 | try testSatAdd(i128, maxInt(i128), -maxInt(i128), 0); |
| ... | @@ -79,7 +77,6 @@ test "saturating subtraction" { | ... | @@ -79,7 +77,6 @@ test "saturating subtraction" { |
| 79 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 77 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 80 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 78 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 81 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 79 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 82 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 83 | 80 | ||
| 84 | const S = struct { | 81 | const S = struct { |
| 85 | fn doTheTest() !void { | 82 | fn doTheTest() !void { |
| ... | @@ -125,7 +122,6 @@ test "saturating subtraction 128bit" { | ... | @@ -125,7 +122,6 @@ test "saturating subtraction 128bit" { |
| 125 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 122 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 126 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 123 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 127 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 124 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 128 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 129 | 125 | ||
| 130 | const S = struct { | 126 | const S = struct { |
| 131 | fn doTheTest() !void { | 127 | fn doTheTest() !void { |
| ... | @@ -152,7 +148,6 @@ test "saturating multiplication" { | ... | @@ -152,7 +148,6 @@ test "saturating multiplication" { |
| 152 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 148 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 153 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 149 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 154 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 150 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 155 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 156 | 151 | ||
| 157 | if (builtin.zig_backend == .stage1 and builtin.cpu.arch == .wasm32) { | 152 | if (builtin.zig_backend == .stage1 and builtin.cpu.arch == .wasm32) { |
| 158 | // https://github.com/ziglang/zig/issues/9660 | 153 | // https://github.com/ziglang/zig/issues/9660 |
| ... | @@ -200,7 +195,6 @@ test "saturating shift-left" { | ... | @@ -200,7 +195,6 @@ test "saturating shift-left" { |
| 200 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 195 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 201 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 196 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 202 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 197 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 203 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 204 | 198 | ||
| 205 | const S = struct { | 199 | const S = struct { |
| 206 | fn doTheTest() !void { | 200 | fn doTheTest() !void { |
| ... | @@ -239,7 +233,6 @@ test "saturating shl uses the LHS type" { | ... | @@ -239,7 +233,6 @@ test "saturating shl uses the LHS type" { |
| 239 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 233 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 240 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 234 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 241 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 235 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 242 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 243 | 236 | ||
| 244 | const lhs_const: u8 = 1; | 237 | const lhs_const: u8 = 1; |
| 245 | var lhs_var: u8 = 1; | 238 | var lhs_var: u8 = 1; |
test/behavior/sizeof_and_typeof.zig-1| ... | @@ -19,7 +19,6 @@ test "@sizeOf on compile-time types" { | ... | @@ -19,7 +19,6 @@ test "@sizeOf on compile-time types" { |
| 19 | 19 | ||
| 20 | test "@TypeOf() with multiple arguments" { | 20 | test "@TypeOf() with multiple arguments" { |
| 21 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 21 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 22 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 23 | { | 22 | { |
| 24 | var var_1: u32 = undefined; | 23 | var var_1: u32 = undefined; |
| 25 | var var_2: u8 = undefined; | 24 | var var_2: u8 = undefined; |
test/behavior/slice.zig-11| ... | @@ -169,7 +169,6 @@ test "comptime pointer cast array and then slice" { | ... | @@ -169,7 +169,6 @@ test "comptime pointer cast array and then slice" { |
| 169 | 169 | ||
| 170 | test "slicing zero length array" { | 170 | test "slicing zero length array" { |
| 171 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 171 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 172 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 173 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 172 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 174 | 173 | ||
| 175 | const s1 = ""[0..]; | 174 | const s1 = ""[0..]; |
| ... | @@ -206,8 +205,6 @@ test "slice string literal has correct type" { | ... | @@ -206,8 +205,6 @@ test "slice string literal has correct type" { |
| 206 | } | 205 | } |
| 207 | 206 | ||
| 208 | test "result location zero sized array inside struct field implicit cast to slice" { | 207 | test "result location zero sized array inside struct field implicit cast to slice" { |
| 209 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 210 | |||
| 211 | const E = struct { | 208 | const E = struct { |
| 212 | entries: []u32, | 209 | entries: []u32, |
| 213 | }; | 210 | }; |
| ... | @@ -229,7 +226,6 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 { | ... | @@ -229,7 +226,6 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 { |
| 229 | 226 | ||
| 230 | test "C pointer" { | 227 | test "C pointer" { |
| 231 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 228 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 232 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 233 | 229 | ||
| 234 | var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf"; | 230 | var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf"; |
| 235 | var len: u32 = 10; | 231 | var len: u32 = 10; |
| ... | @@ -323,7 +319,6 @@ test "empty array to slice" { | ... | @@ -323,7 +319,6 @@ test "empty array to slice" { |
| 323 | 319 | ||
| 324 | test "@ptrCast slice to pointer" { | 320 | test "@ptrCast slice to pointer" { |
| 325 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 321 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 326 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 327 | 322 | ||
| 328 | const S = struct { | 323 | const S = struct { |
| 329 | fn doTheTest() !void { | 324 | fn doTheTest() !void { |
| ... | @@ -339,7 +334,6 @@ test "@ptrCast slice to pointer" { | ... | @@ -339,7 +334,6 @@ test "@ptrCast slice to pointer" { |
| 339 | } | 334 | } |
| 340 | 335 | ||
| 341 | test "slice syntax resulting in pointer-to-array" { | 336 | test "slice syntax resulting in pointer-to-array" { |
| 342 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 343 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 337 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 344 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 338 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 345 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 339 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -477,7 +471,6 @@ test "slice syntax resulting in pointer-to-array" { | ... | @@ -477,7 +471,6 @@ test "slice syntax resulting in pointer-to-array" { |
| 477 | } | 471 | } |
| 478 | 472 | ||
| 479 | test "slice pointer-to-array null terminated" { | 473 | test "slice pointer-to-array null terminated" { |
| 480 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 481 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 474 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 482 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 475 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 483 | 476 | ||
| ... | @@ -503,7 +496,6 @@ test "slice pointer-to-array null terminated" { | ... | @@ -503,7 +496,6 @@ test "slice pointer-to-array null terminated" { |
| 503 | } | 496 | } |
| 504 | 497 | ||
| 505 | test "slice pointer-to-array zero length" { | 498 | test "slice pointer-to-array zero length" { |
| 506 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 507 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 499 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 508 | 500 | ||
| 509 | comptime { | 501 | comptime { |
| ... | @@ -541,7 +533,6 @@ test "slice pointer-to-array zero length" { | ... | @@ -541,7 +533,6 @@ test "slice pointer-to-array zero length" { |
| 541 | } | 533 | } |
| 542 | 534 | ||
| 543 | test "type coercion of pointer to anon struct literal to pointer to slice" { | 535 | test "type coercion of pointer to anon struct literal to pointer to slice" { |
| 544 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 545 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 536 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 546 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 537 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 547 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 538 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -637,7 +628,6 @@ test "slice sentinel access at comptime" { | ... | @@ -637,7 +628,6 @@ test "slice sentinel access at comptime" { |
| 637 | test "slicing array with sentinel as end index" { | 628 | test "slicing array with sentinel as end index" { |
| 638 | // Doesn't work in stage1 | 629 | // Doesn't work in stage1 |
| 639 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 630 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 640 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 641 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 631 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 642 | 632 | ||
| 643 | const S = struct { | 633 | const S = struct { |
| ... | @@ -657,7 +647,6 @@ test "slicing array with sentinel as end index" { | ... | @@ -657,7 +647,6 @@ test "slicing array with sentinel as end index" { |
| 657 | test "slicing slice with sentinel as end index" { | 647 | test "slicing slice with sentinel as end index" { |
| 658 | // Doesn't work in stage1 | 648 | // Doesn't work in stage1 |
| 659 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 649 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 660 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 661 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 650 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 662 | 651 | ||
| 663 | const S = struct { | 652 | const S = struct { |
test/behavior/struct.zig-33| ... | @@ -284,7 +284,6 @@ const Val = struct { | ... | @@ -284,7 +284,6 @@ const Val = struct { |
| 284 | 284 | ||
| 285 | test "struct point to self" { | 285 | test "struct point to self" { |
| 286 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 286 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 287 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 288 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 287 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 289 | 288 | ||
| 290 | var root: Node = undefined; | 289 | var root: Node = undefined; |
| ... | @@ -319,7 +318,6 @@ const VoidStructFieldsFoo = struct { | ... | @@ -319,7 +318,6 @@ const VoidStructFieldsFoo = struct { |
| 319 | 318 | ||
| 320 | test "return empty struct from fn" { | 319 | test "return empty struct from fn" { |
| 321 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 320 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 322 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 323 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 321 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 324 | 322 | ||
| 325 | _ = testReturnEmptyStructFromFn(); | 323 | _ = testReturnEmptyStructFromFn(); |
| ... | @@ -331,7 +329,6 @@ fn testReturnEmptyStructFromFn() EmptyStruct2 { | ... | @@ -331,7 +329,6 @@ fn testReturnEmptyStructFromFn() EmptyStruct2 { |
| 331 | 329 | ||
| 332 | test "pass slice of empty struct to fn" { | 330 | test "pass slice of empty struct to fn" { |
| 333 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 331 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 334 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 335 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 332 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 336 | 333 | ||
| 337 | try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1); | 334 | try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1); |
| ... | @@ -342,7 +339,6 @@ fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize { | ... | @@ -342,7 +339,6 @@ fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize { |
| 342 | 339 | ||
| 343 | test "self-referencing struct via array member" { | 340 | test "self-referencing struct via array member" { |
| 344 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 341 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 345 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 346 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 342 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 347 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 343 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 348 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 344 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -356,8 +352,6 @@ test "self-referencing struct via array member" { | ... | @@ -356,8 +352,6 @@ test "self-referencing struct via array member" { |
| 356 | } | 352 | } |
| 357 | 353 | ||
| 358 | test "empty struct method call" { | 354 | test "empty struct method call" { |
| 359 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 360 | |||
| 361 | const es = EmptyStruct{}; | 355 | const es = EmptyStruct{}; |
| 362 | try expect(es.method() == 1234); | 356 | try expect(es.method() == 1234); |
| 363 | } | 357 | } |
| ... | @@ -370,7 +364,6 @@ const EmptyStruct = struct { | ... | @@ -370,7 +364,6 @@ const EmptyStruct = struct { |
| 370 | 364 | ||
| 371 | test "align 1 field before self referential align 8 field as slice return type" { | 365 | test "align 1 field before self referential align 8 field as slice return type" { |
| 372 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 366 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 373 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 374 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 367 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 375 | 368 | ||
| 376 | const result = alloc(Expr); | 369 | const result = alloc(Expr); |
| ... | @@ -394,7 +387,6 @@ const APackedStruct = packed struct { | ... | @@ -394,7 +387,6 @@ const APackedStruct = packed struct { |
| 394 | test "packed struct" { | 387 | test "packed struct" { |
| 395 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 388 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 396 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 389 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 397 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 398 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 390 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 399 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 391 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 400 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 392 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -421,7 +413,6 @@ const Foo96Bits = packed struct { | ... | @@ -421,7 +413,6 @@ const Foo96Bits = packed struct { |
| 421 | test "packed struct 24bits" { | 413 | test "packed struct 24bits" { |
| 422 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 414 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 423 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 415 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 424 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 425 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 416 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 426 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 417 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 427 | if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO | 418 | if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO |
| ... | @@ -470,7 +461,6 @@ test "packed struct 24bits" { | ... | @@ -470,7 +461,6 @@ test "packed struct 24bits" { |
| 470 | test "runtime struct initialization of bitfield" { | 461 | test "runtime struct initialization of bitfield" { |
| 471 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 462 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 472 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 463 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 473 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 474 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 464 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 475 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 465 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 476 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 466 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -515,7 +505,6 @@ test "packed struct fields are ordered from LSB to MSB" { | ... | @@ -515,7 +505,6 @@ test "packed struct fields are ordered from LSB to MSB" { |
| 515 | } | 505 | } |
| 516 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 506 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 517 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 507 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 518 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 519 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 508 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 520 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 509 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 521 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 510 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -537,7 +526,6 @@ test "packed struct fields are ordered from LSB to MSB" { | ... | @@ -537,7 +526,6 @@ test "packed struct fields are ordered from LSB to MSB" { |
| 537 | test "implicit cast packed struct field to const ptr" { | 526 | test "implicit cast packed struct field to const ptr" { |
| 538 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 527 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 539 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 528 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 540 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 541 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 529 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 542 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 530 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 543 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 531 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -559,7 +547,6 @@ test "implicit cast packed struct field to const ptr" { | ... | @@ -559,7 +547,6 @@ test "implicit cast packed struct field to const ptr" { |
| 559 | 547 | ||
| 560 | test "zero-bit field in packed struct" { | 548 | test "zero-bit field in packed struct" { |
| 561 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 549 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 562 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 563 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 550 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 564 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 551 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 565 | 552 | ||
| ... | @@ -605,7 +592,6 @@ const bit_field_1 = BitField1{ | ... | @@ -605,7 +592,6 @@ const bit_field_1 = BitField1{ |
| 605 | test "bit field access" { | 592 | test "bit field access" { |
| 606 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 593 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 607 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 594 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 608 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 609 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 595 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 610 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 596 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 611 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 597 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -638,7 +624,6 @@ fn getC(data: *const BitField1) u2 { | ... | @@ -638,7 +624,6 @@ fn getC(data: *const BitField1) u2 { |
| 638 | 624 | ||
| 639 | test "default struct initialization fields" { | 625 | test "default struct initialization fields" { |
| 640 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 626 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 641 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 642 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 627 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 643 | 628 | ||
| 644 | const S = struct { | 629 | const S = struct { |
| ... | @@ -771,7 +756,6 @@ test "pointer to packed struct member in a stack variable" { | ... | @@ -771,7 +756,6 @@ test "pointer to packed struct member in a stack variable" { |
| 771 | test "packed struct with u0 field access" { | 756 | test "packed struct with u0 field access" { |
| 772 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 757 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 773 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 758 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 774 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 775 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 759 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 776 | 760 | ||
| 777 | const S = packed struct { | 761 | const S = packed struct { |
| ... | @@ -783,7 +767,6 @@ test "packed struct with u0 field access" { | ... | @@ -783,7 +767,6 @@ test "packed struct with u0 field access" { |
| 783 | 767 | ||
| 784 | test "access to global struct fields" { | 768 | test "access to global struct fields" { |
| 785 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 769 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 786 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 787 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 770 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 788 | 771 | ||
| 789 | g_foo.bar.value = 42; | 772 | g_foo.bar.value = 42; |
| ... | @@ -810,7 +793,6 @@ test "packed struct with fp fields" { | ... | @@ -810,7 +793,6 @@ test "packed struct with fp fields" { |
| 810 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 793 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 811 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 794 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 812 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 795 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 813 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 814 | 796 | ||
| 815 | const S = packed struct { | 797 | const S = packed struct { |
| 816 | data0: f32, | 798 | data0: f32, |
| ... | @@ -886,7 +868,6 @@ test "packed struct field passed to generic function" { | ... | @@ -886,7 +868,6 @@ test "packed struct field passed to generic function" { |
| 886 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 868 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 887 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 869 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 888 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 870 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 889 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 890 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 871 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 891 | 872 | ||
| 892 | const S = struct { | 873 | const S = struct { |
| ... | @@ -910,7 +891,6 @@ test "packed struct field passed to generic function" { | ... | @@ -910,7 +891,6 @@ test "packed struct field passed to generic function" { |
| 910 | 891 | ||
| 911 | test "anonymous struct literal syntax" { | 892 | test "anonymous struct literal syntax" { |
| 912 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 893 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 913 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 914 | 894 | ||
| 915 | const S = struct { | 895 | const S = struct { |
| 916 | const Point = struct { | 896 | const Point = struct { |
| ... | @@ -932,8 +912,6 @@ test "anonymous struct literal syntax" { | ... | @@ -932,8 +912,6 @@ test "anonymous struct literal syntax" { |
| 932 | } | 912 | } |
| 933 | 913 | ||
| 934 | test "fully anonymous struct" { | 914 | test "fully anonymous struct" { |
| 935 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 936 | |||
| 937 | const S = struct { | 915 | const S = struct { |
| 938 | fn doTheTest() !void { | 916 | fn doTheTest() !void { |
| 939 | try dump(.{ | 917 | try dump(.{ |
| ... | @@ -956,8 +934,6 @@ test "fully anonymous struct" { | ... | @@ -956,8 +934,6 @@ test "fully anonymous struct" { |
| 956 | } | 934 | } |
| 957 | 935 | ||
| 958 | test "fully anonymous list literal" { | 936 | test "fully anonymous list literal" { |
| 959 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 960 | |||
| 961 | const S = struct { | 937 | const S = struct { |
| 962 | fn doTheTest() !void { | 938 | fn doTheTest() !void { |
| 963 | try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" }); | 939 | try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" }); |
| ... | @@ -1000,7 +976,6 @@ test "comptime struct field" { | ... | @@ -1000,7 +976,6 @@ test "comptime struct field" { |
| 1000 | } | 976 | } |
| 1001 | 977 | ||
| 1002 | test "tuple element initialized with fn call" { | 978 | test "tuple element initialized with fn call" { |
| 1003 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1004 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 979 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1005 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 980 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1006 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 981 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -1039,7 +1014,6 @@ test "struct with union field" { | ... | @@ -1039,7 +1014,6 @@ test "struct with union field" { |
| 1039 | } | 1014 | } |
| 1040 | 1015 | ||
| 1041 | test "type coercion of anon struct literal to struct" { | 1016 | test "type coercion of anon struct literal to struct" { |
| 1042 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1043 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1017 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1044 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1018 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1045 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1019 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1078,7 +1052,6 @@ test "type coercion of anon struct literal to struct" { | ... | @@ -1078,7 +1052,6 @@ test "type coercion of anon struct literal to struct" { |
| 1078 | 1052 | ||
| 1079 | test "type coercion of pointer to anon struct literal to pointer to struct" { | 1053 | test "type coercion of pointer to anon struct literal to pointer to struct" { |
| 1080 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1054 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1081 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1082 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1055 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1083 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1056 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1084 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1057 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1118,7 +1091,6 @@ test "type coercion of pointer to anon struct literal to pointer to struct" { | ... | @@ -1118,7 +1091,6 @@ test "type coercion of pointer to anon struct literal to pointer to struct" { |
| 1118 | test "packed struct with undefined initializers" { | 1091 | test "packed struct with undefined initializers" { |
| 1119 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 1092 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 1120 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1093 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1121 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1122 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1094 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1123 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1095 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1124 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1096 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| ... | @@ -1190,7 +1162,6 @@ test "for loop over pointers to struct, getting field from struct pointer" { | ... | @@ -1190,7 +1162,6 @@ test "for loop over pointers to struct, getting field from struct pointer" { |
| 1190 | 1162 | ||
| 1191 | test "anon init through error unions and optionals" { | 1163 | test "anon init through error unions and optionals" { |
| 1192 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 1164 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 1193 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1194 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1165 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1195 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1166 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1196 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1167 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -1219,7 +1190,6 @@ test "anon init through error unions and optionals" { | ... | @@ -1219,7 +1190,6 @@ test "anon init through error unions and optionals" { |
| 1219 | 1190 | ||
| 1220 | test "anon init through optional" { | 1191 | test "anon init through optional" { |
| 1221 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 1192 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 1222 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1223 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1193 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1224 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1194 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1225 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1195 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -1241,7 +1211,6 @@ test "anon init through optional" { | ... | @@ -1241,7 +1211,6 @@ test "anon init through optional" { |
| 1241 | 1211 | ||
| 1242 | test "anon init through error union" { | 1212 | test "anon init through error union" { |
| 1243 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 1213 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 1244 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1245 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1214 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1246 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1215 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1247 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1216 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -1263,7 +1232,6 @@ test "anon init through error union" { | ... | @@ -1263,7 +1232,6 @@ test "anon init through error union" { |
| 1263 | 1232 | ||
| 1264 | test "typed init through error unions and optionals" { | 1233 | test "typed init through error unions and optionals" { |
| 1265 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 1234 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 1266 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1267 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1235 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1268 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1236 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1269 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1237 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -1332,7 +1300,6 @@ test "packed struct aggregate init" { | ... | @@ -1332,7 +1300,6 @@ test "packed struct aggregate init" { |
| 1332 | } | 1300 | } |
| 1333 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1301 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1334 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1302 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1335 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1336 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1303 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1337 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1304 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1338 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 1305 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
test/behavior/struct_contains_null_ptr_itself.zig-1| ... | @@ -5,7 +5,6 @@ const builtin = @import("builtin"); | ... | @@ -5,7 +5,6 @@ const builtin = @import("builtin"); |
| 5 | test "struct contains null pointer which contains original struct" { | 5 | test "struct contains null pointer which contains original struct" { |
| 6 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 6 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 7 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 7 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 8 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 9 | var x: ?*NodeLineComment = null; | 8 | var x: ?*NodeLineComment = null; |
| 10 | try expect(x == null); | 9 | try expect(x == null); |
| 11 | } | 10 | } |
test/behavior/struct_contains_slice_of_itself.zig-2| ... | @@ -12,7 +12,6 @@ const NodeAligned = struct { | ... | @@ -12,7 +12,6 @@ const NodeAligned = struct { |
| 12 | }; | 12 | }; |
| 13 | 13 | ||
| 14 | test "struct contains slice of itself" { | 14 | test "struct contains slice of itself" { |
| 15 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 16 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 15 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 17 | 16 | ||
| 18 | var other_nodes = [_]Node{ | 17 | var other_nodes = [_]Node{ |
| ... | @@ -52,7 +51,6 @@ test "struct contains slice of itself" { | ... | @@ -52,7 +51,6 @@ test "struct contains slice of itself" { |
| 52 | } | 51 | } |
| 53 | 52 | ||
| 54 | test "struct contains aligned slice of itself" { | 53 | test "struct contains aligned slice of itself" { |
| 55 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 56 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 54 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 57 | 55 | ||
| 58 | var other_nodes = [_]NodeAligned{ | 56 | var other_nodes = [_]NodeAligned{ |
test/behavior/switch.zig-3| ... | @@ -420,7 +420,6 @@ test "else prong of switch on error set excludes other cases" { | ... | @@ -420,7 +420,6 @@ test "else prong of switch on error set excludes other cases" { |
| 420 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 420 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 421 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 421 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 422 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 422 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 423 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 424 | 423 | ||
| 425 | const S = struct { | 424 | const S = struct { |
| 426 | fn doTheTest() !void { | 425 | fn doTheTest() !void { |
| ... | @@ -455,7 +454,6 @@ test "switch prongs with error set cases make a new error set type for capture v | ... | @@ -455,7 +454,6 @@ test "switch prongs with error set cases make a new error set type for capture v |
| 455 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 454 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 456 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 455 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 457 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 456 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 458 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 459 | 457 | ||
| 460 | const S = struct { | 458 | const S = struct { |
| 461 | fn doTheTest() !void { | 459 | fn doTheTest() !void { |
| ... | @@ -621,7 +619,6 @@ test "switch capture copies its payload" { | ... | @@ -621,7 +619,6 @@ test "switch capture copies its payload" { |
| 621 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 619 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 622 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 620 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 623 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 621 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 624 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 625 | 622 | ||
| 626 | const S = struct { | 623 | const S = struct { |
| 627 | fn doTheTest() !void { | 624 | fn doTheTest() !void { |
test/behavior/switch_prong_err_enum.zig-1| ... | @@ -24,7 +24,6 @@ test "switch prong returns error enum" { | ... | @@ -24,7 +24,6 @@ test "switch prong returns error enum" { |
| 24 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 24 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 25 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 25 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 26 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 26 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 27 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 28 | switch (doThing(17) catch unreachable) { | 27 | switch (doThing(17) catch unreachable) { |
| 29 | FormValue.Address => |payload| { | 28 | FormValue.Address => |payload| { |
| 30 | try expect(payload == 1); | 29 | try expect(payload == 1); |
test/behavior/switch_prong_implicit_cast.zig-1| ... | @@ -18,7 +18,6 @@ test "switch prong implicit cast" { | ... | @@ -18,7 +18,6 @@ test "switch prong implicit cast" { |
| 18 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 18 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 19 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 19 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 20 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 20 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 21 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 22 | const result = switch (foo(2) catch unreachable) { | 21 | const result = switch (foo(2) catch unreachable) { |
| 23 | FormValue.One => false, | 22 | FormValue.One => false, |
| 24 | FormValue.Two => |x| x, | 23 | FormValue.Two => |x| x, |
test/behavior/translate_c_macros.zig-8| ... | @@ -21,7 +21,6 @@ test "casting to void with a macro" { | ... | @@ -21,7 +21,6 @@ test "casting to void with a macro" { |
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | test "initializer list expression" { | 23 | test "initializer list expression" { |
| 24 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 25 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 24 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 26 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 25 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 27 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 26 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -48,7 +47,6 @@ test "reference to a struct type" { | ... | @@ -48,7 +47,6 @@ test "reference to a struct type" { |
| 48 | test "cast negative integer to pointer" { | 47 | test "cast negative integer to pointer" { |
| 49 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 48 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 50 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 49 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 51 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 52 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 50 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 53 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 51 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 54 | 52 | ||
| ... | @@ -58,7 +56,6 @@ test "cast negative integer to pointer" { | ... | @@ -58,7 +56,6 @@ test "cast negative integer to pointer" { |
| 58 | test "casting to union with a macro" { | 56 | test "casting to union with a macro" { |
| 59 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 57 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 60 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 58 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 61 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 62 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 59 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 63 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 60 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 64 | 61 | ||
| ... | @@ -75,7 +72,6 @@ test "casting to union with a macro" { | ... | @@ -75,7 +72,6 @@ test "casting to union with a macro" { |
| 75 | test "casting or calling a value with a paren-surrounded macro" { | 72 | test "casting or calling a value with a paren-surrounded macro" { |
| 76 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 73 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 77 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 74 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 78 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 79 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 75 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 80 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 76 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 81 | 77 | ||
| ... | @@ -95,7 +91,6 @@ test "casting or calling a value with a paren-surrounded macro" { | ... | @@ -95,7 +91,6 @@ test "casting or calling a value with a paren-surrounded macro" { |
| 95 | test "nested comma operator" { | 91 | test "nested comma operator" { |
| 96 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 92 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 97 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 93 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 98 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 99 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 94 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 100 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 95 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 101 | 96 | ||
| ... | @@ -106,7 +101,6 @@ test "nested comma operator" { | ... | @@ -106,7 +101,6 @@ test "nested comma operator" { |
| 106 | test "cast functions" { | 101 | test "cast functions" { |
| 107 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 102 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 108 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 103 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 109 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 110 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 104 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 111 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 105 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 112 | 106 | ||
| ... | @@ -120,7 +114,6 @@ test "cast functions" { | ... | @@ -120,7 +114,6 @@ test "cast functions" { |
| 120 | test "large integer macro" { | 114 | test "large integer macro" { |
| 121 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 115 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 122 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 116 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 123 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 124 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 117 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 125 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 118 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 126 | 119 | ||
| ... | @@ -151,7 +144,6 @@ test "string and char literals that are not UTF-8 encoded. Issue #12784" { | ... | @@ -151,7 +144,6 @@ test "string and char literals that are not UTF-8 encoded. Issue #12784" { |
| 151 | test "Macro that uses division operator. Issue #13162" { | 144 | test "Macro that uses division operator. Issue #13162" { |
| 152 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 145 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 153 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 146 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 154 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 155 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 147 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 156 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 148 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 157 | 149 |
test/behavior/tuple.zig-5| ... | @@ -205,7 +205,6 @@ test "initializing anon struct with explicit type" { | ... | @@ -205,7 +205,6 @@ test "initializing anon struct with explicit type" { |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | test "fieldParentPtr of tuple" { | 207 | test "fieldParentPtr of tuple" { |
| 208 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 209 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 208 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 210 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 209 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 211 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 210 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | @@ -216,7 +215,6 @@ test "fieldParentPtr of tuple" { | ... | @@ -216,7 +215,6 @@ test "fieldParentPtr of tuple" { |
| 216 | } | 215 | } |
| 217 | 216 | ||
| 218 | test "fieldParentPtr of anon struct" { | 217 | test "fieldParentPtr of anon struct" { |
| 219 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 220 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 218 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 221 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 219 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 222 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 220 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| ... | @@ -257,7 +255,6 @@ test "initializing anon struct with mixed comptime-runtime fields" { | ... | @@ -257,7 +255,6 @@ test "initializing anon struct with mixed comptime-runtime fields" { |
| 257 | } | 255 | } |
| 258 | 256 | ||
| 259 | test "tuple in tuple passed to generic function" { | 257 | test "tuple in tuple passed to generic function" { |
| 260 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 261 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 258 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 262 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 259 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 263 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 260 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| ... | @@ -277,7 +274,6 @@ test "tuple in tuple passed to generic function" { | ... | @@ -277,7 +274,6 @@ test "tuple in tuple passed to generic function" { |
| 277 | } | 274 | } |
| 278 | 275 | ||
| 279 | test "coerce tuple to tuple" { | 276 | test "coerce tuple to tuple" { |
| 280 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 281 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 277 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 282 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 278 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 283 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 279 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| ... | @@ -292,7 +288,6 @@ test "coerce tuple to tuple" { | ... | @@ -292,7 +288,6 @@ test "coerce tuple to tuple" { |
| 292 | } | 288 | } |
| 293 | 289 | ||
| 294 | test "tuple type with void field" { | 290 | test "tuple type with void field" { |
| 295 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 296 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 291 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 297 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 292 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 298 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 293 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
test/behavior/type.zig-7| ... | @@ -200,7 +200,6 @@ test "Type.ErrorUnion" { | ... | @@ -200,7 +200,6 @@ test "Type.ErrorUnion" { |
| 200 | 200 | ||
| 201 | test "Type.Opaque" { | 201 | test "Type.Opaque" { |
| 202 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 202 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 203 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 204 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 203 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 205 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 204 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 206 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 205 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -248,7 +247,6 @@ fn add(a: i32, b: i32) i32 { | ... | @@ -248,7 +247,6 @@ fn add(a: i32, b: i32) i32 { |
| 248 | 247 | ||
| 249 | test "Type.ErrorSet" { | 248 | test "Type.ErrorSet" { |
| 250 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 249 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 251 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 252 | 250 | ||
| 253 | try testing.expect(@Type(.{ .ErrorSet = null }) == anyerror); | 251 | try testing.expect(@Type(.{ .ErrorSet = null }) == anyerror); |
| 254 | 252 | ||
| ... | @@ -351,7 +349,6 @@ test "Type.Struct" { | ... | @@ -351,7 +349,6 @@ test "Type.Struct" { |
| 351 | } | 349 | } |
| 352 | 350 | ||
| 353 | test "Type.Enum" { | 351 | test "Type.Enum" { |
| 354 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 355 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 352 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 356 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 353 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 357 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 354 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -396,7 +393,6 @@ test "Type.Enum" { | ... | @@ -396,7 +393,6 @@ test "Type.Enum" { |
| 396 | 393 | ||
| 397 | test "Type.Union" { | 394 | test "Type.Union" { |
| 398 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 395 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 399 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 400 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 396 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 401 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 397 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 402 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 398 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| ... | @@ -462,7 +458,6 @@ test "Type.Union" { | ... | @@ -462,7 +458,6 @@ test "Type.Union" { |
| 462 | } | 458 | } |
| 463 | 459 | ||
| 464 | test "Type.Union from Type.Enum" { | 460 | test "Type.Union from Type.Enum" { |
| 465 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 466 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 461 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 467 | 462 | ||
| 468 | const Tag = @Type(.{ | 463 | const Tag = @Type(.{ |
| ... | @@ -490,7 +485,6 @@ test "Type.Union from Type.Enum" { | ... | @@ -490,7 +485,6 @@ test "Type.Union from Type.Enum" { |
| 490 | } | 485 | } |
| 491 | 486 | ||
| 492 | test "Type.Union from regular enum" { | 487 | test "Type.Union from regular enum" { |
| 493 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 494 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 488 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 495 | 489 | ||
| 496 | const E = enum { working_as_expected }; | 490 | const E = enum { working_as_expected }; |
| ... | @@ -509,7 +503,6 @@ test "Type.Union from regular enum" { | ... | @@ -509,7 +503,6 @@ test "Type.Union from regular enum" { |
| 509 | 503 | ||
| 510 | test "Type.Fn" { | 504 | test "Type.Fn" { |
| 511 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 505 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 512 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 513 | 506 | ||
| 514 | if (true) { | 507 | if (true) { |
| 515 | // https://github.com/ziglang/zig/issues/12360 | 508 | // https://github.com/ziglang/zig/issues/12360 |
test/behavior/type_info.zig+4-13| ... | @@ -355,19 +355,12 @@ fn testOpaque() !void { | ... | @@ -355,19 +355,12 @@ fn testOpaque() !void { |
| 355 | } | 355 | } |
| 356 | 356 | ||
| 357 | test "type info: function type info" { | 357 | test "type info: function type info" { |
| 358 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | ||
| 359 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | ||
| 360 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 361 | |||
| 362 | // wasm doesn't support align attributes on functions | ||
| 363 | if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest; | ||
| 364 | |||
| 365 | try testFunction(); | 358 | try testFunction(); |
| 366 | comptime try testFunction(); | 359 | comptime try testFunction(); |
| 367 | } | 360 | } |
| 368 | 361 | ||
| 369 | fn testFunction() !void { | 362 | fn testFunction() !void { |
| 370 | const fn_info = @typeInfo(@TypeOf(foo)); | 363 | const fn_info = @typeInfo(@TypeOf(typeInfoFoo)); |
| 371 | try expect(fn_info == .Fn); | 364 | try expect(fn_info == .Fn); |
| 372 | try expect(fn_info.Fn.alignment > 0); | 365 | try expect(fn_info.Fn.alignment > 0); |
| 373 | try expect(fn_info.Fn.calling_convention == .C); | 366 | try expect(fn_info.Fn.calling_convention == .C); |
| ... | @@ -375,16 +368,14 @@ fn testFunction() !void { | ... | @@ -375,16 +368,14 @@ fn testFunction() !void { |
| 375 | try expect(fn_info.Fn.args.len == 2); | 368 | try expect(fn_info.Fn.args.len == 2); |
| 376 | try expect(fn_info.Fn.is_var_args); | 369 | try expect(fn_info.Fn.is_var_args); |
| 377 | try expect(fn_info.Fn.return_type.? == usize); | 370 | try expect(fn_info.Fn.return_type.? == usize); |
| 378 | const fn_aligned_info = @typeInfo(@TypeOf(fooAligned)); | 371 | const fn_aligned_info = @typeInfo(@TypeOf(typeInfoFooAligned)); |
| 379 | try expect(fn_aligned_info.Fn.alignment == 4); | 372 | try expect(fn_aligned_info.Fn.alignment == 4); |
| 380 | } | 373 | } |
| 381 | 374 | ||
| 382 | extern fn foo(a: usize, b: bool, ...) callconv(.C) usize; | 375 | extern fn typeInfoFoo(a: usize, b: bool, ...) callconv(.C) usize; |
| 383 | extern fn fooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize; | 376 | extern fn typeInfoFooAligned(a: usize, b: bool, ...) align(4) callconv(.C) usize; |
| 384 | 377 | ||
| 385 | test "type info: generic function types" { | 378 | test "type info: generic function types" { |
| 386 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 387 | |||
| 388 | if (builtin.zig_backend != .stage1) { | 379 | if (builtin.zig_backend != .stage1) { |
| 389 | // stage1 marks all args/return types as null if the function | 380 | // stage1 marks all args/return types as null if the function |
| 390 | // is generic at all. stage2 is more specific. | 381 | // is generic at all. stage2 is more specific. |
test/behavior/undefined.zig-1| ... | @@ -15,7 +15,6 @@ const static_array = initStaticArray(); | ... | @@ -15,7 +15,6 @@ const static_array = initStaticArray(); |
| 15 | test "init static array to undefined" { | 15 | test "init static array to undefined" { |
| 16 | // This test causes `initStaticArray()` to be codegen'd, and the | 16 | // This test causes `initStaticArray()` to be codegen'd, and the |
| 17 | // C backend does not yet support returning arrays, so it fails | 17 | // C backend does not yet support returning arrays, so it fails |
| 18 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 19 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 18 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 20 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 19 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| 21 | 20 |
test/behavior/union.zig-13| ... | @@ -431,7 +431,6 @@ const Foo1 = union(enum) { | ... | @@ -431,7 +431,6 @@ const Foo1 = union(enum) { |
| 431 | var glbl: Foo1 = undefined; | 431 | var glbl: Foo1 = undefined; |
| 432 | 432 | ||
| 433 | test "global union with single field is correctly initialized" { | 433 | test "global union with single field is correctly initialized" { |
| 434 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 435 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 434 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 436 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 435 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 437 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 436 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| ... | @@ -476,7 +475,6 @@ test "update the tag value for zero-sized unions" { | ... | @@ -476,7 +475,6 @@ test "update the tag value for zero-sized unions" { |
| 476 | } | 475 | } |
| 477 | 476 | ||
| 478 | test "union initializer generates padding only if needed" { | 477 | test "union initializer generates padding only if needed" { |
| 479 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 480 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 478 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 481 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 479 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 482 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 480 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| ... | @@ -753,7 +751,6 @@ fn Setter(comptime attr: Attribute) type { | ... | @@ -753,7 +751,6 @@ fn Setter(comptime attr: Attribute) type { |
| 753 | } | 751 | } |
| 754 | 752 | ||
| 755 | test "return union init with void payload" { | 753 | test "return union init with void payload" { |
| 756 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; | ||
| 757 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; | 754 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; |
| 758 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; | 755 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; |
| 759 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; | 756 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; |
| ... | @@ -779,7 +776,6 @@ test "return union init with void payload" { | ... | @@ -779,7 +776,6 @@ test "return union init with void payload" { |
| 779 | } | 776 | } |
| 780 | 777 | ||
| 781 | test "@unionInit stored to a const" { | 778 | test "@unionInit stored to a const" { |
| 782 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 783 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 779 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 784 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 780 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 785 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 781 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -942,7 +938,6 @@ test "function call result coerces from tagged union to the tag" { | ... | @@ -942,7 +938,6 @@ test "function call result coerces from tagged union to the tag" { |
| 942 | } | 938 | } |
| 943 | 939 | ||
| 944 | test "cast from anonymous struct to union" { | 940 | test "cast from anonymous struct to union" { |
| 945 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 946 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 941 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 947 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 942 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 948 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 943 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -975,7 +970,6 @@ test "cast from anonymous struct to union" { | ... | @@ -975,7 +970,6 @@ test "cast from anonymous struct to union" { |
| 975 | } | 970 | } |
| 976 | 971 | ||
| 977 | test "cast from pointer to anonymous struct to pointer to union" { | 972 | test "cast from pointer to anonymous struct to pointer to union" { |
| 978 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 979 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 973 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 980 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 974 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 981 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 975 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -1062,7 +1056,6 @@ test "containers with single-field enums" { | ... | @@ -1062,7 +1056,6 @@ test "containers with single-field enums" { |
| 1062 | } | 1056 | } |
| 1063 | 1057 | ||
| 1064 | test "@unionInit on union with tag but no fields" { | 1058 | test "@unionInit on union with tag but no fields" { |
| 1065 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1066 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1059 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1067 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1060 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1068 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1061 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| ... | @@ -1138,7 +1131,6 @@ test "global variable struct contains union initialized to non-most-aligned fiel | ... | @@ -1138,7 +1131,6 @@ test "global variable struct contains union initialized to non-most-aligned fiel |
| 1138 | } | 1131 | } |
| 1139 | 1132 | ||
| 1140 | test "union with no result loc initiated with a runtime value" { | 1133 | test "union with no result loc initiated with a runtime value" { |
| 1141 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1142 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1134 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1143 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1135 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1144 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1136 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| ... | @@ -1155,7 +1147,6 @@ test "union with no result loc initiated with a runtime value" { | ... | @@ -1155,7 +1147,6 @@ test "union with no result loc initiated with a runtime value" { |
| 1155 | } | 1147 | } |
| 1156 | 1148 | ||
| 1157 | test "union with a large struct field" { | 1149 | test "union with a large struct field" { |
| 1158 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1159 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1150 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1160 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1151 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1161 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1152 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| ... | @@ -1189,7 +1180,6 @@ test "comptime equality of extern unions with same tag" { | ... | @@ -1189,7 +1180,6 @@ test "comptime equality of extern unions with same tag" { |
| 1189 | } | 1180 | } |
| 1190 | 1181 | ||
| 1191 | test "union tag is set when initiated as a temporary value at runtime" { | 1182 | test "union tag is set when initiated as a temporary value at runtime" { |
| 1192 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1193 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1183 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1194 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1184 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1195 | 1185 | ||
| ... | @@ -1325,7 +1315,6 @@ test "union and enum field order doesn't match" { | ... | @@ -1325,7 +1315,6 @@ test "union and enum field order doesn't match" { |
| 1325 | } | 1315 | } |
| 1326 | 1316 | ||
| 1327 | test "@unionInit uses tag value instead of field index" { | 1317 | test "@unionInit uses tag value instead of field index" { |
| 1328 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1329 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1318 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1330 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1319 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1331 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1320 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -1353,7 +1342,6 @@ test "@unionInit uses tag value instead of field index" { | ... | @@ -1353,7 +1342,6 @@ test "@unionInit uses tag value instead of field index" { |
| 1353 | } | 1342 | } |
| 1354 | 1343 | ||
| 1355 | test "union field ptr - zero sized payload" { | 1344 | test "union field ptr - zero sized payload" { |
| 1356 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1357 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1345 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1358 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1346 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1359 | 1347 | ||
| ... | @@ -1367,7 +1355,6 @@ test "union field ptr - zero sized payload" { | ... | @@ -1367,7 +1355,6 @@ test "union field ptr - zero sized payload" { |
| 1367 | } | 1355 | } |
| 1368 | 1356 | ||
| 1369 | test "union field ptr - zero sized field" { | 1357 | test "union field ptr - zero sized field" { |
| 1370 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1371 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1358 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1372 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1359 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 1373 | 1360 |
test/behavior/union_with_members.zig-1| ... | @@ -19,7 +19,6 @@ const ET = union(enum) { | ... | @@ -19,7 +19,6 @@ const ET = union(enum) { |
| 19 | test "enum with members" { | 19 | test "enum with members" { |
| 20 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 20 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 21 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 21 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 22 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 23 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 22 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 24 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 23 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 25 | 24 |
test/behavior/vector.zig-2| ... | @@ -811,7 +811,6 @@ test "vector reduce operation" { | ... | @@ -811,7 +811,6 @@ test "vector reduce operation" { |
| 811 | test "vector @reduce comptime" { | 811 | test "vector @reduce comptime" { |
| 812 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; | 812 | if (builtin.zig_backend == .stage1) return error.SkipZigTest; |
| 813 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 813 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 814 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 815 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 814 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 816 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 815 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 817 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 816 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| ... | @@ -1138,7 +1137,6 @@ test "array of vectors is copied" { | ... | @@ -1138,7 +1137,6 @@ test "array of vectors is copied" { |
| 1138 | 1137 | ||
| 1139 | test "byte vector initialized in inline function" { | 1138 | test "byte vector initialized in inline function" { |
| 1140 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | 1139 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO |
| 1141 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 1142 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 1140 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 1143 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 1141 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 1144 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 1142 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
test/behavior/widening.zig-4| ... | @@ -8,7 +8,6 @@ test "integer widening" { | ... | @@ -8,7 +8,6 @@ test "integer widening" { |
| 8 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 8 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 9 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 10 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 11 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 12 | 11 | ||
| 13 | var a: u8 = 250; | 12 | var a: u8 = 250; |
| 14 | var b: u16 = a; | 13 | var b: u16 = a; |
| ... | @@ -30,7 +29,6 @@ test "integer widening u0 to u8" { | ... | @@ -30,7 +29,6 @@ test "integer widening u0 to u8" { |
| 30 | test "implicit unsigned integer to signed integer" { | 29 | test "implicit unsigned integer to signed integer" { |
| 31 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 30 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 32 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 31 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 33 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 34 | 32 | ||
| 35 | var a: u8 = 250; | 33 | var a: u8 = 250; |
| 36 | var b: i16 = a; | 34 | var b: i16 = a; |
| ... | @@ -42,7 +40,6 @@ test "float widening" { | ... | @@ -42,7 +40,6 @@ test "float widening" { |
| 42 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 40 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 43 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 41 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 44 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 42 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 45 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 46 | 43 | ||
| 47 | var a: f16 = 12.34; | 44 | var a: f16 = 12.34; |
| 48 | var b: f32 = a; | 45 | var b: f32 = a; |
| ... | @@ -62,7 +59,6 @@ test "float widening f16 to f128" { | ... | @@ -62,7 +59,6 @@ test "float widening f16 to f128" { |
| 62 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO | 59 | if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO |
| 63 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | 60 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO |
| 64 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | 61 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO |
| 65 | if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO | ||
| 66 | 62 | ||
| 67 | // TODO https://github.com/ziglang/zig/issues/3282 | 63 | // TODO https://github.com/ziglang/zig/issues/3282 |
| 68 | if (builtin.cpu.arch == .aarch64) return error.SkipZigTest; | 64 | if (builtin.cpu.arch == .aarch64) return error.SkipZigTest; |
test/cases/aarch64-macos/hello_world_with_updates.0.zig+1-1| ... | @@ -2,4 +2,4 @@ | ... | @@ -2,4 +2,4 @@ |
| 2 | // output_mode=Exe | 2 | // output_mode=Exe |
| 3 | // target=aarch64-macos | 3 | // target=aarch64-macos |
| 4 | // | 4 | // |
| 5 | // :109:9: error: root struct of file 'tmp' has no member named 'main' | 5 | // :108:9: error: root struct of file 'tmp' has no member named 'main' |
test/cases/x86_64-linux/hello_world_with_updates.0.zig+1-1| ... | @@ -2,4 +2,4 @@ | ... | @@ -2,4 +2,4 @@ |
| 2 | // output_mode=Exe | 2 | // output_mode=Exe |
| 3 | // target=x86_64-linux | 3 | // target=x86_64-linux |
| 4 | // | 4 | // |
| 5 | // :109:9: error: root struct of file 'tmp' has no member named 'main' | 5 | // :108:9: error: root struct of file 'tmp' has no member named 'main' |
test/cases/x86_64-macos/hello_world_with_updates.0.zig+1-1| ... | @@ -2,4 +2,4 @@ | ... | @@ -2,4 +2,4 @@ |
| 2 | // output_mode=Exe | 2 | // output_mode=Exe |
| 3 | // target=x86_64-macos | 3 | // target=x86_64-macos |
| 4 | // | 4 | // |
| 5 | // :109:9: error: root struct of file 'tmp' has no member named 'main' | 5 | // :108:9: error: root struct of file 'tmp' has no member named 'main' |
test/cases/x86_64-windows/hello_world_with_updates.0.zig+1-1| ... | @@ -2,4 +2,4 @@ | ... | @@ -2,4 +2,4 @@ |
| 2 | // output_mode=Exe | 2 | // output_mode=Exe |
| 3 | // target=x86_64-windows | 3 | // target=x86_64-windows |
| 4 | // | 4 | // |
| 5 | // :130:9: error: root struct of file 'tmp' has no member named 'main' | 5 | // :129:9: error: root struct of file 'tmp' has no member named 'main' |
test/stage2/cbe.zig+11-11| ... | @@ -951,7 +951,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -951,7 +951,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 951 | ctx.h("simple header", linux_x64, | 951 | ctx.h("simple header", linux_x64, |
| 952 | \\export fn start() void{} | 952 | \\export fn start() void{} |
| 953 | , | 953 | , |
| 954 | \\ZIG_EXTERN_C void start(void); | 954 | \\zig_extern_c zig_void start(zig_void); |
| 955 | \\ | 955 | \\ |
| 956 | ); | 956 | ); |
| 957 | ctx.h("header with single param function", linux_x64, | 957 | ctx.h("header with single param function", linux_x64, |
| ... | @@ -959,7 +959,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -959,7 +959,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 959 | \\ _ = a; | 959 | \\ _ = a; |
| 960 | \\} | 960 | \\} |
| 961 | , | 961 | , |
| 962 | \\ZIG_EXTERN_C void start(uint8_t a0); | 962 | \\zig_extern_c zig_void start(zig_u8 const a0); |
| 963 | \\ | 963 | \\ |
| 964 | ); | 964 | ); |
| 965 | ctx.h("header with multiple param function", linux_x64, | 965 | ctx.h("header with multiple param function", linux_x64, |
| ... | @@ -967,25 +967,25 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -967,25 +967,25 @@ pub fn addCases(ctx: *TestContext) !void { |
| 967 | \\ _ = a; _ = b; _ = c; | 967 | \\ _ = a; _ = b; _ = c; |
| 968 | \\} | 968 | \\} |
| 969 | , | 969 | , |
| 970 | \\ZIG_EXTERN_C void start(uint8_t a0, uint8_t a1, uint8_t a2); | 970 | \\zig_extern_c zig_void start(zig_u8 const a0, zig_u8 const a1, zig_u8 const a2); |
| 971 | \\ | 971 | \\ |
| 972 | ); | 972 | ); |
| 973 | ctx.h("header with u32 param function", linux_x64, | 973 | ctx.h("header with u32 param function", linux_x64, |
| 974 | \\export fn start(a: u32) void{ _ = a; } | 974 | \\export fn start(a: u32) void{ _ = a; } |
| 975 | , | 975 | , |
| 976 | \\ZIG_EXTERN_C void start(uint32_t a0); | 976 | \\zig_extern_c zig_void start(zig_u32 const a0); |
| 977 | \\ | 977 | \\ |
| 978 | ); | 978 | ); |
| 979 | ctx.h("header with usize param function", linux_x64, | 979 | ctx.h("header with usize param function", linux_x64, |
| 980 | \\export fn start(a: usize) void{ _ = a; } | 980 | \\export fn start(a: usize) void{ _ = a; } |
| 981 | , | 981 | , |
| 982 | \\ZIG_EXTERN_C void start(uintptr_t a0); | 982 | \\zig_extern_c zig_void start(zig_usize const a0); |
| 983 | \\ | 983 | \\ |
| 984 | ); | 984 | ); |
| 985 | ctx.h("header with bool param function", linux_x64, | 985 | ctx.h("header with bool param function", linux_x64, |
| 986 | \\export fn start(a: bool) void{_ = a;} | 986 | \\export fn start(a: bool) void{_ = a;} |
| 987 | , | 987 | , |
| 988 | \\ZIG_EXTERN_C void start(bool a0); | 988 | \\zig_extern_c zig_void start(zig_bool const a0); |
| 989 | \\ | 989 | \\ |
| 990 | ); | 990 | ); |
| 991 | ctx.h("header with noreturn function", linux_x64, | 991 | ctx.h("header with noreturn function", linux_x64, |
| ... | @@ -993,7 +993,7 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -993,7 +993,7 @@ pub fn addCases(ctx: *TestContext) !void { |
| 993 | \\ unreachable; | 993 | \\ unreachable; |
| 994 | \\} | 994 | \\} |
| 995 | , | 995 | , |
| 996 | \\ZIG_EXTERN_C zig_noreturn void start(void); | 996 | \\zig_extern_c zig_noreturn start(zig_void); |
| 997 | \\ | 997 | \\ |
| 998 | ); | 998 | ); |
| 999 | ctx.h("header with multiple functions", linux_x64, | 999 | ctx.h("header with multiple functions", linux_x64, |
| ... | @@ -1001,15 +1001,15 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -1001,15 +1001,15 @@ pub fn addCases(ctx: *TestContext) !void { |
| 1001 | \\export fn b() void{} | 1001 | \\export fn b() void{} |
| 1002 | \\export fn c() void{} | 1002 | \\export fn c() void{} |
| 1003 | , | 1003 | , |
| 1004 | \\ZIG_EXTERN_C void a(void); | 1004 | \\zig_extern_c zig_void a(zig_void); |
| 1005 | \\ZIG_EXTERN_C void b(void); | 1005 | \\zig_extern_c zig_void b(zig_void); |
| 1006 | \\ZIG_EXTERN_C void c(void); | 1006 | \\zig_extern_c zig_void c(zig_void); |
| 1007 | \\ | 1007 | \\ |
| 1008 | ); | 1008 | ); |
| 1009 | ctx.h("header with multiple includes", linux_x64, | 1009 | ctx.h("header with multiple includes", linux_x64, |
| 1010 | \\export fn start(a: u32, b: usize) void{ _ = a; _ = b; } | 1010 | \\export fn start(a: u32, b: usize) void{ _ = a; _ = b; } |
| 1011 | , | 1011 | , |
| 1012 | \\ZIG_EXTERN_C void start(uint32_t a0, uintptr_t a1); | 1012 | \\zig_extern_c zig_void start(zig_u32 const a0, zig_usize const a1); |
| 1013 | \\ | 1013 | \\ |
| 1014 | ); | 1014 | ); |
| 1015 | } | 1015 | } |