| author | |
| committer | |
| log | 1fdb24827fb51351d5e31103069619668fae31c4 |
| tree | eccc305b5cbbdfe7e9d6cbbad945f4f32c6aa136 |
| parent | 56a905c7d16c79138b4581a84f1f844bce2f00eb |
| signature | Commit is signed but in an unrecognized format. |
* `@clz`, `@ctz`, `@popCount`, `@bswap`, `@bitreverse` now
have a type parameter
* rename @bitreverse to @bitReverse
* rename @bswap to @byteSwap
Closes #2119
Closes #212038 files changed, 466 insertions(+), 396 deletions(-)
doc/langref.html.in+13-11| ... | ... | @@ -6239,8 +6239,8 @@ comptime { |
| 6239 | 6239 | |
| 6240 | 6240 | {#header_close#} |
| 6241 | 6241 | |
| 6242 | {#header_open|@bswap#} | |
| 6243 | <pre>{#syntax#}@bswap(comptime T: type, value: T) T{#endsyntax#}</pre> | |
| 6242 | {#header_open|@byteSwap#} | |
| 6243 | <pre>{#syntax#}@byteSwap(comptime T: type, integer: T) T{#endsyntax#}</pre> | |
| 6244 | 6244 | <p>{#syntax#}T{#endsyntax#} must be an integer type with bit count evenly divisible by 8.</p> |
| 6245 | 6245 | <p> |
| 6246 | 6246 | Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, |
| ... | ... | @@ -6248,8 +6248,8 @@ comptime { |
| 6248 | 6248 | </p> |
| 6249 | 6249 | {#header_close#} |
| 6250 | 6250 | |
| 6251 | {#header_open|@bitreverse#} | |
| 6252 | <pre>{#syntax#}@bitreverse(comptime T: type, value: T) T{#endsyntax#}</pre> | |
| 6251 | {#header_open|@bitReverse#} | |
| 6252 | <pre>{#syntax#}@bitReverse(comptime T: type, integer: T) T{#endsyntax#}</pre> | |
| 6253 | 6253 | <p>{#syntax#}T{#endsyntax#} accepts any integer type.</p> |
| 6254 | 6254 | <p> |
| 6255 | 6255 | Reverses the bitpattern of an integer value, including the sign bit if applicable. |
| ... | ... | @@ -6337,14 +6337,15 @@ comptime { |
| 6337 | 6337 | {#header_close#} |
| 6338 | 6338 | |
| 6339 | 6339 | {#header_open|@clz#} |
| 6340 | <pre>{#syntax#}@clz(x: T) U{#endsyntax#}</pre> | |
| 6340 | <pre>{#syntax#}@clz(comptime T: type, integer: T) math.Log2Int(@intType(false, @typeInfo(T).Int.bits + 1)){#endsyntax#}</pre> | |
| 6341 | 6341 | <p> |
| 6342 | 6342 | This function counts the number of leading zeroes in {#syntax#}x{#endsyntax#} which is an integer |
| 6343 | 6343 | type {#syntax#}T{#endsyntax#}. |
| 6344 | 6344 | </p> |
| 6345 | 6345 | <p> |
| 6346 | The return type {#syntax#}U{#endsyntax#} is an unsigned integer with the minimum number | |
| 6347 | of bits that can represent the value {#syntax#}T.bit_count{#endsyntax#}. | |
| 6346 | If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#endsyntax#}. | |
| 6347 | Otherwise, the return type is an unsigned integer with the minimum number | |
| 6348 | of bits that can represent the bit count of the integer type. | |
| 6348 | 6349 | </p> |
| 6349 | 6350 | <p> |
| 6350 | 6351 | If {#syntax#}x{#endsyntax#} is zero, {#syntax#}@clz{#endsyntax#} returns {#syntax#}T.bit_count{#endsyntax#}. |
| ... | ... | @@ -6477,14 +6478,15 @@ test "main" { |
| 6477 | 6478 | {#header_close#} |
| 6478 | 6479 | |
| 6479 | 6480 | {#header_open|@ctz#} |
| 6480 | <pre>{#syntax#}@ctz(x: T) U{#endsyntax#}</pre> | |
| 6481 | <pre>{#syntax#}@ctz(comptime T: type, integer: T) math.Log2Int(@intType(false, @typeInfo(T).Int.bits + 1)){#endsyntax#}</pre> | |
| 6481 | 6482 | <p> |
| 6482 | 6483 | This function counts the number of trailing zeroes in {#syntax#}x{#endsyntax#} which is an integer |
| 6483 | 6484 | type {#syntax#}T{#endsyntax#}. |
| 6484 | 6485 | </p> |
| 6485 | 6486 | <p> |
| 6486 | The return type {#syntax#}U{#endsyntax#} is an unsigned integer with the minimum number | |
| 6487 | of bits that can represent the value {#syntax#}T.bit_count{#endsyntax#}. | |
| 6487 | If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#endsyntax#}. | |
| 6488 | Otherwise, the return type is an unsigned integer with the minimum number | |
| 6489 | of bits that can represent the bit count of the integer type. | |
| 6488 | 6490 | </p> |
| 6489 | 6491 | <p> |
| 6490 | 6492 | If {#syntax#}x{#endsyntax#} is zero, {#syntax#}@ctz{#endsyntax#} returns {#syntax#}T.bit_count{#endsyntax#}. |
| ... | ... | @@ -7034,7 +7036,7 @@ test "call foo" { |
| 7034 | 7036 | {#header_close#} |
| 7035 | 7037 | |
| 7036 | 7038 | {#header_open|@popCount#} |
| 7037 | <pre>{#syntax#}@popCount(integer: var) var{#endsyntax#}</pre> | |
| 7039 | <pre>{#syntax#}@popCount(comptime T: type, integer: T) math.Log2Int(@intType(false, @typeInfo(T).Int.bits + 1)){#endsyntax#}</pre> | |
| 7038 | 7040 | <p>Counts the number of bits set in an integer.</p> |
| 7039 | 7041 | <p> |
| 7040 | 7042 | If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#endsyntax#}. |
src/all_types.hpp+10-7| ... | ... | @@ -1407,6 +1407,8 @@ enum BuiltinFnId { |
| 1407 | 1407 | BuiltinFnIdCtz, |
| 1408 | 1408 | BuiltinFnIdClz, |
| 1409 | 1409 | BuiltinFnIdPopCount, |
| 1410 | BuiltinFnIdBswap, | |
| 1411 | BuiltinFnIdBitReverse, | |
| 1410 | 1412 | BuiltinFnIdImport, |
| 1411 | 1413 | BuiltinFnIdCImport, |
| 1412 | 1414 | BuiltinFnIdErrName, |
| ... | ... | @@ -1469,8 +1471,6 @@ enum BuiltinFnId { |
| 1469 | 1471 | BuiltinFnIdErrorReturnTrace, |
| 1470 | 1472 | BuiltinFnIdAtomicRmw, |
| 1471 | 1473 | BuiltinFnIdAtomicLoad, |
| 1472 | BuiltinFnIdBswap, | |
| 1473 | BuiltinFnIdBitReverse, | |
| 1474 | 1474 | }; |
| 1475 | 1475 | |
| 1476 | 1476 | struct BuiltinFnEntry { |
| ... | ... | @@ -2191,6 +2191,8 @@ enum IrInstructionId { |
| 2191 | 2191 | IrInstructionIdClz, |
| 2192 | 2192 | IrInstructionIdCtz, |
| 2193 | 2193 | IrInstructionIdPopCount, |
| 2194 | IrInstructionIdBswap, | |
| 2195 | IrInstructionIdBitReverse, | |
| 2194 | 2196 | IrInstructionIdImport, |
| 2195 | 2197 | IrInstructionIdCImport, |
| 2196 | 2198 | IrInstructionIdCInclude, |
| ... | ... | @@ -2287,8 +2289,6 @@ enum IrInstructionId { |
| 2287 | 2289 | IrInstructionIdMergeErrRetTraces, |
| 2288 | 2290 | IrInstructionIdMarkErrRetTracePtr, |
| 2289 | 2291 | IrInstructionIdSqrt, |
| 2290 | IrInstructionIdBswap, | |
| 2291 | IrInstructionIdBitReverse, | |
| 2292 | 2292 | IrInstructionIdErrSetCast, |
| 2293 | 2293 | IrInstructionIdToBytes, |
| 2294 | 2294 | IrInstructionIdFromBytes, |
| ... | ... | @@ -2744,19 +2744,22 @@ struct IrInstructionOptionalUnwrapPtr { |
| 2744 | 2744 | struct IrInstructionCtz { |
| 2745 | 2745 | IrInstruction base; |
| 2746 | 2746 | |
| 2747 | IrInstruction *value; | |
| 2747 | IrInstruction *type; | |
| 2748 | IrInstruction *op; | |
| 2748 | 2749 | }; |
| 2749 | 2750 | |
| 2750 | 2751 | struct IrInstructionClz { |
| 2751 | 2752 | IrInstruction base; |
| 2752 | 2753 | |
| 2753 | IrInstruction *value; | |
| 2754 | IrInstruction *type; | |
| 2755 | IrInstruction *op; | |
| 2754 | 2756 | }; |
| 2755 | 2757 | |
| 2756 | 2758 | struct IrInstructionPopCount { |
| 2757 | 2759 | IrInstruction base; |
| 2758 | 2760 | |
| 2759 | IrInstruction *value; | |
| 2761 | IrInstruction *type; | |
| 2762 | IrInstruction *op; | |
| 2760 | 2763 | }; |
| 2761 | 2764 | |
| 2762 | 2765 | struct IrInstructionUnionTag { |
src/analyze.cpp+23-9| ... | ... | @@ -213,15 +213,6 @@ static ZigType *new_container_type_entry(CodeGen *g, ZigTypeId id, AstNode *sour |
| 213 | 213 | return entry; |
| 214 | 214 | } |
| 215 | 215 | |
| 216 | static uint8_t bits_needed_for_unsigned(uint64_t x) { | |
| 217 | if (x == 0) { | |
| 218 | return 0; | |
| 219 | } | |
| 220 | uint8_t base = log2_u64(x); | |
| 221 | uint64_t upper = (((uint64_t)1) << base) - 1; | |
| 222 | return (upper >= x) ? base : (base + 1); | |
| 223 | } | |
| 224 | ||
| 225 | 216 | AstNode *type_decl_node(ZigType *type_entry) { |
| 226 | 217 | switch (type_entry->id) { |
| 227 | 218 | case ZigTypeIdInvalid: |
| ... | ... | @@ -335,10 +326,33 @@ static bool is_slice(ZigType *type) { |
| 335 | 326 | return type->id == ZigTypeIdStruct && type->data.structure.is_slice; |
| 336 | 327 | } |
| 337 | 328 | |
| 329 | static uint8_t bits_needed_for_unsigned(uint64_t x) { | |
| 330 | if (x == 0) { | |
| 331 | return 0; | |
| 332 | } | |
| 333 | uint8_t base = log2_u64(x); | |
| 334 | uint64_t upper = (((uint64_t)1) << base) - 1; | |
| 335 | return (upper >= x) ? base : (base + 1); | |
| 336 | } | |
| 337 | ||
| 338 | static uint8_t bits_needed_for_popcount_unsigned(uint64_t x) { | |
| 339 | uint8_t count = 0; | |
| 340 | for (uint64_t s = x;s != 0;s >>= 1) | |
| 341 | count++; | |
| 342 | ||
| 343 | return count; | |
| 344 | } | |
| 345 | ||
| 338 | 346 | ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) { |
| 339 | 347 | return get_int_type(g, false, bits_needed_for_unsigned(x)); |
| 340 | 348 | } |
| 341 | 349 | |
| 350 | // This is not the same as above, because while shift by bit width is UB, @clz, @popCount, and @ctz | |
| 351 | // can return bit width | |
| 352 | ZigType *get_smallest_popcount_unsigned_int_type(CodeGen *g, uint64_t x) { | |
| 353 | return get_int_type(g, false, bits_needed_for_popcount_unsigned(x)); | |
| 354 | } | |
| 355 | ||
| 342 | 356 | ZigType *get_promise_type(CodeGen *g, ZigType *result_type) { |
| 343 | 357 | if (result_type != nullptr && result_type->promise_parent != nullptr) { |
| 344 | 358 | return result_type->promise_parent; |
src/analyze.hpp+1| ... | ... | @@ -34,6 +34,7 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type); |
| 34 | 34 | ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, |
| 35 | 35 | AstNode *decl_node, const char *full_name, Buf *bare_name, ContainerLayout layout); |
| 36 | 36 | ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x); |
| 37 | ZigType *get_smallest_popcount_unsigned_int_type(CodeGen *g, uint64_t x); | |
| 37 | 38 | ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payload_type); |
| 38 | 39 | ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry); |
| 39 | 40 | ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name); |
src/codegen.cpp+28-20| ... | ... | @@ -4126,11 +4126,19 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI |
| 4126 | 4126 | |
| 4127 | 4127 | char llvm_name[64]; |
| 4128 | 4128 | sprintf(llvm_name, "llvm.%s.i%" PRIu32, fn_name, int_type->data.integral.bit_count); |
| 4129 | LLVMTypeRef param_types[] = { | |
| 4130 | get_llvm_type(g, int_type), | |
| 4131 | LLVMInt1Type(), | |
| 4132 | }; | |
| 4133 | LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, int_type), param_types, n_args, false); | |
| 4129 | LLVMTypeRef param_types[3]; | |
| 4130 | switch (n_args) { | |
| 4131 | case 1: | |
| 4132 | param_types[0] = get_llvm_type(g, int_type); | |
| 4133 | break; | |
| 4134 | case 2: // clz and ctz | |
| 4135 | param_types[0] = get_llvm_type(g, int_type); | |
| 4136 | param_types[1] = LLVMInt1Type(); | |
| 4137 | break; | |
| 4138 | default: | |
| 4139 | zig_unreachable(); | |
| 4140 | } | |
| 4141 | LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, int_type), &param_types[0], n_args, false); | |
| 4134 | 4142 | LLVMValueRef fn_val = LLVMAddFunction(g->module, llvm_name, fn_type); |
| 4135 | 4143 | assert(LLVMGetIntrinsicID(fn_val)); |
| 4136 | 4144 | |
| ... | ... | @@ -4140,9 +4148,9 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI |
| 4140 | 4148 | } |
| 4141 | 4149 | |
| 4142 | 4150 | static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstructionClz *instruction) { |
| 4143 | ZigType *int_type = instruction->value->value.type; | |
| 4151 | ZigType *int_type = instruction->op->value.type; | |
| 4144 | 4152 | LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdClz); |
| 4145 | LLVMValueRef operand = ir_llvm_value(g, instruction->value); | |
| 4153 | LLVMValueRef operand = ir_llvm_value(g, instruction->op); | |
| 4146 | 4154 | LLVMValueRef params[] { |
| 4147 | 4155 | operand, |
| 4148 | 4156 | LLVMConstNull(LLVMInt1Type()), |
| ... | ... | @@ -4152,9 +4160,9 @@ static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstru |
| 4152 | 4160 | } |
| 4153 | 4161 | |
| 4154 | 4162 | static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstructionCtz *instruction) { |
| 4155 | ZigType *int_type = instruction->value->value.type; | |
| 4163 | ZigType *int_type = instruction->op->value.type; | |
| 4156 | 4164 | LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdCtz); |
| 4157 | LLVMValueRef operand = ir_llvm_value(g, instruction->value); | |
| 4165 | LLVMValueRef operand = ir_llvm_value(g, instruction->op); | |
| 4158 | 4166 | LLVMValueRef params[] { |
| 4159 | 4167 | operand, |
| 4160 | 4168 | LLVMConstNull(LLVMInt1Type()), |
| ... | ... | @@ -4164,9 +4172,9 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstru |
| 4164 | 4172 | } |
| 4165 | 4173 | |
| 4166 | 4174 | static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutable *executable, IrInstructionPopCount *instruction) { |
| 4167 | ZigType *int_type = instruction->value->value.type; | |
| 4175 | ZigType *int_type = instruction->op->value.type; | |
| 4168 | 4176 | LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount); |
| 4169 | LLVMValueRef operand = ir_llvm_value(g, instruction->value); | |
| 4177 | LLVMValueRef operand = ir_llvm_value(g, instruction->op); | |
| 4170 | 4178 | LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, &operand, 1, ""); |
| 4171 | 4179 | return gen_widen_or_shorten(g, false, int_type, instruction->base.value.type, wrong_size_int); |
| 4172 | 4180 | } |
| ... | ... | @@ -5650,6 +5658,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 5650 | 5658 | return ir_render_pop_count(g, executable, (IrInstructionPopCount *)instruction); |
| 5651 | 5659 | case IrInstructionIdSwitchBr: |
| 5652 | 5660 | return ir_render_switch_br(g, executable, (IrInstructionSwitchBr *)instruction); |
| 5661 | case IrInstructionIdBswap: | |
| 5662 | return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction); | |
| 5663 | case IrInstructionIdBitReverse: | |
| 5664 | return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction); | |
| 5653 | 5665 | case IrInstructionIdPhi: |
| 5654 | 5666 | return ir_render_phi(g, executable, (IrInstructionPhi *)instruction); |
| 5655 | 5667 | case IrInstructionIdRef: |
| ... | ... | @@ -5766,10 +5778,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 5766 | 5778 | return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction); |
| 5767 | 5779 | case IrInstructionIdSqrt: |
| 5768 | 5780 | return ir_render_sqrt(g, executable, (IrInstructionSqrt *)instruction); |
| 5769 | case IrInstructionIdBswap: | |
| 5770 | return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction); | |
| 5771 | case IrInstructionIdBitReverse: | |
| 5772 | return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction); | |
| 5773 | 5781 | case IrInstructionIdArrayToVector: |
| 5774 | 5782 | return ir_render_array_to_vector(g, executable, (IrInstructionArrayToVector *)instruction); |
| 5775 | 5783 | case IrInstructionIdVectorToArray: |
| ... | ... | @@ -7332,9 +7340,11 @@ static void define_builtin_fns(CodeGen *g) { |
| 7332 | 7340 | create_builtin_fn(g, BuiltinFnIdCInclude, "cInclude", 1); |
| 7333 | 7341 | create_builtin_fn(g, BuiltinFnIdCDefine, "cDefine", 2); |
| 7334 | 7342 | create_builtin_fn(g, BuiltinFnIdCUndef, "cUndef", 1); |
| 7335 | create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 1); | |
| 7336 | create_builtin_fn(g, BuiltinFnIdClz, "clz", 1); | |
| 7337 | create_builtin_fn(g, BuiltinFnIdPopCount, "popCount", 1); | |
| 7343 | create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 2); | |
| 7344 | create_builtin_fn(g, BuiltinFnIdClz, "clz", 2); | |
| 7345 | create_builtin_fn(g, BuiltinFnIdPopCount, "popCount", 2); | |
| 7346 | create_builtin_fn(g, BuiltinFnIdBswap, "byteSwap", 2); | |
| 7347 | create_builtin_fn(g, BuiltinFnIdBitReverse, "bitReverse", 2); | |
| 7338 | 7348 | create_builtin_fn(g, BuiltinFnIdImport, "import", 1); |
| 7339 | 7349 | create_builtin_fn(g, BuiltinFnIdCImport, "cImport", 1); |
| 7340 | 7350 | create_builtin_fn(g, BuiltinFnIdErrName, "errorName", 1); |
| ... | ... | @@ -7395,8 +7405,6 @@ static void define_builtin_fns(CodeGen *g) { |
| 7395 | 7405 | create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1); |
| 7396 | 7406 | create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2); |
| 7397 | 7407 | create_builtin_fn(g, BuiltinFnIdThis, "This", 0); |
| 7398 | create_builtin_fn(g, BuiltinFnIdBswap, "bswap", 2); | |
| 7399 | create_builtin_fn(g, BuiltinFnIdBitReverse, "bitreverse", 2); | |
| 7400 | 7408 | } |
| 7401 | 7409 | |
| 7402 | 7410 | static const char *bool_to_str(bool b) { |
src/ir.cpp+172-159| ... | ... | @@ -575,6 +575,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) { |
| 575 | 575 | return IrInstructionIdPopCount; |
| 576 | 576 | } |
| 577 | 577 | |
| 578 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) { | |
| 579 | return IrInstructionIdBswap; | |
| 580 | } | |
| 581 | ||
| 582 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) { | |
| 583 | return IrInstructionIdBitReverse; | |
| 584 | } | |
| 585 | ||
| 578 | 586 | static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) { |
| 579 | 587 | return IrInstructionIdUnionTag; |
| 580 | 588 | } |
| ... | ... | @@ -983,14 +991,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) { |
| 983 | 991 | return IrInstructionIdSqrt; |
| 984 | 992 | } |
| 985 | 993 | |
| 986 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) { | |
| 987 | return IrInstructionIdBswap; | |
| 988 | } | |
| 989 | ||
| 990 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) { | |
| 991 | return IrInstructionIdBitReverse; | |
| 992 | } | |
| 993 | ||
| 994 | 994 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { |
| 995 | 995 | return IrInstructionIdCheckRuntimeScope; |
| 996 | 996 | } |
| ... | ... | @@ -1768,29 +1768,57 @@ static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNo |
| 1768 | 1768 | return &instruction->base; |
| 1769 | 1769 | } |
| 1770 | 1770 | |
| 1771 | static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { | |
| 1771 | static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { | |
| 1772 | 1772 | IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, scope, source_node); |
| 1773 | instruction->value = value; | |
| 1773 | instruction->type = type; | |
| 1774 | instruction->op = op; | |
| 1774 | 1775 | |
| 1775 | ir_ref_instruction(value, irb->current_basic_block); | |
| 1776 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); | |
| 1777 | ir_ref_instruction(op, irb->current_basic_block); | |
| 1776 | 1778 | |
| 1777 | 1779 | return &instruction->base; |
| 1778 | 1780 | } |
| 1779 | 1781 | |
| 1780 | static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { | |
| 1782 | static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { | |
| 1781 | 1783 | IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, scope, source_node); |
| 1782 | instruction->value = value; | |
| 1784 | instruction->type = type; | |
| 1785 | instruction->op = op; | |
| 1783 | 1786 | |
| 1784 | ir_ref_instruction(value, irb->current_basic_block); | |
| 1787 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); | |
| 1788 | ir_ref_instruction(op, irb->current_basic_block); | |
| 1785 | 1789 | |
| 1786 | 1790 | return &instruction->base; |
| 1787 | 1791 | } |
| 1788 | 1792 | |
| 1789 | static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { | |
| 1793 | static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { | |
| 1790 | 1794 | IrInstructionPopCount *instruction = ir_build_instruction<IrInstructionPopCount>(irb, scope, source_node); |
| 1791 | instruction->value = value; | |
| 1795 | instruction->type = type; | |
| 1796 | instruction->op = op; | |
| 1792 | 1797 | |
| 1793 | ir_ref_instruction(value, irb->current_basic_block); | |
| 1798 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); | |
| 1799 | ir_ref_instruction(op, irb->current_basic_block); | |
| 1800 | ||
| 1801 | return &instruction->base; | |
| 1802 | } | |
| 1803 | ||
| 1804 | static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { | |
| 1805 | IrInstructionBswap *instruction = ir_build_instruction<IrInstructionBswap>(irb, scope, source_node); | |
| 1806 | instruction->type = type; | |
| 1807 | instruction->op = op; | |
| 1808 | ||
| 1809 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); | |
| 1810 | ir_ref_instruction(op, irb->current_basic_block); | |
| 1811 | ||
| 1812 | return &instruction->base; | |
| 1813 | } | |
| 1814 | ||
| 1815 | static IrInstruction *ir_build_bit_reverse(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { | |
| 1816 | IrInstructionBitReverse *instruction = ir_build_instruction<IrInstructionBitReverse>(irb, scope, source_node); | |
| 1817 | instruction->type = type; | |
| 1818 | instruction->op = op; | |
| 1819 | ||
| 1820 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); | |
| 1821 | ir_ref_instruction(op, irb->current_basic_block); | |
| 1794 | 1822 | |
| 1795 | 1823 | return &instruction->base; |
| 1796 | 1824 | } |
| ... | ... | @@ -2986,28 +3014,6 @@ static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 2986 | 3014 | return &instruction->base; |
| 2987 | 3015 | } |
| 2988 | 3016 | |
| 2989 | static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { | |
| 2990 | IrInstructionBswap *instruction = ir_build_instruction<IrInstructionBswap>(irb, scope, source_node); | |
| 2991 | instruction->type = type; | |
| 2992 | instruction->op = op; | |
| 2993 | ||
| 2994 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); | |
| 2995 | ir_ref_instruction(op, irb->current_basic_block); | |
| 2996 | ||
| 2997 | return &instruction->base; | |
| 2998 | } | |
| 2999 | ||
| 3000 | static IrInstruction *ir_build_bit_reverse(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { | |
| 3001 | IrInstructionBitReverse *instruction = ir_build_instruction<IrInstructionBitReverse>(irb, scope, source_node); | |
| 3002 | instruction->type = type; | |
| 3003 | instruction->op = op; | |
| 3004 | ||
| 3005 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); | |
| 3006 | ir_ref_instruction(op, irb->current_basic_block); | |
| 3007 | ||
| 3008 | return &instruction->base; | |
| 3009 | } | |
| 3010 | ||
| 3011 | 3017 | static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) { |
| 3012 | 3018 | IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node); |
| 3013 | 3019 | instruction->scope_is_comptime = scope_is_comptime; |
| ... | ... | @@ -4082,36 +4088,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4082 | 4088 | IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value); |
| 4083 | 4089 | return ir_lval_wrap(irb, scope, size_of, lval); |
| 4084 | 4090 | } |
| 4085 | case BuiltinFnIdCtz: | |
| 4086 | { | |
| 4087 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | |
| 4088 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | |
| 4089 | if (arg0_value == irb->codegen->invalid_instruction) | |
| 4090 | return arg0_value; | |
| 4091 | ||
| 4092 | IrInstruction *ctz = ir_build_ctz(irb, scope, node, arg0_value); | |
| 4093 | return ir_lval_wrap(irb, scope, ctz, lval); | |
| 4094 | } | |
| 4095 | case BuiltinFnIdPopCount: | |
| 4096 | { | |
| 4097 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | |
| 4098 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | |
| 4099 | if (arg0_value == irb->codegen->invalid_instruction) | |
| 4100 | return arg0_value; | |
| 4101 | ||
| 4102 | IrInstruction *instr = ir_build_pop_count(irb, scope, node, arg0_value); | |
| 4103 | return ir_lval_wrap(irb, scope, instr, lval); | |
| 4104 | } | |
| 4105 | case BuiltinFnIdClz: | |
| 4106 | { | |
| 4107 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | |
| 4108 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | |
| 4109 | if (arg0_value == irb->codegen->invalid_instruction) | |
| 4110 | return arg0_value; | |
| 4111 | ||
| 4112 | IrInstruction *clz = ir_build_clz(irb, scope, node, arg0_value); | |
| 4113 | return ir_lval_wrap(irb, scope, clz, lval); | |
| 4114 | } | |
| 4115 | 4091 | case BuiltinFnIdImport: |
| 4116 | 4092 | { |
| 4117 | 4093 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | ... | @@ -5084,21 +5060,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5084 | 5060 | IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); |
| 5085 | 5061 | return ir_lval_wrap(irb, scope, result, lval); |
| 5086 | 5062 | } |
| 5063 | case BuiltinFnIdCtz: | |
| 5064 | case BuiltinFnIdPopCount: | |
| 5065 | case BuiltinFnIdClz: | |
| 5087 | 5066 | case BuiltinFnIdBswap: |
| 5088 | { | |
| 5089 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | |
| 5090 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | |
| 5091 | if (arg0_value == irb->codegen->invalid_instruction) | |
| 5092 | return arg0_value; | |
| 5093 | ||
| 5094 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | |
| 5095 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | |
| 5096 | if (arg1_value == irb->codegen->invalid_instruction) | |
| 5097 | return arg1_value; | |
| 5098 | ||
| 5099 | IrInstruction *result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value); | |
| 5100 | return ir_lval_wrap(irb, scope, result, lval); | |
| 5101 | } | |
| 5102 | 5067 | case BuiltinFnIdBitReverse: |
| 5103 | 5068 | { |
| 5104 | 5069 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); |
| ... | ... | @@ -5111,7 +5076,26 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5111 | 5076 | if (arg1_value == irb->codegen->invalid_instruction) |
| 5112 | 5077 | return arg1_value; |
| 5113 | 5078 | |
| 5114 | IrInstruction *result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value); | |
| 5079 | IrInstruction *result; | |
| 5080 | switch (builtin_fn->id) { | |
| 5081 | case BuiltinFnIdCtz: | |
| 5082 | result = ir_build_ctz(irb, scope, node, arg0_value, arg1_value); | |
| 5083 | break; | |
| 5084 | case BuiltinFnIdPopCount: | |
| 5085 | result = ir_build_pop_count(irb, scope, node, arg0_value, arg1_value); | |
| 5086 | break; | |
| 5087 | case BuiltinFnIdClz: | |
| 5088 | result = ir_build_clz(irb, scope, node, arg0_value, arg1_value); | |
| 5089 | break; | |
| 5090 | case BuiltinFnIdBswap: | |
| 5091 | result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value); | |
| 5092 | break; | |
| 5093 | case BuiltinFnIdBitReverse: | |
| 5094 | result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value); | |
| 5095 | break; | |
| 5096 | default: | |
| 5097 | zig_unreachable(); | |
| 5098 | } | |
| 5115 | 5099 | return ir_lval_wrap(irb, scope, result, lval); |
| 5116 | 5100 | } |
| 5117 | 5101 | } |
| ... | ... | @@ -17040,92 +17024,125 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, |
| 17040 | 17024 | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on); |
| 17041 | 17025 | } |
| 17042 | 17026 | |
| 17043 | static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *ctz_instruction) { | |
| 17044 | IrInstruction *value = ctz_instruction->value->child; | |
| 17045 | if (type_is_invalid(value->value.type)) { | |
| 17027 | static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) { | |
| 17028 | ZigType *int_type = ir_resolve_type(ira, instruction->type->child); | |
| 17029 | if (type_is_invalid(int_type)) | |
| 17046 | 17030 | return ira->codegen->invalid_instruction; |
| 17047 | } else if (value->value.type->id == ZigTypeIdInt) { | |
| 17048 | ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, | |
| 17049 | value->value.type->data.integral.bit_count); | |
| 17050 | if (value->value.special != ConstValSpecialRuntime) { | |
| 17051 | size_t result_usize = bigint_ctz(&value->value.data.x_bigint, | |
| 17052 | value->value.type->data.integral.bit_count); | |
| 17053 | IrInstruction *result = ir_const(ira, &ctz_instruction->base, return_type); | |
| 17054 | bigint_init_unsigned(&result->value.data.x_bigint, result_usize); | |
| 17055 | return result; | |
| 17056 | } | |
| 17057 | 17031 | |
| 17058 | IrInstruction *result = ir_build_ctz(&ira->new_irb, | |
| 17059 | ctz_instruction->base.scope, ctz_instruction->base.source_node, value); | |
| 17060 | result->value.type = return_type; | |
| 17061 | return result; | |
| 17062 | } else { | |
| 17063 | ir_add_error_node(ira, ctz_instruction->base.source_node, | |
| 17064 | buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); | |
| 17032 | IrInstruction *op = instruction->op->child; | |
| 17033 | ||
| 17034 | if (int_type->id != ZigTypeIdInt) { | |
| 17035 | ir_add_error(ira, instruction->type, | |
| 17036 | buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name))); | |
| 17065 | 17037 | return ira->codegen->invalid_instruction; |
| 17066 | 17038 | } |
| 17067 | } | |
| 17068 | 17039 | |
| 17069 | static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *clz_instruction) { | |
| 17070 | IrInstruction *value = clz_instruction->value->child; | |
| 17071 | if (type_is_invalid(value->value.type)) { | |
| 17040 | IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type); | |
| 17041 | if (type_is_invalid(casted_op->value.type)) | |
| 17072 | 17042 | return ira->codegen->invalid_instruction; |
| 17073 | } else if (value->value.type->id == ZigTypeIdInt) { | |
| 17074 | ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, | |
| 17075 | value->value.type->data.integral.bit_count); | |
| 17076 | if (value->value.special != ConstValSpecialRuntime) { | |
| 17077 | size_t result_usize = bigint_clz(&value->value.data.x_bigint, | |
| 17078 | value->value.type->data.integral.bit_count); | |
| 17079 | IrInstruction *result = ir_const(ira, &clz_instruction->base, return_type); | |
| 17080 | bigint_init_unsigned(&result->value.data.x_bigint, result_usize); | |
| 17081 | return result; | |
| 17082 | } | |
| 17083 | 17043 | |
| 17084 | IrInstruction *result = ir_build_clz(&ira->new_irb, | |
| 17085 | clz_instruction->base.scope, clz_instruction->base.source_node, value); | |
| 17086 | result->value.type = return_type; | |
| 17044 | ZigType *return_type = get_smallest_popcount_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); | |
| 17045 | ||
| 17046 | if (int_type->data.integral.bit_count == 0) { | |
| 17047 | IrInstruction *result = ir_const(ira, &instruction->base, return_type); | |
| 17048 | bigint_init_unsigned(&result->value.data.x_bigint, 0); | |
| 17087 | 17049 | return result; |
| 17088 | } else { | |
| 17089 | ir_add_error_node(ira, clz_instruction->base.source_node, | |
| 17090 | buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); | |
| 17050 | } | |
| 17051 | ||
| 17052 | if (instr_is_comptime(casted_op)) { | |
| 17053 | size_t result_usize = bigint_ctz(&op->value.data.x_bigint, | |
| 17054 | op->value.type->data.integral.bit_count); | |
| 17055 | IrInstruction *result = ir_const(ira, &instruction->base, return_type); | |
| 17056 | bigint_init_unsigned(&result->value.data.x_bigint, result_usize); | |
| 17057 | return result; | |
| 17058 | } | |
| 17059 | ||
| 17060 | IrInstruction *result = ir_build_ctz(&ira->new_irb, instruction->base.scope, | |
| 17061 | instruction->base.source_node, nullptr, casted_op); | |
| 17062 | result->value.type = return_type; | |
| 17063 | return result; | |
| 17064 | } | |
| 17065 | ||
| 17066 | static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *instruction) { | |
| 17067 | ZigType *int_type = ir_resolve_type(ira, instruction->type->child); | |
| 17068 | if (type_is_invalid(int_type)) | |
| 17069 | return ira->codegen->invalid_instruction; | |
| 17070 | ||
| 17071 | IrInstruction *op = instruction->op->child; | |
| 17072 | ||
| 17073 | if (int_type->id != ZigTypeIdInt) { | |
| 17074 | ir_add_error(ira, instruction->type, | |
| 17075 | buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name))); | |
| 17091 | 17076 | return ira->codegen->invalid_instruction; |
| 17092 | 17077 | } |
| 17078 | ||
| 17079 | IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type); | |
| 17080 | if (type_is_invalid(casted_op->value.type)) | |
| 17081 | return ira->codegen->invalid_instruction; | |
| 17082 | ||
| 17083 | ZigType *return_type = get_smallest_popcount_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); | |
| 17084 | ||
| 17085 | if (int_type->data.integral.bit_count == 0) { | |
| 17086 | IrInstruction *result = ir_const(ira, &instruction->base, return_type); | |
| 17087 | bigint_init_unsigned(&result->value.data.x_bigint, 0); | |
| 17088 | return result; | |
| 17089 | } | |
| 17090 | ||
| 17091 | if (instr_is_comptime(casted_op)) { | |
| 17092 | size_t result_usize = bigint_clz(&op->value.data.x_bigint, | |
| 17093 | op->value.type->data.integral.bit_count); | |
| 17094 | IrInstruction *result = ir_const(ira, &instruction->base, return_type); | |
| 17095 | bigint_init_unsigned(&result->value.data.x_bigint, result_usize); | |
| 17096 | return result; | |
| 17097 | } | |
| 17098 | ||
| 17099 | IrInstruction *result = ir_build_clz(&ira->new_irb, instruction->base.scope, | |
| 17100 | instruction->base.source_node, nullptr, casted_op); | |
| 17101 | result->value.type = return_type; | |
| 17102 | return result; | |
| 17093 | 17103 | } |
| 17094 | 17104 | |
| 17095 | 17105 | static IrInstruction *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) { |
| 17096 | IrInstruction *value = instruction->value->child; | |
| 17097 | if (type_is_invalid(value->value.type)) | |
| 17106 | ZigType *int_type = ir_resolve_type(ira, instruction->type->child); | |
| 17107 | if (type_is_invalid(int_type)) | |
| 17098 | 17108 | return ira->codegen->invalid_instruction; |
| 17099 | 17109 | |
| 17100 | if (value->value.type->id != ZigTypeIdInt && value->value.type->id != ZigTypeIdComptimeInt) { | |
| 17101 | ir_add_error(ira, value, | |
| 17102 | buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); | |
| 17110 | IrInstruction *op = instruction->op->child; | |
| 17111 | ||
| 17112 | if (int_type->id != ZigTypeIdInt) { | |
| 17113 | ir_add_error(ira, instruction->type, | |
| 17114 | buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name))); | |
| 17103 | 17115 | return ira->codegen->invalid_instruction; |
| 17104 | 17116 | } |
| 17105 | 17117 | |
| 17106 | if (instr_is_comptime(value)) { | |
| 17107 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); | |
| 17118 | IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type); | |
| 17119 | if (type_is_invalid(casted_op->value.type)) | |
| 17120 | return ira->codegen->invalid_instruction; | |
| 17121 | ||
| 17122 | ZigType *return_type = get_smallest_popcount_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); | |
| 17123 | ||
| 17124 | if (int_type->data.integral.bit_count == 0) { | |
| 17125 | IrInstruction *result = ir_const(ira, &instruction->base, return_type); | |
| 17126 | bigint_init_unsigned(&result->value.data.x_bigint, 0); | |
| 17127 | return result; | |
| 17128 | } | |
| 17129 | ||
| 17130 | if (instr_is_comptime(casted_op)) { | |
| 17131 | ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad); | |
| 17108 | 17132 | if (!val) |
| 17109 | 17133 | return ira->codegen->invalid_instruction; |
| 17134 | ||
| 17110 | 17135 | if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { |
| 17111 | 17136 | size_t result = bigint_popcount_unsigned(&val->data.x_bigint); |
| 17112 | 17137 | return ir_const_unsigned(ira, &instruction->base, result); |
| 17113 | 17138 | } |
| 17114 | if (value->value.type->id == ZigTypeIdComptimeInt) { | |
| 17115 | Buf *val_buf = buf_alloc(); | |
| 17116 | bigint_append_buf(val_buf, &val->data.x_bigint, 10); | |
| 17117 | ir_add_error(ira, &instruction->base, | |
| 17118 | buf_sprintf("@popCount on negative %s value %s", | |
| 17119 | buf_ptr(&value->value.type->name), buf_ptr(val_buf))); | |
| 17120 | return ira->codegen->invalid_instruction; | |
| 17121 | } | |
| 17122 | size_t result = bigint_popcount_signed(&val->data.x_bigint, value->value.type->data.integral.bit_count); | |
| 17139 | size_t result = bigint_popcount_signed(&val->data.x_bigint, op->value.type->data.integral.bit_count); | |
| 17123 | 17140 | return ir_const_unsigned(ira, &instruction->base, result); |
| 17124 | 17141 | } |
| 17125 | 17142 | |
| 17126 | 17143 | IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope, |
| 17127 | instruction->base.source_node, value); | |
| 17128 | result->value.type = get_smallest_unsigned_int_type(ira->codegen, value->value.type->data.integral.bit_count); | |
| 17144 | instruction->base.source_node, nullptr, casted_op); | |
| 17145 | result->value.type = return_type; | |
| 17129 | 17146 | return result; |
| 17130 | 17147 | } |
| 17131 | 17148 | |
| ... | ... | @@ -22990,8 +23007,6 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction |
| 22990 | 23007 | return ira->codegen->invalid_instruction; |
| 22991 | 23008 | |
| 22992 | 23009 | IrInstruction *op = instruction->op->child; |
| 22993 | if (type_is_invalid(op->value.type)) | |
| 22994 | return ira->codegen->invalid_instruction; | |
| 22995 | 23010 | |
| 22996 | 23011 | if (int_type->id != ZigTypeIdInt) { |
| 22997 | 23012 | ir_add_error(ira, instruction->type, |
| ... | ... | @@ -22999,17 +23014,17 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction |
| 22999 | 23014 | return ira->codegen->invalid_instruction; |
| 23000 | 23015 | } |
| 23001 | 23016 | |
| 23017 | IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type); | |
| 23018 | if (type_is_invalid(casted_op->value.type)) | |
| 23019 | return ira->codegen->invalid_instruction; | |
| 23020 | ||
| 23002 | 23021 | if (int_type->data.integral.bit_count % 8 != 0) { |
| 23003 | ir_add_error(ira, instruction->type, | |
| 23004 | buf_sprintf("@bswap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8", | |
| 23022 | ir_add_error(ira, instruction->op, | |
| 23023 | buf_sprintf("@byteSwap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8", | |
| 23005 | 23024 | buf_ptr(&int_type->name), int_type->data.integral.bit_count)); |
| 23006 | 23025 | return ira->codegen->invalid_instruction; |
| 23007 | 23026 | } |
| 23008 | 23027 | |
| 23009 | IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type); | |
| 23010 | if (type_is_invalid(casted_op->value.type)) | |
| 23011 | return ira->codegen->invalid_instruction; | |
| 23012 | ||
| 23013 | 23028 | if (int_type->data.integral.bit_count == 0) { |
| 23014 | 23029 | IrInstruction *result = ir_const(ira, &instruction->base, int_type); |
| 23015 | 23030 | bigint_init_unsigned(&result->value.data.x_bigint, 0); |
| ... | ... | @@ -23017,7 +23032,7 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction |
| 23017 | 23032 | } |
| 23018 | 23033 | |
| 23019 | 23034 | if (int_type->data.integral.bit_count == 8) { |
| 23020 | return casted_op; | |
| 23035 | return op; | |
| 23021 | 23036 | } |
| 23022 | 23037 | |
| 23023 | 23038 | if (instr_is_comptime(casted_op)) { |
| ... | ... | @@ -23046,8 +23061,6 @@ static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstr |
| 23046 | 23061 | return ira->codegen->invalid_instruction; |
| 23047 | 23062 | |
| 23048 | 23063 | IrInstruction *op = instruction->op->child; |
| 23049 | if (type_is_invalid(op->value.type)) | |
| 23050 | return ira->codegen->invalid_instruction; | |
| 23051 | 23064 | |
| 23052 | 23065 | if (int_type->id != ZigTypeIdInt) { |
| 23053 | 23066 | ir_add_error(ira, instruction->type, |
| ... | ... | @@ -23251,6 +23264,10 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23251 | 23264 | return ir_analyze_instruction_ctz(ira, (IrInstructionCtz *)instruction); |
| 23252 | 23265 | case IrInstructionIdPopCount: |
| 23253 | 23266 | return ir_analyze_instruction_pop_count(ira, (IrInstructionPopCount *)instruction); |
| 23267 | case IrInstructionIdBswap: | |
| 23268 | return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction); | |
| 23269 | case IrInstructionIdBitReverse: | |
| 23270 | return ir_analyze_instruction_bit_reverse(ira, (IrInstructionBitReverse *)instruction); | |
| 23254 | 23271 | case IrInstructionIdSwitchBr: |
| 23255 | 23272 | return ir_analyze_instruction_switch_br(ira, (IrInstructionSwitchBr *)instruction); |
| 23256 | 23273 | case IrInstructionIdSwitchTarget: |
| ... | ... | @@ -23443,10 +23460,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23443 | 23460 | return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); |
| 23444 | 23461 | case IrInstructionIdSqrt: |
| 23445 | 23462 | return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction); |
| 23446 | case IrInstructionIdBswap: | |
| 23447 | return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction); | |
| 23448 | case IrInstructionIdBitReverse: | |
| 23449 | return ir_analyze_instruction_bit_reverse(ira, (IrInstructionBitReverse *)instruction); | |
| 23450 | 23463 | case IrInstructionIdIntToErr: |
| 23451 | 23464 | return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); |
| 23452 | 23465 | case IrInstructionIdErrToInt: |
| ... | ... | @@ -23621,6 +23634,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23621 | 23634 | case IrInstructionIdClz: |
| 23622 | 23635 | case IrInstructionIdCtz: |
| 23623 | 23636 | case IrInstructionIdPopCount: |
| 23637 | case IrInstructionIdBswap: | |
| 23638 | case IrInstructionIdBitReverse: | |
| 23624 | 23639 | case IrInstructionIdSwitchVar: |
| 23625 | 23640 | case IrInstructionIdSwitchElseVar: |
| 23626 | 23641 | case IrInstructionIdSwitchTarget: |
| ... | ... | @@ -23679,8 +23694,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23679 | 23694 | case IrInstructionIdCoroPromise: |
| 23680 | 23695 | case IrInstructionIdPromiseResultType: |
| 23681 | 23696 | case IrInstructionIdSqrt: |
| 23682 | case IrInstructionIdBswap: | |
| 23683 | case IrInstructionIdBitReverse: | |
| 23684 | 23697 | case IrInstructionIdAtomicLoad: |
| 23685 | 23698 | case IrInstructionIdIntCast: |
| 23686 | 23699 | case IrInstructionIdFloatCast: |
src/ir_print.cpp+54-36| ... | ... | @@ -504,19 +504,61 @@ static void ir_print_optional_unwrap_ptr(IrPrint *irp, IrInstructionOptionalUnwr |
| 504 | 504 | |
| 505 | 505 | static void ir_print_clz(IrPrint *irp, IrInstructionClz *instruction) { |
| 506 | 506 | fprintf(irp->f, "@clz("); |
| 507 | ir_print_other_instruction(irp, instruction->value); | |
| 507 | if (instruction->type != nullptr) { | |
| 508 | ir_print_other_instruction(irp, instruction->type); | |
| 509 | } else { | |
| 510 | fprintf(irp->f, "null"); | |
| 511 | } | |
| 512 | fprintf(irp->f, ","); | |
| 513 | ir_print_other_instruction(irp, instruction->op); | |
| 508 | 514 | fprintf(irp->f, ")"); |
| 509 | 515 | } |
| 510 | 516 | |
| 511 | 517 | static void ir_print_ctz(IrPrint *irp, IrInstructionCtz *instruction) { |
| 512 | 518 | fprintf(irp->f, "@ctz("); |
| 513 | ir_print_other_instruction(irp, instruction->value); | |
| 519 | if (instruction->type != nullptr) { | |
| 520 | ir_print_other_instruction(irp, instruction->type); | |
| 521 | } else { | |
| 522 | fprintf(irp->f, "null"); | |
| 523 | } | |
| 524 | fprintf(irp->f, ","); | |
| 525 | ir_print_other_instruction(irp, instruction->op); | |
| 514 | 526 | fprintf(irp->f, ")"); |
| 515 | 527 | } |
| 516 | 528 | |
| 517 | 529 | static void ir_print_pop_count(IrPrint *irp, IrInstructionPopCount *instruction) { |
| 518 | 530 | fprintf(irp->f, "@popCount("); |
| 519 | ir_print_other_instruction(irp, instruction->value); | |
| 531 | if (instruction->type != nullptr) { | |
| 532 | ir_print_other_instruction(irp, instruction->type); | |
| 533 | } else { | |
| 534 | fprintf(irp->f, "null"); | |
| 535 | } | |
| 536 | fprintf(irp->f, ","); | |
| 537 | ir_print_other_instruction(irp, instruction->op); | |
| 538 | fprintf(irp->f, ")"); | |
| 539 | } | |
| 540 | ||
| 541 | static void ir_print_bswap(IrPrint *irp, IrInstructionBswap *instruction) { | |
| 542 | fprintf(irp->f, "@byteSwap("); | |
| 543 | if (instruction->type != nullptr) { | |
| 544 | ir_print_other_instruction(irp, instruction->type); | |
| 545 | } else { | |
| 546 | fprintf(irp->f, "null"); | |
| 547 | } | |
| 548 | fprintf(irp->f, ","); | |
| 549 | ir_print_other_instruction(irp, instruction->op); | |
| 550 | fprintf(irp->f, ")"); | |
| 551 | } | |
| 552 | ||
| 553 | static void ir_print_bit_reverse(IrPrint *irp, IrInstructionBitReverse *instruction) { | |
| 554 | fprintf(irp->f, "@bitReverse("); | |
| 555 | if (instruction->type != nullptr) { | |
| 556 | ir_print_other_instruction(irp, instruction->type); | |
| 557 | } else { | |
| 558 | fprintf(irp->f, "null"); | |
| 559 | } | |
| 560 | fprintf(irp->f, ","); | |
| 561 | ir_print_other_instruction(irp, instruction->op); | |
| 520 | 562 | fprintf(irp->f, ")"); |
| 521 | 563 | } |
| 522 | 564 | |
| ... | ... | @@ -1411,30 +1453,6 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va |
| 1411 | 1453 | } |
| 1412 | 1454 | } |
| 1413 | 1455 | |
| 1414 | static void ir_print_bswap(IrPrint *irp, IrInstructionBswap *instruction) { | |
| 1415 | fprintf(irp->f, "@bswap("); | |
| 1416 | if (instruction->type != nullptr) { | |
| 1417 | ir_print_other_instruction(irp, instruction->type); | |
| 1418 | } else { | |
| 1419 | fprintf(irp->f, "null"); | |
| 1420 | } | |
| 1421 | fprintf(irp->f, ","); | |
| 1422 | ir_print_other_instruction(irp, instruction->op); | |
| 1423 | fprintf(irp->f, ")"); | |
| 1424 | } | |
| 1425 | ||
| 1426 | static void ir_print_bit_reverse(IrPrint *irp, IrInstructionBitReverse *instruction) { | |
| 1427 | fprintf(irp->f, "@bitreverse("); | |
| 1428 | if (instruction->type != nullptr) { | |
| 1429 | ir_print_other_instruction(irp, instruction->type); | |
| 1430 | } else { | |
| 1431 | fprintf(irp->f, "null"); | |
| 1432 | } | |
| 1433 | fprintf(irp->f, ","); | |
| 1434 | ir_print_other_instruction(irp, instruction->op); | |
| 1435 | fprintf(irp->f, ")"); | |
| 1436 | } | |
| 1437 | ||
| 1438 | 1456 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1439 | 1457 | ir_print_prefix(irp, instruction); |
| 1440 | 1458 | switch (instruction->id) { |
| ... | ... | @@ -1551,15 +1569,21 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1551 | 1569 | case IrInstructionIdOptionalUnwrapPtr: |
| 1552 | 1570 | ir_print_optional_unwrap_ptr(irp, (IrInstructionOptionalUnwrapPtr *)instruction); |
| 1553 | 1571 | break; |
| 1554 | case IrInstructionIdCtz: | |
| 1555 | ir_print_ctz(irp, (IrInstructionCtz *)instruction); | |
| 1556 | break; | |
| 1557 | 1572 | case IrInstructionIdPopCount: |
| 1558 | 1573 | ir_print_pop_count(irp, (IrInstructionPopCount *)instruction); |
| 1559 | 1574 | break; |
| 1560 | 1575 | case IrInstructionIdClz: |
| 1561 | 1576 | ir_print_clz(irp, (IrInstructionClz *)instruction); |
| 1562 | 1577 | break; |
| 1578 | case IrInstructionIdCtz: | |
| 1579 | ir_print_ctz(irp, (IrInstructionCtz *)instruction); | |
| 1580 | break; | |
| 1581 | case IrInstructionIdBswap: | |
| 1582 | ir_print_bswap(irp, (IrInstructionBswap *)instruction); | |
| 1583 | break; | |
| 1584 | case IrInstructionIdBitReverse: | |
| 1585 | ir_print_bit_reverse(irp, (IrInstructionBitReverse *)instruction); | |
| 1586 | break; | |
| 1563 | 1587 | case IrInstructionIdSwitchBr: |
| 1564 | 1588 | ir_print_switch_br(irp, (IrInstructionSwitchBr *)instruction); |
| 1565 | 1589 | break; |
| ... | ... | @@ -1869,12 +1893,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1869 | 1893 | case IrInstructionIdSqrt: |
| 1870 | 1894 | ir_print_sqrt(irp, (IrInstructionSqrt *)instruction); |
| 1871 | 1895 | break; |
| 1872 | case IrInstructionIdBswap: | |
| 1873 | ir_print_bswap(irp, (IrInstructionBswap *)instruction); | |
| 1874 | break; | |
| 1875 | case IrInstructionIdBitReverse: | |
| 1876 | ir_print_bit_reverse(irp, (IrInstructionBitReverse *)instruction); | |
| 1877 | break; | |
| 1878 | 1896 | case IrInstructionIdAtomicLoad: |
| 1879 | 1897 | ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction); |
| 1880 | 1898 | break; |
std/heap.zig+1-1| ... | ... | @@ -894,7 +894,7 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo |
| 894 | 894 | const large_align = u29(os.page_size << 2); |
| 895 | 895 | |
| 896 | 896 | var align_mask: usize = undefined; |
| 897 | _ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(large_align)), &align_mask); | |
| 897 | _ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(u29, large_align)), &align_mask); | |
| 898 | 898 | |
| 899 | 899 | var slice = try allocator.alignedAlloc(u8, large_align, 500); |
| 900 | 900 | testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr)); |
std/math.zig+1-1| ... | ... | @@ -698,7 +698,7 @@ test "math.floorPowerOfTwo" { |
| 698 | 698 | |
| 699 | 699 | pub fn log2_int(comptime T: type, x: T) Log2Int(T) { |
| 700 | 700 | assert(x != 0); |
| 701 | return @intCast(Log2Int(T), T.bit_count - 1 - @clz(x)); | |
| 701 | return @intCast(Log2Int(T), T.bit_count - 1 - @clz(T, x)); | |
| 702 | 702 | } |
| 703 | 703 | |
| 704 | 704 | pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) { |
std/math/big/int.zig+4-4| ... | ... | @@ -207,7 +207,7 @@ pub const Int = struct { |
| 207 | 207 | |
| 208 | 208 | /// Returns the number of bits required to represent the absolute value an Int. |
| 209 | 209 | fn bitCountAbs(self: Int) usize { |
| 210 | return (self.len() - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len() - 1])); | |
| 210 | return (self.len() - 1) * Limb.bit_count + (Limb.bit_count - @clz(Limb, self.limbs[self.len() - 1])); | |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | 213 | /// Returns the number of bits required to represent the integer in twos-complement form. |
| ... | ... | @@ -226,9 +226,9 @@ pub const Int = struct { |
| 226 | 226 | if (!self.isPositive()) block: { |
| 227 | 227 | bits += 1; |
| 228 | 228 | |
| 229 | if (@popCount(self.limbs[self.len() - 1]) == 1) { | |
| 229 | if (@popCount(Limb, self.limbs[self.len() - 1]) == 1) { | |
| 230 | 230 | for (self.limbs[0 .. self.len() - 1]) |limb| { |
| 231 | if (@popCount(limb) != 0) { | |
| 231 | if (@popCount(Limb, limb) != 0) { | |
| 232 | 232 | break :block; |
| 233 | 233 | } |
| 234 | 234 | } |
| ... | ... | @@ -962,7 +962,7 @@ pub const Int = struct { |
| 962 | 962 | defer tmp.deinit(); |
| 963 | 963 | |
| 964 | 964 | // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) and even |
| 965 | var norm_shift = @clz(y.limbs[y.len() - 1]); | |
| 965 | var norm_shift = @clz(Limb, y.limbs[y.len() - 1]); | |
| 966 | 966 | if (norm_shift == 0 and y.isOdd()) { |
| 967 | 967 | norm_shift = Limb.bit_count; |
| 968 | 968 | } |
std/mem.zig+8-8| ... | ... | @@ -513,7 +513,7 @@ pub fn readIntNative(comptime T: type, bytes: *const [@divExact(T.bit_count, 8)] |
| 513 | 513 | /// This function cannot fail and cannot cause undefined behavior. |
| 514 | 514 | /// Assumes the endianness of memory is foreign, so it must byte-swap. |
| 515 | 515 | pub fn readIntForeign(comptime T: type, bytes: *const [@divExact(T.bit_count, 8)]u8) T { |
| 516 | return @bswap(T, readIntNative(T, bytes)); | |
| 516 | return @byteSwap(T, readIntNative(T, bytes)); | |
| 517 | 517 | } |
| 518 | 518 | |
| 519 | 519 | pub const readIntLittle = switch (builtin.endian) { |
| ... | ... | @@ -543,7 +543,7 @@ pub fn readIntSliceNative(comptime T: type, bytes: []const u8) T { |
| 543 | 543 | /// The bit count of T must be evenly divisible by 8. |
| 544 | 544 | /// Assumes the endianness of memory is foreign, so it must byte-swap. |
| 545 | 545 | pub fn readIntSliceForeign(comptime T: type, bytes: []const u8) T { |
| 546 | return @bswap(T, readIntSliceNative(T, bytes)); | |
| 546 | return @byteSwap(T, readIntSliceNative(T, bytes)); | |
| 547 | 547 | } |
| 548 | 548 | |
| 549 | 549 | pub const readIntSliceLittle = switch (builtin.endian) { |
| ... | ... | @@ -624,9 +624,9 @@ pub fn writeIntNative(comptime T: type, buf: *[(T.bit_count + 7) / 8]u8, value: |
| 624 | 624 | /// Writes an integer to memory, storing it in twos-complement. |
| 625 | 625 | /// This function always succeeds, has defined behavior for all inputs, but |
| 626 | 626 | /// the integer bit width must be divisible by 8. |
| 627 | /// This function stores in foreign endian, which means it does a @bswap first. | |
| 627 | /// This function stores in foreign endian, which means it does a @byteSwap first. | |
| 628 | 628 | pub fn writeIntForeign(comptime T: type, buf: *[@divExact(T.bit_count, 8)]u8, value: T) void { |
| 629 | writeIntNative(T, buf, @bswap(T, value)); | |
| 629 | writeIntNative(T, buf, @byteSwap(T, value)); | |
| 630 | 630 | } |
| 631 | 631 | |
| 632 | 632 | pub const writeIntLittle = switch (builtin.endian) { |
| ... | ... | @@ -1229,14 +1229,14 @@ test "std.mem.rotate" { |
| 1229 | 1229 | pub fn littleToNative(comptime T: type, x: T) T { |
| 1230 | 1230 | return switch (builtin.endian) { |
| 1231 | 1231 | builtin.Endian.Little => x, |
| 1232 | builtin.Endian.Big => @bswap(T, x), | |
| 1232 | builtin.Endian.Big => @byteSwap(T, x), | |
| 1233 | 1233 | }; |
| 1234 | 1234 | } |
| 1235 | 1235 | |
| 1236 | 1236 | /// Converts a big-endian integer to host endianness. |
| 1237 | 1237 | pub fn bigToNative(comptime T: type, x: T) T { |
| 1238 | 1238 | return switch (builtin.endian) { |
| 1239 | builtin.Endian.Little => @bswap(T, x), | |
| 1239 | builtin.Endian.Little => @byteSwap(T, x), | |
| 1240 | 1240 | builtin.Endian.Big => x, |
| 1241 | 1241 | }; |
| 1242 | 1242 | } |
| ... | ... | @@ -1261,14 +1261,14 @@ pub fn nativeTo(comptime T: type, x: T, desired_endianness: builtin.Endian) T { |
| 1261 | 1261 | pub fn nativeToLittle(comptime T: type, x: T) T { |
| 1262 | 1262 | return switch (builtin.endian) { |
| 1263 | 1263 | builtin.Endian.Little => x, |
| 1264 | builtin.Endian.Big => @bswap(T, x), | |
| 1264 | builtin.Endian.Big => @byteSwap(T, x), | |
| 1265 | 1265 | }; |
| 1266 | 1266 | } |
| 1267 | 1267 | |
| 1268 | 1268 | /// Converts an integer which has host endianness to big endian. |
| 1269 | 1269 | pub fn nativeToBig(comptime T: type, x: T) T { |
| 1270 | 1270 | return switch (builtin.endian) { |
| 1271 | builtin.Endian.Little => @bswap(T, x), | |
| 1271 | builtin.Endian.Little => @byteSwap(T, x), | |
| 1272 | 1272 | builtin.Endian.Big => x, |
| 1273 | 1273 | }; |
| 1274 | 1274 | } |
std/os.zig+1-1| ... | ... | @@ -3377,7 +3377,7 @@ pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize { |
| 3377 | 3377 | const result = set[0 .. rc / @sizeOf(usize)]; |
| 3378 | 3378 | var sum: usize = 0; |
| 3379 | 3379 | for (result) |x| { |
| 3380 | sum += @popCount(x); | |
| 3380 | sum += @popCount(usize, x); | |
| 3381 | 3381 | } |
| 3382 | 3382 | return sum; |
| 3383 | 3383 | } else { |
std/packed_int_array.zig+3-3| ... | ... | @@ -66,7 +66,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { |
| 66 | 66 | const value_ptr = @ptrCast(*align(1) const Container, &bytes[start_byte]); |
| 67 | 67 | var value = value_ptr.*; |
| 68 | 68 | |
| 69 | if (endian != builtin.endian) value = @bswap(Container, value); | |
| 69 | if (endian != builtin.endian) value = @byteSwap(Container, value); | |
| 70 | 70 | |
| 71 | 71 | switch (endian) { |
| 72 | 72 | .Big => { |
| ... | ... | @@ -114,7 +114,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { |
| 114 | 114 | const target_ptr = @ptrCast(*align(1) Container, &bytes[start_byte]); |
| 115 | 115 | var target = target_ptr.*; |
| 116 | 116 | |
| 117 | if (endian != builtin.endian) target = @bswap(Container, target); | |
| 117 | if (endian != builtin.endian) target = @byteSwap(Container, target); | |
| 118 | 118 | |
| 119 | 119 | //zero the bits we want to replace in the existing bytes |
| 120 | 120 | const inv_mask = @intCast(Container, std.math.maxInt(UnInt)) << keep_shift; |
| ... | ... | @@ -124,7 +124,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { |
| 124 | 124 | //merge the new value |
| 125 | 125 | target |= value; |
| 126 | 126 | |
| 127 | if (endian != builtin.endian) target = @bswap(Container, target); | |
| 127 | if (endian != builtin.endian) target = @byteSwap(Container, target); | |
| 128 | 128 | |
| 129 | 129 | //save it back |
| 130 | 130 | target_ptr.* = target; |
std/special/compiler_rt.zig+1-2| ... | ... | @@ -19,7 +19,6 @@ comptime { |
| 19 | 19 | @export("__getf2", @import("compiler_rt/comparetf2.zig").__getf2, linkage); |
| 20 | 20 | |
| 21 | 21 | if (!is_test) { |
| 22 | // only create these aliases when not testing | |
| 23 | 22 | @export("__cmpsf2", @import("compiler_rt/comparesf2.zig").__lesf2, linkage); |
| 24 | 23 | @export("__cmpdf2", @import("compiler_rt/comparedf2.zig").__ledf2, linkage); |
| 25 | 24 | @export("__cmptf2", @import("compiler_rt/comparetf2.zig").__letf2, linkage); |
| ... | ... | @@ -599,7 +598,7 @@ extern fn __udivsi3(n: u32, d: u32) u32 { |
| 599 | 598 | // special cases |
| 600 | 599 | if (d == 0) return 0; // ?! |
| 601 | 600 | if (n == 0) return 0; |
| 602 | var sr = @bitCast(c_uint, c_int(@clz(d)) - c_int(@clz(n))); | |
| 601 | var sr = @bitCast(c_uint, c_int(@clz(u32, d)) - c_int(@clz(u32, n))); | |
| 603 | 602 | // 0 <= sr <= n_uword_bits - 1 or sr large |
| 604 | 603 | if (sr > n_uword_bits - 1) { |
| 605 | 604 | // d > r |
std/special/compiler_rt/addXf3.zig+4-4| ... | ... | @@ -36,11 +36,11 @@ pub extern fn __subtf3(a: f128, b: f128) f128 { |
| 36 | 36 | // TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154 |
| 37 | 37 | fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { |
| 38 | 38 | const Z = @IntType(false, T.bit_count); |
| 39 | const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1)); | |
| 39 | const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1)); | |
| 40 | 40 | const significandBits = std.math.floatMantissaBits(T); |
| 41 | 41 | const implicitBit = Z(1) << significandBits; |
| 42 | 42 | |
| 43 | const shift = @clz(significand.*) - @clz(implicitBit); | |
| 43 | const shift = @clz(@IntType(false, T.bit_count), significand.*) - @clz(Z, implicitBit); | |
| 44 | 44 | significand.* <<= @intCast(S, shift); |
| 45 | 45 | return 1 - shift; |
| 46 | 46 | } |
| ... | ... | @@ -48,7 +48,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { |
| 48 | 48 | // TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154 |
| 49 | 49 | fn addXf3(comptime T: type, a: T, b: T) T { |
| 50 | 50 | const Z = @IntType(false, T.bit_count); |
| 51 | const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1)); | |
| 51 | const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1)); | |
| 52 | 52 | |
| 53 | 53 | const typeWidth = T.bit_count; |
| 54 | 54 | const significandBits = std.math.floatMantissaBits(T); |
| ... | ... | @@ -162,7 +162,7 @@ fn addXf3(comptime T: type, a: T, b: T) T { |
| 162 | 162 | // If partial cancellation occured, we need to left-shift the result |
| 163 | 163 | // and adjust the exponent: |
| 164 | 164 | if (aSignificand < implicitBit << 3) { |
| 165 | const shift = @intCast(i32, @clz(aSignificand)) - @intCast(i32, @clz(implicitBit << 3)); | |
| 165 | const shift = @intCast(i32, @clz(Z, aSignificand)) - @intCast(i32, @clz(@IntType(false, T.bit_count), implicitBit << 3)); | |
| 166 | 166 | aSignificand <<= @intCast(S, shift); |
| 167 | 167 | aExponent -= shift; |
| 168 | 168 | } |
std/special/compiler_rt/divdf3.zig+1-1| ... | ... | @@ -318,7 +318,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { |
| 318 | 318 | const significandBits = std.math.floatMantissaBits(T); |
| 319 | 319 | const implicitBit = Z(1) << significandBits; |
| 320 | 320 | |
| 321 | const shift = @clz(significand.*) - @clz(implicitBit); | |
| 321 | const shift = @clz(Z, significand.*) - @clz(Z, implicitBit); | |
| 322 | 322 | significand.* <<= @intCast(std.math.Log2Int(Z), shift); |
| 323 | 323 | return 1 - shift; |
| 324 | 324 | } |
std/special/compiler_rt/divsf3.zig+1-1| ... | ... | @@ -191,7 +191,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { |
| 191 | 191 | const significandBits = std.math.floatMantissaBits(T); |
| 192 | 192 | const implicitBit = Z(1) << significandBits; |
| 193 | 193 | |
| 194 | const shift = @clz(significand.*) - @clz(implicitBit); | |
| 194 | const shift = @clz(Z, significand.*) - @clz(Z, implicitBit); | |
| 195 | 195 | significand.* <<= @intCast(std.math.Log2Int(Z), shift); |
| 196 | 196 | return 1 - shift; |
| 197 | 197 | } |
std/special/compiler_rt/extendXfYf2.zig+2-1| ... | ... | @@ -75,7 +75,8 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t |
| 75 | 75 | // a is denormal. |
| 76 | 76 | // renormalize the significand and clear the leading bit, then insert |
| 77 | 77 | // the correct adjusted exponent in the destination type. |
| 78 | const scale: u32 = @clz(aAbs) - @clz(src_rep_t(srcMinNormal)); | |
| 78 | const scale: u32 = @clz(src_rep_t, aAbs) - | |
| 79 | @clz(src_rep_t, src_rep_t(srcMinNormal)); | |
| 79 | 80 | absResult = dst_rep_t(aAbs) << @intCast(DstShift, dstSigBits - srcSigBits + scale); |
| 80 | 81 | absResult ^= dstMinNormal; |
| 81 | 82 | const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1; |
std/special/compiler_rt/floatsiXf.zig+2-2| ... | ... | @@ -6,7 +6,7 @@ fn floatsiXf(comptime T: type, a: i32) T { |
| 6 | 6 | @setRuntimeSafety(builtin.is_test); |
| 7 | 7 | |
| 8 | 8 | const Z = @IntType(false, T.bit_count); |
| 9 | const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1)); | |
| 9 | const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1)); | |
| 10 | 10 | |
| 11 | 11 | if (a == 0) { |
| 12 | 12 | return T(0.0); |
| ... | ... | @@ -23,7 +23,7 @@ fn floatsiXf(comptime T: type, a: i32) T { |
| 23 | 23 | // Take absolute value of a via abs(x) = (x^(x >> 31)) - (x >> 31). |
| 24 | 24 | const abs_a = (a ^ sign) -% sign; |
| 25 | 25 | // The exponent is the width of abs(a) |
| 26 | const exp = Z(31 - @clz(abs_a)); | |
| 26 | const exp = Z(31 - @clz(i32, abs_a)); | |
| 27 | 27 | |
| 28 | 28 | const sign_bit = if (sign < 0) signBit else 0; |
| 29 | 29 |
std/special/compiler_rt/floattidf.zig+1-1| ... | ... | @@ -17,7 +17,7 @@ pub extern fn __floattidf(arg: i128) f64 { |
| 17 | 17 | ai = ((ai ^ si) -% si); |
| 18 | 18 | var a = @bitCast(u128, ai); |
| 19 | 19 | |
| 20 | const sd = @bitCast(i32, N - @clz(a)); // number of significant digits | |
| 20 | const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits | |
| 21 | 21 | var e: i32 = sd - 1; // exponent |
| 22 | 22 | if (sd > DBL_MANT_DIG) { |
| 23 | 23 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx |
std/special/compiler_rt/floattisf.zig+1-1| ... | ... | @@ -17,7 +17,7 @@ pub extern fn __floattisf(arg: i128) f32 { |
| 17 | 17 | ai = ((ai ^ si) -% si); |
| 18 | 18 | var a = @bitCast(u128, ai); |
| 19 | 19 | |
| 20 | const sd = @bitCast(i32, N - @clz(a)); // number of significant digits | |
| 20 | const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits | |
| 21 | 21 | var e: i32 = sd - 1; // exponent |
| 22 | 22 | |
| 23 | 23 | if (sd > FLT_MANT_DIG) { |
std/special/compiler_rt/floattitf.zig+1-1| ... | ... | @@ -17,7 +17,7 @@ pub extern fn __floattitf(arg: i128) f128 { |
| 17 | 17 | ai = ((ai ^ si) -% si); |
| 18 | 18 | var a = @bitCast(u128, ai); |
| 19 | 19 | |
| 20 | const sd = @bitCast(i32, N - @clz(a)); // number of significant digits | |
| 20 | const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits | |
| 21 | 21 | var e: i32 = sd - 1; // exponent |
| 22 | 22 | if (sd > LDBL_MANT_DIG) { |
| 23 | 23 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx |
std/special/compiler_rt/floatunditf.zig+1-1| ... | ... | @@ -14,7 +14,7 @@ pub extern fn __floatunditf(a: u128) f128 { |
| 14 | 14 | const exponent_bias = (1 << (exponent_bits - 1)) - 1; |
| 15 | 15 | const implicit_bit = 1 << mantissa_bits; |
| 16 | 16 | |
| 17 | const exp = (u128.bit_count - 1) - @clz(a); | |
| 17 | const exp = (u128.bit_count - 1) - @clz(u128, a); | |
| 18 | 18 | const shift = mantissa_bits - @intCast(u7, exp); |
| 19 | 19 | |
| 20 | 20 | var result: u128 align(16) = (a << shift) ^ implicit_bit; |
std/special/compiler_rt/floatunsidf.zig+1-1| ... | ... | @@ -10,7 +10,7 @@ pub extern fn __floatunsidf(arg: u32) f64 { |
| 10 | 10 | if (arg == 0) return 0.0; |
| 11 | 11 | |
| 12 | 12 | // The exponent is the width of abs(a) |
| 13 | const exp = u64(31) - @clz(arg); | |
| 13 | const exp = u64(31) - @clz(u32, arg); | |
| 14 | 14 | // Shift a into the significand field and clear the implicit bit |
| 15 | 15 | const shift = @intCast(u6, 52 - exp); |
| 16 | 16 | const mant = u64(arg) << shift ^ implicitBit; |
std/special/compiler_rt/floatunsitf.zig+1-1| ... | ... | @@ -14,7 +14,7 @@ pub extern fn __floatunsitf(a: u64) f128 { |
| 14 | 14 | const exponent_bias = (1 << (exponent_bits - 1)) - 1; |
| 15 | 15 | const implicit_bit = 1 << mantissa_bits; |
| 16 | 16 | |
| 17 | const exp = (u64.bit_count - 1) - @clz(a); | |
| 17 | const exp = (u64.bit_count - 1) - @clz(u64, a); | |
| 18 | 18 | const shift = mantissa_bits - @intCast(u7, exp); |
| 19 | 19 | |
| 20 | 20 | // TODO(#1148): @bitCast alignment error |
std/special/compiler_rt/floatuntidf.zig+1-1| ... | ... | @@ -13,7 +13,7 @@ pub extern fn __floatuntidf(arg: u128) f64 { |
| 13 | 13 | |
| 14 | 14 | var a = arg; |
| 15 | 15 | const N: u32 = @sizeOf(u128) * 8; |
| 16 | const sd = @bitCast(i32, N - @clz(a)); // number of significant digits | |
| 16 | const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits | |
| 17 | 17 | var e: i32 = sd - 1; // exponent |
| 18 | 18 | if (sd > DBL_MANT_DIG) { |
| 19 | 19 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx |
std/special/compiler_rt/floatuntisf.zig+1-1| ... | ... | @@ -13,7 +13,7 @@ pub extern fn __floatuntisf(arg: u128) f32 { |
| 13 | 13 | |
| 14 | 14 | var a = arg; |
| 15 | 15 | const N: u32 = @sizeOf(u128) * 8; |
| 16 | const sd = @bitCast(i32, N - @clz(a)); // number of significant digits | |
| 16 | const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits | |
| 17 | 17 | var e: i32 = sd - 1; // exponent |
| 18 | 18 | if (sd > FLT_MANT_DIG) { |
| 19 | 19 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx |
std/special/compiler_rt/floatuntitf.zig+1-1| ... | ... | @@ -13,7 +13,7 @@ pub extern fn __floatuntitf(arg: u128) f128 { |
| 13 | 13 | |
| 14 | 14 | var a = arg; |
| 15 | 15 | const N: u32 = @sizeOf(u128) * 8; |
| 16 | const sd = @bitCast(i32, N - @clz(a)); // number of significant digits | |
| 16 | const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits | |
| 17 | 17 | var e: i32 = sd - 1; // exponent |
| 18 | 18 | if (sd > LDBL_MANT_DIG) { |
| 19 | 19 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx |
std/special/compiler_rt/mulXf3.zig+1-1| ... | ... | @@ -260,7 +260,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { |
| 260 | 260 | const significandBits = std.math.floatMantissaBits(T); |
| 261 | 261 | const implicitBit = Z(1) << significandBits; |
| 262 | 262 | |
| 263 | const shift = @clz(significand.*) - @clz(implicitBit); | |
| 263 | const shift = @clz(Z, significand.*) - @clz(Z, implicitBit); | |
| 264 | 264 | significand.* <<= @intCast(std.math.Log2Int(Z), shift); |
| 265 | 265 | return 1 - shift; |
| 266 | 266 | } |
std/special/compiler_rt/udivmod.zig+5-5| ... | ... | @@ -71,12 +71,12 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 71 | 71 | r[high] = n[high] & (d[high] - 1); |
| 72 | 72 | rem.* = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421 |
| 73 | 73 | } |
| 74 | return n[high] >> @intCast(Log2SingleInt, @ctz(d[high])); | |
| 74 | return n[high] >> @intCast(Log2SingleInt, @ctz(SingleInt, d[high])); | |
| 75 | 75 | } |
| 76 | 76 | // K K |
| 77 | 77 | // --- |
| 78 | 78 | // K 0 |
| 79 | sr = @bitCast(c_uint, c_int(@clz(d[high])) - c_int(@clz(n[high]))); | |
| 79 | sr = @bitCast(c_uint, c_int(@clz(SingleInt, d[high])) - c_int(@clz(SingleInt, n[high]))); | |
| 80 | 80 | // 0 <= sr <= SingleInt.bit_count - 2 or sr large |
| 81 | 81 | if (sr > SingleInt.bit_count - 2) { |
| 82 | 82 | if (maybe_rem) |rem| { |
| ... | ... | @@ -106,7 +106,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 106 | 106 | if (d[low] == 1) { |
| 107 | 107 | return a; |
| 108 | 108 | } |
| 109 | sr = @ctz(d[low]); | |
| 109 | sr = @ctz(SingleInt, d[low]); | |
| 110 | 110 | q[high] = n[high] >> @intCast(Log2SingleInt, sr); |
| 111 | 111 | q[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr)); |
| 112 | 112 | return @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &q[0]).*; // TODO issue #421 |
| ... | ... | @@ -114,7 +114,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 114 | 114 | // K X |
| 115 | 115 | // --- |
| 116 | 116 | // 0 K |
| 117 | sr = 1 + SingleInt.bit_count + c_uint(@clz(d[low])) - c_uint(@clz(n[high])); | |
| 117 | sr = 1 + SingleInt.bit_count + c_uint(@clz(SingleInt, d[low])) - c_uint(@clz(SingleInt, n[high])); | |
| 118 | 118 | // 2 <= sr <= DoubleInt.bit_count - 1 |
| 119 | 119 | // q.all = a << (DoubleInt.bit_count - sr); |
| 120 | 120 | // r.all = a >> sr; |
| ... | ... | @@ -140,7 +140,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 140 | 140 | // K X |
| 141 | 141 | // --- |
| 142 | 142 | // K K |
| 143 | sr = @bitCast(c_uint, c_int(@clz(d[high])) - c_int(@clz(n[high]))); | |
| 143 | sr = @bitCast(c_uint, c_int(@clz(SingleInt, d[high])) - c_int(@clz(SingleInt, n[high]))); | |
| 144 | 144 | // 0 <= sr <= SingleInt.bit_count - 1 or sr large |
| 145 | 145 | if (sr > SingleInt.bit_count - 1) { |
| 146 | 146 | if (maybe_rem) |rem| { |
test/compile_errors.zig+1-10| ... | ... | @@ -1363,21 +1363,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1363 | 1363 | cases.add( |
| 1364 | 1364 | "@popCount - non-integer", |
| 1365 | 1365 | \\export fn entry(x: f32) u32 { |
| 1366 | \\ return @popCount(x); | |
| 1366 | \\ return @popCount(f32, x); | |
| 1367 | 1367 | \\} |
| 1368 | 1368 | , |
| 1369 | 1369 | "tmp.zig:2:22: error: expected integer type, found 'f32'", |
| 1370 | 1370 | ); |
| 1371 | 1371 | |
| 1372 | cases.add( | |
| 1373 | "@popCount - negative comptime_int", | |
| 1374 | \\comptime { | |
| 1375 | \\ _ = @popCount(-1); | |
| 1376 | \\} | |
| 1377 | , | |
| 1378 | "tmp.zig:2:9: error: @popCount on negative comptime_int value -1", | |
| 1379 | ); | |
| 1380 | ||
| 1381 | 1372 | cases.addCase(x: { |
| 1382 | 1373 | const tc = cases.create( |
| 1383 | 1374 | "wrong same named struct", |
test/stage1/behavior.zig+1-1| ... | ... | @@ -8,7 +8,7 @@ comptime { |
| 8 | 8 | _ = @import("behavior/bitcast.zig"); |
| 9 | 9 | _ = @import("behavior/bitreverse.zig"); |
| 10 | 10 | _ = @import("behavior/bool.zig"); |
| 11 | _ = @import("behavior/bswap.zig"); | |
| 11 | _ = @import("behavior/byteswap.zig"); | |
| 12 | 12 | _ = @import("behavior/bugs/1025.zig"); |
| 13 | 13 | _ = @import("behavior/bugs/1076.zig"); |
| 14 | 14 | _ = @import("behavior/bugs/1111.zig"); |
test/stage1/behavior/bitreverse.zig+38-50| ... | ... | @@ -2,80 +2,68 @@ const std = @import("std"); |
| 2 | 2 | const expect = std.testing.expect; |
| 3 | 3 | const minInt = std.math.minInt; |
| 4 | 4 | |
| 5 | test "@bitreverse" { | |
| 5 | test "@bitReverse" { | |
| 6 | 6 | comptime testBitReverse(); |
| 7 | 7 | testBitReverse(); |
| 8 | 8 | } |
| 9 | 9 | |
| 10 | 10 | fn testBitReverse() void { |
| 11 | 11 | // using comptime_ints, unsigned |
| 12 | expect(@bitreverse(u0, 0) == 0); | |
| 13 | expect(@bitreverse(u5, 0x12) == 0x9); | |
| 14 | expect(@bitreverse(u8, 0x12) == 0x48); | |
| 15 | expect(@bitreverse(u16, 0x1234) == 0x2c48); | |
| 16 | expect(@bitreverse(u24, 0x123456) == 0x6a2c48); | |
| 17 | expect(@bitreverse(u32, 0x12345678) == 0x1e6a2c48); | |
| 18 | expect(@bitreverse(u40, 0x123456789a) == 0x591e6a2c48); | |
| 19 | expect(@bitreverse(u48, 0x123456789abc) == 0x3d591e6a2c48); | |
| 20 | expect(@bitreverse(u56, 0x123456789abcde) == 0x7b3d591e6a2c48); | |
| 21 | expect(@bitreverse(u64, 0x123456789abcdef1) == 0x8f7b3d591e6a2c48); | |
| 22 | expect(@bitreverse(u128, 0x123456789abcdef11121314151617181) == 0x818e868a828c84888f7b3d591e6a2c48); | |
| 12 | expect(@bitReverse(u0, u0(0)) == 0); | |
| 13 | expect(@bitReverse(u5, u5(0x12)) == 0x9); | |
| 14 | expect(@bitReverse(u8, u8(0x12)) == 0x48); | |
| 15 | expect(@bitReverse(u16, u16(0x1234)) == 0x2c48); | |
| 16 | expect(@bitReverse(u24, u24(0x123456)) == 0x6a2c48); | |
| 17 | expect(@bitReverse(u32, u32(0x12345678)) == 0x1e6a2c48); | |
| 18 | expect(@bitReverse(u40, u40(0x123456789a)) == 0x591e6a2c48); | |
| 19 | expect(@bitReverse(u48, u48(0x123456789abc)) == 0x3d591e6a2c48); | |
| 20 | expect(@bitReverse(u56, u56(0x123456789abcde)) == 0x7b3d591e6a2c48); | |
| 21 | expect(@bitReverse(u64, u64(0x123456789abcdef1)) == 0x8f7b3d591e6a2c48); | |
| 22 | expect(@bitReverse(u128, u128(0x123456789abcdef11121314151617181)) == 0x818e868a828c84888f7b3d591e6a2c48); | |
| 23 | 23 | |
| 24 | 24 | // using runtime uints, unsigned |
| 25 | 25 | var num0: u0 = 0; |
| 26 | expect(@bitreverse(u0, num0) == 0); | |
| 26 | expect(@bitReverse(u0, num0) == 0); | |
| 27 | 27 | var num5: u5 = 0x12; |
| 28 | expect(@bitreverse(u5, num5) == 0x9); | |
| 28 | expect(@bitReverse(u5, num5) == 0x9); | |
| 29 | 29 | var num8: u8 = 0x12; |
| 30 | expect(@bitreverse(u8, num8) == 0x48); | |
| 30 | expect(@bitReverse(u8, num8) == 0x48); | |
| 31 | 31 | var num16: u16 = 0x1234; |
| 32 | expect(@bitreverse(u16, num16) == 0x2c48); | |
| 32 | expect(@bitReverse(u16, num16) == 0x2c48); | |
| 33 | 33 | var num24: u24 = 0x123456; |
| 34 | expect(@bitreverse(u24, num24) == 0x6a2c48); | |
| 34 | expect(@bitReverse(u24, num24) == 0x6a2c48); | |
| 35 | 35 | var num32: u32 = 0x12345678; |
| 36 | expect(@bitreverse(u32, num32) == 0x1e6a2c48); | |
| 36 | expect(@bitReverse(u32, num32) == 0x1e6a2c48); | |
| 37 | 37 | var num40: u40 = 0x123456789a; |
| 38 | expect(@bitreverse(u40, num40) == 0x591e6a2c48); | |
| 38 | expect(@bitReverse(u40, num40) == 0x591e6a2c48); | |
| 39 | 39 | var num48: u48 = 0x123456789abc; |
| 40 | expect(@bitreverse(u48, num48) == 0x3d591e6a2c48); | |
| 40 | expect(@bitReverse(u48, num48) == 0x3d591e6a2c48); | |
| 41 | 41 | var num56: u56 = 0x123456789abcde; |
| 42 | expect(@bitreverse(u56, num56) == 0x7b3d591e6a2c48); | |
| 42 | expect(@bitReverse(u56, num56) == 0x7b3d591e6a2c48); | |
| 43 | 43 | var num64: u64 = 0x123456789abcdef1; |
| 44 | expect(@bitreverse(u64, num64) == 0x8f7b3d591e6a2c48); | |
| 44 | expect(@bitReverse(u64, num64) == 0x8f7b3d591e6a2c48); | |
| 45 | 45 | var num128: u128 = 0x123456789abcdef11121314151617181; |
| 46 | expect(@bitreverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48); | |
| 46 | expect(@bitReverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48); | |
| 47 | 47 | |
| 48 | 48 | // using comptime_ints, signed, positive |
| 49 | expect(@bitreverse(i0, 0) == 0); | |
| 50 | expect(@bitreverse(i8, @bitCast(i8, u8(0x92))) == @bitCast(i8, u8(0x49))); | |
| 51 | expect(@bitreverse(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x2c48))); | |
| 52 | expect(@bitreverse(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x6a2c48))); | |
| 53 | expect(@bitreverse(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x1e6a2c48))); | |
| 54 | expect(@bitreverse(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x591e6a2c48))); | |
| 55 | expect(@bitreverse(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0x3d591e6a2c48))); | |
| 56 | expect(@bitreverse(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0x7b3d591e6a2c48))); | |
| 57 | expect(@bitreverse(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0x8f7b3d591e6a2c48))); | |
| 58 | expect(@bitreverse(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == @bitCast(i128, u128(0x818e868a828c84888f7b3d591e6a2c48))); | |
| 49 | expect(@bitReverse(u8, u8(0)) == 0); | |
| 50 | expect(@bitReverse(i8, @bitCast(i8, u8(0x92))) == @bitCast(i8, u8(0x49))); | |
| 51 | expect(@bitReverse(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x2c48))); | |
| 52 | expect(@bitReverse(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x6a2c48))); | |
| 53 | expect(@bitReverse(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x1e6a2c48))); | |
| 54 | expect(@bitReverse(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x591e6a2c48))); | |
| 55 | expect(@bitReverse(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0x3d591e6a2c48))); | |
| 56 | expect(@bitReverse(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0x7b3d591e6a2c48))); | |
| 57 | expect(@bitReverse(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0x8f7b3d591e6a2c48))); | |
| 58 | expect(@bitReverse(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == @bitCast(i128, u128(0x818e868a828c84888f7b3d591e6a2c48))); | |
| 59 | 59 | |
| 60 | // using comptime_ints, signed, negative. Compare to runtime ints returned from llvm. | |
| 61 | var neg5: i5 = minInt(i5) + 1; | |
| 62 | expect(@bitreverse(i5, minInt(i5) + 1) == @bitreverse(i5, neg5)); | |
| 60 | // using signed, negative. Compare to runtime ints returned from llvm. | |
| 63 | 61 | var neg8: i8 = -18; |
| 64 | expect(@bitreverse(i8, -18) == @bitreverse(i8, neg8)); | |
| 62 | expect(@bitReverse(i8, i8(-18)) == @bitReverse(i8, neg8)); | |
| 65 | 63 | var neg16: i16 = -32694; |
| 66 | expect(@bitreverse(i16, -32694) == @bitreverse(i16, neg16)); | |
| 64 | expect(@bitReverse(i16, i16(-32694)) == @bitReverse(i16, neg16)); | |
| 67 | 65 | var neg24: i24 = -6773785; |
| 68 | expect(@bitreverse(i24, -6773785) == @bitreverse(i24, neg24)); | |
| 66 | expect(@bitReverse(i24, i24(-6773785)) == @bitReverse(i24, neg24)); | |
| 69 | 67 | var neg32: i32 = -16773785; |
| 70 | expect(@bitreverse(i32, -16773785) == @bitreverse(i32, neg32)); | |
| 71 | var neg40: i40 = minInt(i40) + 12345; | |
| 72 | expect(@bitreverse(i40, minInt(i40) + 12345) == @bitreverse(i40, neg40)); | |
| 73 | var neg48: i48 = minInt(i48) + 12345; | |
| 74 | expect(@bitreverse(i48, minInt(i48) + 12345) == @bitreverse(i48, neg48)); | |
| 75 | var neg56: i56 = minInt(i56) + 12345; | |
| 76 | expect(@bitreverse(i56, minInt(i56) + 12345) == @bitreverse(i56, neg56)); | |
| 77 | var neg64: i64 = minInt(i64) + 12345; | |
| 78 | expect(@bitreverse(i64, minInt(i64) + 12345) == @bitreverse(i64, neg64)); | |
| 79 | var neg128: i128 = minInt(i128) + 12345; | |
| 80 | expect(@bitreverse(i128, minInt(i128) + 12345) == @bitreverse(i128, neg128)); | |
| 68 | expect(@bitReverse(i32, i32(-16773785)) == @bitReverse(i32, neg32)); | |
| 81 | 69 | } |
test/stage1/behavior/bswap.zig deleted-32| ... | ... | @@ -1,32 +0,0 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "@bswap" { | |
| 5 | comptime testByteSwap(); | |
| 6 | testByteSwap(); | |
| 7 | } | |
| 8 | ||
| 9 | fn testByteSwap() void { | |
| 10 | expect(@bswap(u0, 0) == 0); | |
| 11 | expect(@bswap(u8, 0x12) == 0x12); | |
| 12 | expect(@bswap(u16, 0x1234) == 0x3412); | |
| 13 | expect(@bswap(u24, 0x123456) == 0x563412); | |
| 14 | expect(@bswap(u32, 0x12345678) == 0x78563412); | |
| 15 | expect(@bswap(u40, 0x123456789a) == 0x9a78563412); | |
| 16 | expect(@bswap(u48, 0x123456789abc) == 0xbc9a78563412); | |
| 17 | expect(@bswap(u56, 0x123456789abcde) == 0xdebc9a78563412); | |
| 18 | expect(@bswap(u64, 0x123456789abcdef1) == 0xf1debc9a78563412); | |
| 19 | expect(@bswap(u128, 0x123456789abcdef11121314151617181) == 0x8171615141312111f1debc9a78563412); | |
| 20 | ||
| 21 | expect(@bswap(i0, 0) == 0); | |
| 22 | expect(@bswap(i8, -50) == -50); | |
| 23 | expect(@bswap(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x3412))); | |
| 24 | expect(@bswap(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x563412))); | |
| 25 | expect(@bswap(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x78563412))); | |
| 26 | expect(@bswap(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x9a78563412))); | |
| 27 | expect(@bswap(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0xbc9a78563412))); | |
| 28 | expect(@bswap(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0xdebc9a78563412))); | |
| 29 | expect(@bswap(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0xf1debc9a78563412))); | |
| 30 | expect(@bswap(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == | |
| 31 | @bitCast(i128, u128(0x8171615141312111f1debc9a78563412))); | |
| 32 | } |
test/stage1/behavior/bugs/2114.zig+1-1| ... | ... | @@ -3,7 +3,7 @@ const expect = std.testing.expect; |
| 3 | 3 | const math = std.math; |
| 4 | 4 | |
| 5 | 5 | fn ctz(x: var) usize { |
| 6 | return @ctz(x); | |
| 6 | return @ctz(u128, x); | |
| 7 | 7 | } |
| 8 | 8 | |
| 9 | 9 | test "fixed" { |
test/stage1/behavior/byteswap.zig created+32| ... | ... | @@ -0,0 +1,32 @@ |
| 1 | const std = @import("std"); | |
| 2 | const expect = std.testing.expect; | |
| 3 | ||
| 4 | test "@byteSwap" { | |
| 5 | comptime testByteSwap(); | |
| 6 | testByteSwap(); | |
| 7 | } | |
| 8 | ||
| 9 | fn testByteSwap() void { | |
| 10 | expect(@byteSwap(u0, u0(0)) == 0); | |
| 11 | expect(@byteSwap(u8, u8(0x12)) == 0x12); | |
| 12 | expect(@byteSwap(u16, u16(0x1234)) == 0x3412); | |
| 13 | expect(@byteSwap(u24, u24(0x123456)) == 0x563412); | |
| 14 | expect(@byteSwap(u32, u32(0x12345678)) == 0x78563412); | |
| 15 | expect(@byteSwap(u40, u40(0x123456789a)) == 0x9a78563412); | |
| 16 | expect(@byteSwap(i48, u48(0x123456789abc)) == @bitCast(i48, u48(0xbc9a78563412))); | |
| 17 | expect(@byteSwap(u56, u56(0x123456789abcde)) == 0xdebc9a78563412); | |
| 18 | expect(@byteSwap(u64, u64(0x123456789abcdef1)) == 0xf1debc9a78563412); | |
| 19 | expect(@byteSwap(u128, u128(0x123456789abcdef11121314151617181)) == 0x8171615141312111f1debc9a78563412); | |
| 20 | ||
| 21 | expect(@byteSwap(u0, u0(0)) == 0); | |
| 22 | expect(@byteSwap(i8, i8(-50)) == -50); | |
| 23 | expect(@byteSwap(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x3412))); | |
| 24 | expect(@byteSwap(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x563412))); | |
| 25 | expect(@byteSwap(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x78563412))); | |
| 26 | expect(@byteSwap(u40, @bitCast(i40, u40(0x123456789a))) == u40(0x9a78563412)); | |
| 27 | expect(@byteSwap(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0xbc9a78563412))); | |
| 28 | expect(@byteSwap(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0xdebc9a78563412))); | |
| 29 | expect(@byteSwap(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0xf1debc9a78563412))); | |
| 30 | expect(@byteSwap(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == | |
| 31 | @bitCast(i128, u128(0x8171615141312111f1debc9a78563412))); | |
| 32 | } |
test/stage1/behavior/math.zig+25-12| ... | ... | @@ -114,15 +114,16 @@ test "@clz" { |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | 116 | fn testClz() void { |
| 117 | expect(clz(u8(0b00001010)) == 4); | |
| 118 | expect(clz(u8(0b10001010)) == 0); | |
| 119 | expect(clz(u8(0b00000000)) == 8); | |
| 120 | expect(clz(u128(0xffffffffffffffff)) == 64); | |
| 121 | expect(clz(u128(0x10000000000000000)) == 63); | |
| 117 | expect(clz(u8, u8(0b10001010)) == 0); | |
| 118 | expect(clz(u8, u8(0b00001010)) == 4); | |
| 119 | expect(clz(u8, u8(0b00011010)) == 3); | |
| 120 | expect(clz(u8, u8(0b00000000)) == 8); | |
| 121 | expect(clz(u128, u128(0xffffffffffffffff)) == 64); | |
| 122 | expect(clz(u128, u128(0x10000000000000000)) == 63); | |
| 122 | 123 | } |
| 123 | 124 | |
| 124 | fn clz(x: var) usize { | |
| 125 | return @clz(x); | |
| 125 | fn clz(comptime T: type, x: T) usize { | |
| 126 | return @clz(T, x); | |
| 126 | 127 | } |
| 127 | 128 | |
| 128 | 129 | test "@ctz" { |
| ... | ... | @@ -131,13 +132,25 @@ test "@ctz" { |
| 131 | 132 | } |
| 132 | 133 | |
| 133 | 134 | fn testCtz() void { |
| 134 | expect(ctz(u8(0b10100000)) == 5); | |
| 135 | expect(ctz(u8(0b10001010)) == 1); | |
| 136 | expect(ctz(u8(0b00000000)) == 8); | |
| 135 | expect(ctz(u8, u8(0b10100000)) == 5); | |
| 136 | expect(ctz(u8, u8(0b10001010)) == 1); | |
| 137 | expect(ctz(u8, u8(0b00000000)) == 8); | |
| 138 | expect(ctz(u16, u16(0b00000000)) == 16); | |
| 137 | 139 | } |
| 138 | 140 | |
| 139 | fn ctz(x: var) usize { | |
| 140 | return @ctz(x); | |
| 141 | fn ctz(comptime T: type, x: T) usize { | |
| 142 | return @ctz(T, x); | |
| 143 | } | |
| 144 | ||
| 145 | pub fn Log2Int(comptime T: type) type { | |
| 146 | // comptime ceil log2 | |
| 147 | comptime var count = 0; | |
| 148 | comptime var s = T.bit_count - 1; | |
| 149 | inline while (s != 0) : (s >>= 1) { | |
| 150 | count += 1; | |
| 151 | } | |
| 152 | ||
| 153 | return @IntType(false, count); | |
| 141 | 154 | } |
| 142 | 155 | |
| 143 | 156 | test "assignment operators" { |
test/stage1/behavior/popcount.zig+23-4| ... | ... | @@ -6,20 +6,39 @@ test "@popCount" { |
| 6 | 6 | } |
| 7 | 7 | |
| 8 | 8 | fn testPopCount() void { |
| 9 | { | |
| 10 | var x: u32 = 0xffffffff; | |
| 11 | expect(@popCount(u32, x) == 32); | |
| 12 | } | |
| 13 | { | |
| 14 | var x: u5 = 0x1f; | |
| 15 | expect(@popCount(u5, x) == 5); | |
| 16 | } | |
| 9 | 17 | { |
| 10 | 18 | var x: u32 = 0xaa; |
| 11 | expect(@popCount(x) == 4); | |
| 19 | expect(@popCount(u32, x) == 4); | |
| 12 | 20 | } |
| 13 | 21 | { |
| 14 | 22 | var x: u32 = 0xaaaaaaaa; |
| 15 | expect(@popCount(x) == 16); | |
| 23 | expect(@popCount(u32, x) == 16); | |
| 24 | } | |
| 25 | { | |
| 26 | var x: u32 = 0xaaaaaaaa; | |
| 27 | expect(@popCount(u32, x) == 16); | |
| 16 | 28 | } |
| 17 | 29 | { |
| 18 | 30 | var x: i16 = -1; |
| 19 | expect(@popCount(x) == 16); | |
| 31 | expect(@popCount(i16, x) == 16); | |
| 32 | } | |
| 33 | { | |
| 34 | var x: i8 = -120; | |
| 35 | expect(@popCount(i8, x) == 2); | |
| 36 | } | |
| 37 | comptime { | |
| 38 | expect(@popCount(u8, @bitCast(u8, i8(-120))) == 2); | |
| 20 | 39 | } |
| 21 | 40 | comptime { |
| 22 | expect(@popCount(0b11111111000110001100010000100001000011000011100101010001) == 24); | |
| 41 | expect(@popCount(i128, u128(0b11111111000110001100010000100001000011000011100101010001)) == 24); | |
| 23 | 42 | } |
| 24 | 43 | } |
| 25 | 44 |