authorgravatar for shawn@git.icuShawn Landden <shawn@git.icu> 2019-04-03 09:00:39-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-05-16 16:37:58-04:00
log1fdb24827fb51351d5e31103069619668fae31c4
treeeccc305b5cbbdfe7e9d6cbbad945f4f32c6aa136
parent56a905c7d16c79138b4581a84f1f844bce2f00eb
signaturelock-open Commit is signed but in an unrecognized format.

breaking changes to all bit manipulation intrinsics

* `@clz`, `@ctz`, `@popCount`, `@bswap`, `@bitreverse` now have a type parameter * rename @bitreverse to @bitReverse * rename @bswap to @byteSwap Closes #2119 Closes #2120

38 files changed, 466 insertions(+), 396 deletions(-)

doc/langref.html.in+13-11
...@@ -6239,8 +6239,8 @@ comptime {...@@ -6239,8 +6239,8 @@ comptime {
62396239
6240 {#header_close#}6240 {#header_close#}
62416241
6242 {#header_open|@bswap#}6242 {#header_open|@byteSwap#}
6243 <pre>{#syntax#}@bswap(comptime T: type, value: T) T{#endsyntax#}</pre>6243 <pre>{#syntax#}@byteSwap(comptime T: type, integer: T) T{#endsyntax#}</pre>
6244 <p>{#syntax#}T{#endsyntax#} must be an integer type with bit count evenly divisible by 8.</p>6244 <p>{#syntax#}T{#endsyntax#} must be an integer type with bit count evenly divisible by 8.</p>
6245 <p>6245 <p>
6246 Swaps the byte order of the integer. This converts a big endian integer to a little endian integer,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,8 +6248,8 @@ comptime {
6248 </p>6248 </p>
6249 {#header_close#}6249 {#header_close#}
62506250
6251 {#header_open|@bitreverse#}6251 {#header_open|@bitReverse#}
6252 <pre>{#syntax#}@bitreverse(comptime T: type, value: T) T{#endsyntax#}</pre>6252 <pre>{#syntax#}@bitReverse(comptime T: type, integer: T) T{#endsyntax#}</pre>
6253 <p>{#syntax#}T{#endsyntax#} accepts any integer type.</p>6253 <p>{#syntax#}T{#endsyntax#} accepts any integer type.</p>
6254 <p>6254 <p>
6255 Reverses the bitpattern of an integer value, including the sign bit if applicable.6255 Reverses the bitpattern of an integer value, including the sign bit if applicable.
...@@ -6337,14 +6337,15 @@ comptime {...@@ -6337,14 +6337,15 @@ comptime {
6337 {#header_close#}6337 {#header_close#}
63386338
6339 {#header_open|@clz#}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 <p>6341 <p>
6342 This function counts the number of leading zeroes in {#syntax#}x{#endsyntax#} which is an integer6342 This function counts the number of leading zeroes in {#syntax#}x{#endsyntax#} which is an integer
6343 type {#syntax#}T{#endsyntax#}.6343 type {#syntax#}T{#endsyntax#}.
6344 </p>6344 </p>
6345 <p>6345 <p>
6346 The return type {#syntax#}U{#endsyntax#} is an unsigned integer with the minimum number6346 If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#endsyntax#}.
6347 of bits that can represent the value {#syntax#}T.bit_count{#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 </p>6349 </p>
6349 <p>6350 <p>
6350 If {#syntax#}x{#endsyntax#} is zero, {#syntax#}@clz{#endsyntax#} returns {#syntax#}T.bit_count{#endsyntax#}.6351 If {#syntax#}x{#endsyntax#} is zero, {#syntax#}@clz{#endsyntax#} returns {#syntax#}T.bit_count{#endsyntax#}.
...@@ -6477,14 +6478,15 @@ test "main" {...@@ -6477,14 +6478,15 @@ test "main" {
6477 {#header_close#}6478 {#header_close#}
64786479
6479 {#header_open|@ctz#}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 <p>6482 <p>
6482 This function counts the number of trailing zeroes in {#syntax#}x{#endsyntax#} which is an integer6483 This function counts the number of trailing zeroes in {#syntax#}x{#endsyntax#} which is an integer
6483 type {#syntax#}T{#endsyntax#}.6484 type {#syntax#}T{#endsyntax#}.
6484 </p>6485 </p>
6485 <p>6486 <p>
6486 The return type {#syntax#}U{#endsyntax#} is an unsigned integer with the minimum number6487 If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#endsyntax#}.
6487 of bits that can represent the value {#syntax#}T.bit_count{#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 </p>6490 </p>
6489 <p>6491 <p>
6490 If {#syntax#}x{#endsyntax#} is zero, {#syntax#}@ctz{#endsyntax#} returns {#syntax#}T.bit_count{#endsyntax#}.6492 If {#syntax#}x{#endsyntax#} is zero, {#syntax#}@ctz{#endsyntax#} returns {#syntax#}T.bit_count{#endsyntax#}.
...@@ -7034,7 +7036,7 @@ test "call foo" {...@@ -7034,7 +7036,7 @@ test "call foo" {
7034 {#header_close#}7036 {#header_close#}
70357037
7036 {#header_open|@popCount#}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 <p>Counts the number of bits set in an integer.</p>7040 <p>Counts the number of bits set in an integer.</p>
7039 <p>7041 <p>
7040 If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#endsyntax#}.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,6 +1407,8 @@ enum BuiltinFnId {
1407 BuiltinFnIdCtz,1407 BuiltinFnIdCtz,
1408 BuiltinFnIdClz,1408 BuiltinFnIdClz,
1409 BuiltinFnIdPopCount,1409 BuiltinFnIdPopCount,
1410 BuiltinFnIdBswap,
1411 BuiltinFnIdBitReverse,
1410 BuiltinFnIdImport,1412 BuiltinFnIdImport,
1411 BuiltinFnIdCImport,1413 BuiltinFnIdCImport,
1412 BuiltinFnIdErrName,1414 BuiltinFnIdErrName,
...@@ -1469,8 +1471,6 @@ enum BuiltinFnId {...@@ -1469,8 +1471,6 @@ enum BuiltinFnId {
1469 BuiltinFnIdErrorReturnTrace,1471 BuiltinFnIdErrorReturnTrace,
1470 BuiltinFnIdAtomicRmw,1472 BuiltinFnIdAtomicRmw,
1471 BuiltinFnIdAtomicLoad,1473 BuiltinFnIdAtomicLoad,
1472 BuiltinFnIdBswap,
1473 BuiltinFnIdBitReverse,
1474};1474};
14751475
1476struct BuiltinFnEntry {1476struct BuiltinFnEntry {
...@@ -2191,6 +2191,8 @@ enum IrInstructionId {...@@ -2191,6 +2191,8 @@ enum IrInstructionId {
2191 IrInstructionIdClz,2191 IrInstructionIdClz,
2192 IrInstructionIdCtz,2192 IrInstructionIdCtz,
2193 IrInstructionIdPopCount,2193 IrInstructionIdPopCount,
2194 IrInstructionIdBswap,
2195 IrInstructionIdBitReverse,
2194 IrInstructionIdImport,2196 IrInstructionIdImport,
2195 IrInstructionIdCImport,2197 IrInstructionIdCImport,
2196 IrInstructionIdCInclude,2198 IrInstructionIdCInclude,
...@@ -2287,8 +2289,6 @@ enum IrInstructionId {...@@ -2287,8 +2289,6 @@ enum IrInstructionId {
2287 IrInstructionIdMergeErrRetTraces,2289 IrInstructionIdMergeErrRetTraces,
2288 IrInstructionIdMarkErrRetTracePtr,2290 IrInstructionIdMarkErrRetTracePtr,
2289 IrInstructionIdSqrt,2291 IrInstructionIdSqrt,
2290 IrInstructionIdBswap,
2291 IrInstructionIdBitReverse,
2292 IrInstructionIdErrSetCast,2292 IrInstructionIdErrSetCast,
2293 IrInstructionIdToBytes,2293 IrInstructionIdToBytes,
2294 IrInstructionIdFromBytes,2294 IrInstructionIdFromBytes,
...@@ -2744,19 +2744,22 @@ struct IrInstructionOptionalUnwrapPtr {...@@ -2744,19 +2744,22 @@ struct IrInstructionOptionalUnwrapPtr {
2744struct IrInstructionCtz {2744struct IrInstructionCtz {
2745 IrInstruction base;2745 IrInstruction base;
27462746
2747 IrInstruction *value;2747 IrInstruction *type;
2748 IrInstruction *op;
2748};2749};
27492750
2750struct IrInstructionClz {2751struct IrInstructionClz {
2751 IrInstruction base;2752 IrInstruction base;
27522753
2753 IrInstruction *value;2754 IrInstruction *type;
2755 IrInstruction *op;
2754};2756};
27552757
2756struct IrInstructionPopCount {2758struct IrInstructionPopCount {
2757 IrInstruction base;2759 IrInstruction base;
27582760
2759 IrInstruction *value;2761 IrInstruction *type;
2762 IrInstruction *op;
2760};2763};
27612764
2762struct IrInstructionUnionTag {2765struct IrInstructionUnionTag {
src/analyze.cpp+23-9
...@@ -213,15 +213,6 @@ static ZigType *new_container_type_entry(CodeGen *g, ZigTypeId id, AstNode *sour...@@ -213,15 +213,6 @@ static ZigType *new_container_type_entry(CodeGen *g, ZigTypeId id, AstNode *sour
213 return entry;213 return entry;
214}214}
215215
216static 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
225AstNode *type_decl_node(ZigType *type_entry) {216AstNode *type_decl_node(ZigType *type_entry) {
226 switch (type_entry->id) {217 switch (type_entry->id) {
227 case ZigTypeIdInvalid:218 case ZigTypeIdInvalid:
...@@ -335,10 +326,33 @@ static bool is_slice(ZigType *type) {...@@ -335,10 +326,33 @@ static bool is_slice(ZigType *type) {
335 return type->id == ZigTypeIdStruct && type->data.structure.is_slice;326 return type->id == ZigTypeIdStruct && type->data.structure.is_slice;
336}327}
337328
329static 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
338static 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
338ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {346ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
339 return get_int_type(g, false, bits_needed_for_unsigned(x));347 return get_int_type(g, false, bits_needed_for_unsigned(x));
340}348}
341349
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
352ZigType *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
342ZigType *get_promise_type(CodeGen *g, ZigType *result_type) {356ZigType *get_promise_type(CodeGen *g, ZigType *result_type) {
343 if (result_type != nullptr && result_type->promise_parent != nullptr) {357 if (result_type != nullptr && result_type->promise_parent != nullptr) {
344 return result_type->promise_parent;358 return result_type->promise_parent;
src/analyze.hpp+1
...@@ -34,6 +34,7 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type);...@@ -34,6 +34,7 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type);
34ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind,34ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind,
35 AstNode *decl_node, const char *full_name, Buf *bare_name, ContainerLayout layout);35 AstNode *decl_node, const char *full_name, Buf *bare_name, ContainerLayout layout);
36ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);36ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);
37ZigType *get_smallest_popcount_unsigned_int_type(CodeGen *g, uint64_t x);
37ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payload_type);38ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payload_type);
38ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry);39ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry);
39ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name);40ZigType *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,11 +4126,19 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI
41264126
4127 char llvm_name[64];4127 char llvm_name[64];
4128 sprintf(llvm_name, "llvm.%s.i%" PRIu32, fn_name, int_type->data.integral.bit_count);4128 sprintf(llvm_name, "llvm.%s.i%" PRIu32, fn_name, int_type->data.integral.bit_count);
4129 LLVMTypeRef param_types[] = {4129 LLVMTypeRef param_types[3];
4130 get_llvm_type(g, int_type),4130 switch (n_args) {
4131 LLVMInt1Type(),4131 case 1:
4132 };4132 param_types[0] = get_llvm_type(g, int_type);
4133 LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, int_type), param_types, n_args, false);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 LLVMValueRef fn_val = LLVMAddFunction(g->module, llvm_name, fn_type);4142 LLVMValueRef fn_val = LLVMAddFunction(g->module, llvm_name, fn_type);
4135 assert(LLVMGetIntrinsicID(fn_val));4143 assert(LLVMGetIntrinsicID(fn_val));
41364144
...@@ -4140,9 +4148,9 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI...@@ -4140,9 +4148,9 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI
4140}4148}
41414149
4142static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstructionClz *instruction) {4150static 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 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdClz);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 LLVMValueRef params[] {4154 LLVMValueRef params[] {
4147 operand,4155 operand,
4148 LLVMConstNull(LLVMInt1Type()),4156 LLVMConstNull(LLVMInt1Type()),
...@@ -4152,9 +4160,9 @@ static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstru...@@ -4152,9 +4160,9 @@ static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstru
4152}4160}
41534161
4154static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstructionCtz *instruction) {4162static 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 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdCtz);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 LLVMValueRef params[] {4166 LLVMValueRef params[] {
4159 operand,4167 operand,
4160 LLVMConstNull(LLVMInt1Type()),4168 LLVMConstNull(LLVMInt1Type()),
...@@ -4164,9 +4172,9 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstru...@@ -4164,9 +4172,9 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstru
4164}4172}
41654173
4166static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutable *executable, IrInstructionPopCount *instruction) {4174static 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 LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount);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 LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, &operand, 1, "");4178 LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, &operand, 1, "");
4171 return gen_widen_or_shorten(g, false, int_type, instruction->base.value.type, wrong_size_int);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,6 +5658,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5650 return ir_render_pop_count(g, executable, (IrInstructionPopCount *)instruction);5658 return ir_render_pop_count(g, executable, (IrInstructionPopCount *)instruction);
5651 case IrInstructionIdSwitchBr:5659 case IrInstructionIdSwitchBr:
5652 return ir_render_switch_br(g, executable, (IrInstructionSwitchBr *)instruction);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 case IrInstructionIdPhi:5665 case IrInstructionIdPhi:
5654 return ir_render_phi(g, executable, (IrInstructionPhi *)instruction);5666 return ir_render_phi(g, executable, (IrInstructionPhi *)instruction);
5655 case IrInstructionIdRef:5667 case IrInstructionIdRef:
...@@ -5766,10 +5778,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5766,10 +5778,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5766 return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction);5778 return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction);
5767 case IrInstructionIdSqrt:5779 case IrInstructionIdSqrt:
5768 return ir_render_sqrt(g, executable, (IrInstructionSqrt *)instruction);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 case IrInstructionIdArrayToVector:5781 case IrInstructionIdArrayToVector:
5774 return ir_render_array_to_vector(g, executable, (IrInstructionArrayToVector *)instruction);5782 return ir_render_array_to_vector(g, executable, (IrInstructionArrayToVector *)instruction);
5775 case IrInstructionIdVectorToArray:5783 case IrInstructionIdVectorToArray:
...@@ -7332,9 +7340,11 @@ static void define_builtin_fns(CodeGen *g) {...@@ -7332,9 +7340,11 @@ static void define_builtin_fns(CodeGen *g) {
7332 create_builtin_fn(g, BuiltinFnIdCInclude, "cInclude", 1);7340 create_builtin_fn(g, BuiltinFnIdCInclude, "cInclude", 1);
7333 create_builtin_fn(g, BuiltinFnIdCDefine, "cDefine", 2);7341 create_builtin_fn(g, BuiltinFnIdCDefine, "cDefine", 2);
7334 create_builtin_fn(g, BuiltinFnIdCUndef, "cUndef", 1);7342 create_builtin_fn(g, BuiltinFnIdCUndef, "cUndef", 1);
7335 create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 1);7343 create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 2);
7336 create_builtin_fn(g, BuiltinFnIdClz, "clz", 1);7344 create_builtin_fn(g, BuiltinFnIdClz, "clz", 2);
7337 create_builtin_fn(g, BuiltinFnIdPopCount, "popCount", 1);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 create_builtin_fn(g, BuiltinFnIdImport, "import", 1);7348 create_builtin_fn(g, BuiltinFnIdImport, "import", 1);
7339 create_builtin_fn(g, BuiltinFnIdCImport, "cImport", 1);7349 create_builtin_fn(g, BuiltinFnIdCImport, "cImport", 1);
7340 create_builtin_fn(g, BuiltinFnIdErrName, "errorName", 1);7350 create_builtin_fn(g, BuiltinFnIdErrName, "errorName", 1);
...@@ -7395,8 +7405,6 @@ static void define_builtin_fns(CodeGen *g) {...@@ -7395,8 +7405,6 @@ static void define_builtin_fns(CodeGen *g) {
7395 create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);7405 create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);
7396 create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);7406 create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);
7397 create_builtin_fn(g, BuiltinFnIdThis, "This", 0);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}
74017409
7402static const char *bool_to_str(bool b) {7410static const char *bool_to_str(bool b) {
src/ir.cpp+172-159
...@@ -575,6 +575,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) {...@@ -575,6 +575,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) {
575 return IrInstructionIdPopCount;575 return IrInstructionIdPopCount;
576}576}
577577
578static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) {
579 return IrInstructionIdBswap;
580}
581
582static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) {
583 return IrInstructionIdBitReverse;
584}
585
578static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) {586static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) {
579 return IrInstructionIdUnionTag;587 return IrInstructionIdUnionTag;
580}588}
...@@ -983,14 +991,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) {...@@ -983,14 +991,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) {
983 return IrInstructionIdSqrt;991 return IrInstructionIdSqrt;
984}992}
985993
986static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) {
987 return IrInstructionIdBswap;
988}
989
990static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) {
991 return IrInstructionIdBitReverse;
992}
993
994static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) {994static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) {
995 return IrInstructionIdCheckRuntimeScope;995 return IrInstructionIdCheckRuntimeScope;
996}996}
...@@ -1768,29 +1768,57 @@ static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNo...@@ -1768,29 +1768,57 @@ static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNo
1768 return &instruction->base;1768 return &instruction->base;
1769}1769}
17701770
1771static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {1771static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) {
1772 IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, scope, source_node);1772 IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, scope, source_node);
1773 instruction->value = value;1773 instruction->type = type;
1774 instruction->op = op;
17741775
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);
17761778
1777 return &instruction->base;1779 return &instruction->base;
1778}1780}
17791781
1780static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {1782static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) {
1781 IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, scope, source_node);1783 IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, scope, source_node);
1782 instruction->value = value;1784 instruction->type = type;
1785 instruction->op = op;
17831786
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);
17851789
1786 return &instruction->base;1790 return &instruction->base;
1787}1791}
17881792
1789static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {1793static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) {
1790 IrInstructionPopCount *instruction = ir_build_instruction<IrInstructionPopCount>(irb, scope, source_node);1794 IrInstructionPopCount *instruction = ir_build_instruction<IrInstructionPopCount>(irb, scope, source_node);
1791 instruction->value = value;1795 instruction->type = type;
1796 instruction->op = op;
17921797
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
1804static 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
1815static 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);
17941822
1795 return &instruction->base;1823 return &instruction->base;
1796}1824}
...@@ -2986,28 +3014,6 @@ static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *sourc...@@ -2986,28 +3014,6 @@ static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *sourc
2986 return &instruction->base;3014 return &instruction->base;
2987}3015}
29883016
2989static 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
3000static 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
3011static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) {3017static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) {
3012 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node);3018 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node);
3013 instruction->scope_is_comptime = scope_is_comptime;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,36 +4088,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4082 IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value);4088 IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value);
4083 return ir_lval_wrap(irb, scope, size_of, lval);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 case BuiltinFnIdImport:4091 case BuiltinFnIdImport:
4116 {4092 {
4117 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);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,21 +5060,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5084 IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value);5060 IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value);
5085 return ir_lval_wrap(irb, scope, result, lval);5061 return ir_lval_wrap(irb, scope, result, lval);
5086 }5062 }
5063 case BuiltinFnIdCtz:
5064 case BuiltinFnIdPopCount:
5065 case BuiltinFnIdClz:
5087 case BuiltinFnIdBswap: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 case BuiltinFnIdBitReverse:5067 case BuiltinFnIdBitReverse:
5103 {5068 {
5104 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);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,7 +5076,26 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
5111 if (arg1_value == irb->codegen->invalid_instruction)5076 if (arg1_value == irb->codegen->invalid_instruction)
5112 return arg1_value;5077 return arg1_value;
51135078
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 return ir_lval_wrap(irb, scope, result, lval);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,92 +17024,125 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira,
17040 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on);17024 return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on);
17041}17025}
1704217026
17043static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *ctz_instruction) {17027static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) {
17044 IrInstruction *value = ctz_instruction->value->child;17028 ZigType *int_type = ir_resolve_type(ira, instruction->type->child);
17045 if (type_is_invalid(value->value.type)) {17029 if (type_is_invalid(int_type))
17046 return ira->codegen->invalid_instruction;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 }
1705717031
17058 IrInstruction *result = ir_build_ctz(&ira->new_irb,17032 IrInstruction *op = instruction->op->child;
17059 ctz_instruction->base.scope, ctz_instruction->base.source_node, value);17033
17060 result->value.type = return_type;17034 if (int_type->id != ZigTypeIdInt) {
17061 return result;17035 ir_add_error(ira, instruction->type,
17062 } else {17036 buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name)));
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)));
17065 return ira->codegen->invalid_instruction;17037 return ira->codegen->invalid_instruction;
17066 }17038 }
17067}
1706817039
17069static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *clz_instruction) {17040 IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type);
17070 IrInstruction *value = clz_instruction->value->child;17041 if (type_is_invalid(casted_op->value.type))
17071 if (type_is_invalid(value->value.type)) {
17072 return ira->codegen->invalid_instruction;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 }
1708317043
17084 IrInstruction *result = ir_build_clz(&ira->new_irb,17044 ZigType *return_type = get_smallest_popcount_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count);
17085 clz_instruction->base.scope, clz_instruction->base.source_node, value);17045
17086 result->value.type = return_type;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 return result;17049 return result;
17088 } else {17050 }
17089 ir_add_error_node(ira, clz_instruction->base.source_node,17051
17090 buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name)));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
17066static 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 return ira->codegen->invalid_instruction;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}
1709417104
17095static IrInstruction *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) {17105static IrInstruction *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) {
17096 IrInstruction *value = instruction->value->child;17106 ZigType *int_type = ir_resolve_type(ira, instruction->type->child);
17097 if (type_is_invalid(value->value.type))17107 if (type_is_invalid(int_type))
17098 return ira->codegen->invalid_instruction;17108 return ira->codegen->invalid_instruction;
1709917109
17100 if (value->value.type->id != ZigTypeIdInt && value->value.type->id != ZigTypeIdComptimeInt) {17110 IrInstruction *op = instruction->op->child;
17101 ir_add_error(ira, value,17111
17102 buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name)));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 return ira->codegen->invalid_instruction;17115 return ira->codegen->invalid_instruction;
17104 }17116 }
1710517117
17106 if (instr_is_comptime(value)) {17118 IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type);
17107 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);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 if (!val)17132 if (!val)
17109 return ira->codegen->invalid_instruction;17133 return ira->codegen->invalid_instruction;
17134
17110 if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) {17135 if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) {
17111 size_t result = bigint_popcount_unsigned(&val->data.x_bigint);17136 size_t result = bigint_popcount_unsigned(&val->data.x_bigint);
17112 return ir_const_unsigned(ira, &instruction->base, result);17137 return ir_const_unsigned(ira, &instruction->base, result);
17113 }17138 }
17114 if (value->value.type->id == ZigTypeIdComptimeInt) {17139 size_t result = bigint_popcount_signed(&val->data.x_bigint, op->value.type->data.integral.bit_count);
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);
17123 return ir_const_unsigned(ira, &instruction->base, result);17140 return ir_const_unsigned(ira, &instruction->base, result);
17124 }17141 }
1712517142
17126 IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope,17143 IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope,
17127 instruction->base.source_node, value);17144 instruction->base.source_node, nullptr, casted_op);
17128 result->value.type = get_smallest_unsigned_int_type(ira->codegen, value->value.type->data.integral.bit_count);17145 result->value.type = return_type;
17129 return result;17146 return result;
17130}17147}
1713117148
...@@ -22990,8 +23007,6 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction...@@ -22990,8 +23007,6 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction
22990 return ira->codegen->invalid_instruction;23007 return ira->codegen->invalid_instruction;
2299123008
22992 IrInstruction *op = instruction->op->child;23009 IrInstruction *op = instruction->op->child;
22993 if (type_is_invalid(op->value.type))
22994 return ira->codegen->invalid_instruction;
2299523010
22996 if (int_type->id != ZigTypeIdInt) {23011 if (int_type->id != ZigTypeIdInt) {
22997 ir_add_error(ira, instruction->type,23012 ir_add_error(ira, instruction->type,
...@@ -22999,17 +23014,17 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction...@@ -22999,17 +23014,17 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction
22999 return ira->codegen->invalid_instruction;23014 return ira->codegen->invalid_instruction;
23000 }23015 }
2300123016
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 if (int_type->data.integral.bit_count % 8 != 0) {23021 if (int_type->data.integral.bit_count % 8 != 0) {
23003 ir_add_error(ira, instruction->type,23022 ir_add_error(ira, instruction->op,
23004 buf_sprintf("@bswap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8",23023 buf_sprintf("@byteSwap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8",
23005 buf_ptr(&int_type->name), int_type->data.integral.bit_count));23024 buf_ptr(&int_type->name), int_type->data.integral.bit_count));
23006 return ira->codegen->invalid_instruction;23025 return ira->codegen->invalid_instruction;
23007 }23026 }
2300823027
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 if (int_type->data.integral.bit_count == 0) {23028 if (int_type->data.integral.bit_count == 0) {
23014 IrInstruction *result = ir_const(ira, &instruction->base, int_type);23029 IrInstruction *result = ir_const(ira, &instruction->base, int_type);
23015 bigint_init_unsigned(&result->value.data.x_bigint, 0);23030 bigint_init_unsigned(&result->value.data.x_bigint, 0);
...@@ -23017,7 +23032,7 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction...@@ -23017,7 +23032,7 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction
23017 }23032 }
2301823033
23019 if (int_type->data.integral.bit_count == 8) {23034 if (int_type->data.integral.bit_count == 8) {
23020 return casted_op;23035 return op;
23021 }23036 }
2302223037
23023 if (instr_is_comptime(casted_op)) {23038 if (instr_is_comptime(casted_op)) {
...@@ -23046,8 +23061,6 @@ static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstr...@@ -23046,8 +23061,6 @@ static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstr
23046 return ira->codegen->invalid_instruction;23061 return ira->codegen->invalid_instruction;
2304723062
23048 IrInstruction *op = instruction->op->child;23063 IrInstruction *op = instruction->op->child;
23049 if (type_is_invalid(op->value.type))
23050 return ira->codegen->invalid_instruction;
2305123064
23052 if (int_type->id != ZigTypeIdInt) {23065 if (int_type->id != ZigTypeIdInt) {
23053 ir_add_error(ira, instruction->type,23066 ir_add_error(ira, instruction->type,
...@@ -23251,6 +23264,10 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -23251,6 +23264,10 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
23251 return ir_analyze_instruction_ctz(ira, (IrInstructionCtz *)instruction);23264 return ir_analyze_instruction_ctz(ira, (IrInstructionCtz *)instruction);
23252 case IrInstructionIdPopCount:23265 case IrInstructionIdPopCount:
23253 return ir_analyze_instruction_pop_count(ira, (IrInstructionPopCount *)instruction);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 case IrInstructionIdSwitchBr:23271 case IrInstructionIdSwitchBr:
23255 return ir_analyze_instruction_switch_br(ira, (IrInstructionSwitchBr *)instruction);23272 return ir_analyze_instruction_switch_br(ira, (IrInstructionSwitchBr *)instruction);
23256 case IrInstructionIdSwitchTarget:23273 case IrInstructionIdSwitchTarget:
...@@ -23443,10 +23460,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -23443,10 +23460,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
23443 return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction);23460 return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction);
23444 case IrInstructionIdSqrt:23461 case IrInstructionIdSqrt:
23445 return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction);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 case IrInstructionIdIntToErr:23463 case IrInstructionIdIntToErr:
23451 return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction);23464 return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction);
23452 case IrInstructionIdErrToInt:23465 case IrInstructionIdErrToInt:
...@@ -23621,6 +23634,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -23621,6 +23634,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
23621 case IrInstructionIdClz:23634 case IrInstructionIdClz:
23622 case IrInstructionIdCtz:23635 case IrInstructionIdCtz:
23623 case IrInstructionIdPopCount:23636 case IrInstructionIdPopCount:
23637 case IrInstructionIdBswap:
23638 case IrInstructionIdBitReverse:
23624 case IrInstructionIdSwitchVar:23639 case IrInstructionIdSwitchVar:
23625 case IrInstructionIdSwitchElseVar:23640 case IrInstructionIdSwitchElseVar:
23626 case IrInstructionIdSwitchTarget:23641 case IrInstructionIdSwitchTarget:
...@@ -23679,8 +23694,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -23679,8 +23694,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
23679 case IrInstructionIdCoroPromise:23694 case IrInstructionIdCoroPromise:
23680 case IrInstructionIdPromiseResultType:23695 case IrInstructionIdPromiseResultType:
23681 case IrInstructionIdSqrt:23696 case IrInstructionIdSqrt:
23682 case IrInstructionIdBswap:
23683 case IrInstructionIdBitReverse:
23684 case IrInstructionIdAtomicLoad:23697 case IrInstructionIdAtomicLoad:
23685 case IrInstructionIdIntCast:23698 case IrInstructionIdIntCast:
23686 case IrInstructionIdFloatCast:23699 case IrInstructionIdFloatCast:
src/ir_print.cpp+54-36
...@@ -504,19 +504,61 @@ static void ir_print_optional_unwrap_ptr(IrPrint *irp, IrInstructionOptionalUnwr...@@ -504,19 +504,61 @@ static void ir_print_optional_unwrap_ptr(IrPrint *irp, IrInstructionOptionalUnwr
504504
505static void ir_print_clz(IrPrint *irp, IrInstructionClz *instruction) {505static void ir_print_clz(IrPrint *irp, IrInstructionClz *instruction) {
506 fprintf(irp->f, "@clz(");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 fprintf(irp->f, ")");514 fprintf(irp->f, ")");
509}515}
510516
511static void ir_print_ctz(IrPrint *irp, IrInstructionCtz *instruction) {517static void ir_print_ctz(IrPrint *irp, IrInstructionCtz *instruction) {
512 fprintf(irp->f, "@ctz(");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 fprintf(irp->f, ")");526 fprintf(irp->f, ")");
515}527}
516528
517static void ir_print_pop_count(IrPrint *irp, IrInstructionPopCount *instruction) {529static void ir_print_pop_count(IrPrint *irp, IrInstructionPopCount *instruction) {
518 fprintf(irp->f, "@popCount(");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
541static 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
553static 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 fprintf(irp->f, ")");562 fprintf(irp->f, ")");
521}563}
522564
...@@ -1411,30 +1453,6 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va...@@ -1411,30 +1453,6 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va
1411 }1453 }
1412}1454}
14131455
1414static 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
1426static 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
1438static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {1456static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1439 ir_print_prefix(irp, instruction);1457 ir_print_prefix(irp, instruction);
1440 switch (instruction->id) {1458 switch (instruction->id) {
...@@ -1551,15 +1569,21 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1551,15 +1569,21 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1551 case IrInstructionIdOptionalUnwrapPtr:1569 case IrInstructionIdOptionalUnwrapPtr:
1552 ir_print_optional_unwrap_ptr(irp, (IrInstructionOptionalUnwrapPtr *)instruction);1570 ir_print_optional_unwrap_ptr(irp, (IrInstructionOptionalUnwrapPtr *)instruction);
1553 break;1571 break;
1554 case IrInstructionIdCtz:
1555 ir_print_ctz(irp, (IrInstructionCtz *)instruction);
1556 break;
1557 case IrInstructionIdPopCount:1572 case IrInstructionIdPopCount:
1558 ir_print_pop_count(irp, (IrInstructionPopCount *)instruction);1573 ir_print_pop_count(irp, (IrInstructionPopCount *)instruction);
1559 break;1574 break;
1560 case IrInstructionIdClz:1575 case IrInstructionIdClz:
1561 ir_print_clz(irp, (IrInstructionClz *)instruction);1576 ir_print_clz(irp, (IrInstructionClz *)instruction);
1562 break;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 case IrInstructionIdSwitchBr:1587 case IrInstructionIdSwitchBr:
1564 ir_print_switch_br(irp, (IrInstructionSwitchBr *)instruction);1588 ir_print_switch_br(irp, (IrInstructionSwitchBr *)instruction);
1565 break;1589 break;
...@@ -1869,12 +1893,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1869,12 +1893,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1869 case IrInstructionIdSqrt:1893 case IrInstructionIdSqrt:
1870 ir_print_sqrt(irp, (IrInstructionSqrt *)instruction);1894 ir_print_sqrt(irp, (IrInstructionSqrt *)instruction);
1871 break;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 case IrInstructionIdAtomicLoad:1896 case IrInstructionIdAtomicLoad:
1879 ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction);1897 ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction);
1880 break;1898 break;
std/heap.zig+1-1
...@@ -894,7 +894,7 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo...@@ -894,7 +894,7 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo
894 const large_align = u29(os.page_size << 2);894 const large_align = u29(os.page_size << 2);
895895
896 var align_mask: usize = undefined;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);
898898
899 var slice = try allocator.alignedAlloc(u8, large_align, 500);899 var slice = try allocator.alignedAlloc(u8, large_align, 500);
900 testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));900 testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
std/math.zig+1-1
...@@ -698,7 +698,7 @@ test "math.floorPowerOfTwo" {...@@ -698,7 +698,7 @@ test "math.floorPowerOfTwo" {
698698
699pub fn log2_int(comptime T: type, x: T) Log2Int(T) {699pub fn log2_int(comptime T: type, x: T) Log2Int(T) {
700 assert(x != 0);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}
703703
704pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) {704pub 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,7 +207,7 @@ pub const Int = struct {
207207
208 /// Returns the number of bits required to represent the absolute value an Int.208 /// Returns the number of bits required to represent the absolute value an Int.
209 fn bitCountAbs(self: Int) usize {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 }
212212
213 /// Returns the number of bits required to represent the integer in twos-complement form.213 /// Returns the number of bits required to represent the integer in twos-complement form.
...@@ -226,9 +226,9 @@ pub const Int = struct {...@@ -226,9 +226,9 @@ pub const Int = struct {
226 if (!self.isPositive()) block: {226 if (!self.isPositive()) block: {
227 bits += 1;227 bits += 1;
228228
229 if (@popCount(self.limbs[self.len() - 1]) == 1) {229 if (@popCount(Limb, self.limbs[self.len() - 1]) == 1) {
230 for (self.limbs[0 .. self.len() - 1]) |limb| {230 for (self.limbs[0 .. self.len() - 1]) |limb| {
231 if (@popCount(limb) != 0) {231 if (@popCount(Limb, limb) != 0) {
232 break :block;232 break :block;
233 }233 }
234 }234 }
...@@ -962,7 +962,7 @@ pub const Int = struct {...@@ -962,7 +962,7 @@ pub const Int = struct {
962 defer tmp.deinit();962 defer tmp.deinit();
963963
964 // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) and even964 // 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 if (norm_shift == 0 and y.isOdd()) {966 if (norm_shift == 0 and y.isOdd()) {
967 norm_shift = Limb.bit_count;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,7 +513,7 @@ pub fn readIntNative(comptime T: type, bytes: *const [@divExact(T.bit_count, 8)]
513/// This function cannot fail and cannot cause undefined behavior.513/// This function cannot fail and cannot cause undefined behavior.
514/// Assumes the endianness of memory is foreign, so it must byte-swap.514/// Assumes the endianness of memory is foreign, so it must byte-swap.
515pub fn readIntForeign(comptime T: type, bytes: *const [@divExact(T.bit_count, 8)]u8) T {515pub 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}
518518
519pub const readIntLittle = switch (builtin.endian) {519pub const readIntLittle = switch (builtin.endian) {
...@@ -543,7 +543,7 @@ pub fn readIntSliceNative(comptime T: type, bytes: []const u8) T {...@@ -543,7 +543,7 @@ pub fn readIntSliceNative(comptime T: type, bytes: []const u8) T {
543/// The bit count of T must be evenly divisible by 8.543/// The bit count of T must be evenly divisible by 8.
544/// Assumes the endianness of memory is foreign, so it must byte-swap.544/// Assumes the endianness of memory is foreign, so it must byte-swap.
545pub fn readIntSliceForeign(comptime T: type, bytes: []const u8) T {545pub 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}
548548
549pub const readIntSliceLittle = switch (builtin.endian) {549pub const readIntSliceLittle = switch (builtin.endian) {
...@@ -624,9 +624,9 @@ pub fn writeIntNative(comptime T: type, buf: *[(T.bit_count + 7) / 8]u8, value:...@@ -624,9 +624,9 @@ pub fn writeIntNative(comptime T: type, buf: *[(T.bit_count + 7) / 8]u8, value:
624/// Writes an integer to memory, storing it in twos-complement.624/// Writes an integer to memory, storing it in twos-complement.
625/// This function always succeeds, has defined behavior for all inputs, but625/// This function always succeeds, has defined behavior for all inputs, but
626/// the integer bit width must be divisible by 8.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.
628pub fn writeIntForeign(comptime T: type, buf: *[@divExact(T.bit_count, 8)]u8, value: T) void {628pub 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}
631631
632pub const writeIntLittle = switch (builtin.endian) {632pub const writeIntLittle = switch (builtin.endian) {
...@@ -1229,14 +1229,14 @@ test "std.mem.rotate" {...@@ -1229,14 +1229,14 @@ test "std.mem.rotate" {
1229pub fn littleToNative(comptime T: type, x: T) T {1229pub fn littleToNative(comptime T: type, x: T) T {
1230 return switch (builtin.endian) {1230 return switch (builtin.endian) {
1231 builtin.Endian.Little => x,1231 builtin.Endian.Little => x,
1232 builtin.Endian.Big => @bswap(T, x),1232 builtin.Endian.Big => @byteSwap(T, x),
1233 };1233 };
1234}1234}
12351235
1236/// Converts a big-endian integer to host endianness.1236/// Converts a big-endian integer to host endianness.
1237pub fn bigToNative(comptime T: type, x: T) T {1237pub fn bigToNative(comptime T: type, x: T) T {
1238 return switch (builtin.endian) {1238 return switch (builtin.endian) {
1239 builtin.Endian.Little => @bswap(T, x),1239 builtin.Endian.Little => @byteSwap(T, x),
1240 builtin.Endian.Big => x,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,14 +1261,14 @@ pub fn nativeTo(comptime T: type, x: T, desired_endianness: builtin.Endian) T {
1261pub fn nativeToLittle(comptime T: type, x: T) T {1261pub fn nativeToLittle(comptime T: type, x: T) T {
1262 return switch (builtin.endian) {1262 return switch (builtin.endian) {
1263 builtin.Endian.Little => x,1263 builtin.Endian.Little => x,
1264 builtin.Endian.Big => @bswap(T, x),1264 builtin.Endian.Big => @byteSwap(T, x),
1265 };1265 };
1266}1266}
12671267
1268/// Converts an integer which has host endianness to big endian.1268/// Converts an integer which has host endianness to big endian.
1269pub fn nativeToBig(comptime T: type, x: T) T {1269pub fn nativeToBig(comptime T: type, x: T) T {
1270 return switch (builtin.endian) {1270 return switch (builtin.endian) {
1271 builtin.Endian.Little => @bswap(T, x),1271 builtin.Endian.Little => @byteSwap(T, x),
1272 builtin.Endian.Big => x,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,7 +3377,7 @@ pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize {
3377 const result = set[0 .. rc / @sizeOf(usize)];3377 const result = set[0 .. rc / @sizeOf(usize)];
3378 var sum: usize = 0;3378 var sum: usize = 0;
3379 for (result) |x| {3379 for (result) |x| {
3380 sum += @popCount(x);3380 sum += @popCount(usize, x);
3381 }3381 }
3382 return sum;3382 return sum;
3383 } else {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,7 +66,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type {
66 const value_ptr = @ptrCast(*align(1) const Container, &bytes[start_byte]);66 const value_ptr = @ptrCast(*align(1) const Container, &bytes[start_byte]);
67 var value = value_ptr.*;67 var value = value_ptr.*;
6868
69 if (endian != builtin.endian) value = @bswap(Container, value);69 if (endian != builtin.endian) value = @byteSwap(Container, value);
7070
71 switch (endian) {71 switch (endian) {
72 .Big => {72 .Big => {
...@@ -114,7 +114,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type {...@@ -114,7 +114,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type {
114 const target_ptr = @ptrCast(*align(1) Container, &bytes[start_byte]);114 const target_ptr = @ptrCast(*align(1) Container, &bytes[start_byte]);
115 var target = target_ptr.*;115 var target = target_ptr.*;
116116
117 if (endian != builtin.endian) target = @bswap(Container, target);117 if (endian != builtin.endian) target = @byteSwap(Container, target);
118118
119 //zero the bits we want to replace in the existing bytes119 //zero the bits we want to replace in the existing bytes
120 const inv_mask = @intCast(Container, std.math.maxInt(UnInt)) << keep_shift;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,7 +124,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type {
124 //merge the new value124 //merge the new value
125 target |= value;125 target |= value;
126126
127 if (endian != builtin.endian) target = @bswap(Container, target);127 if (endian != builtin.endian) target = @byteSwap(Container, target);
128128
129 //save it back129 //save it back
130 target_ptr.* = target;130 target_ptr.* = target;
std/special/compiler_rt.zig+1-2
...@@ -19,7 +19,6 @@ comptime {...@@ -19,7 +19,6 @@ comptime {
19 @export("__getf2", @import("compiler_rt/comparetf2.zig").__getf2, linkage);19 @export("__getf2", @import("compiler_rt/comparetf2.zig").__getf2, linkage);
2020
21 if (!is_test) {21 if (!is_test) {
22 // only create these aliases when not testing
23 @export("__cmpsf2", @import("compiler_rt/comparesf2.zig").__lesf2, linkage);22 @export("__cmpsf2", @import("compiler_rt/comparesf2.zig").__lesf2, linkage);
24 @export("__cmpdf2", @import("compiler_rt/comparedf2.zig").__ledf2, linkage);23 @export("__cmpdf2", @import("compiler_rt/comparedf2.zig").__ledf2, linkage);
25 @export("__cmptf2", @import("compiler_rt/comparetf2.zig").__letf2, linkage);24 @export("__cmptf2", @import("compiler_rt/comparetf2.zig").__letf2, linkage);
...@@ -599,7 +598,7 @@ extern fn __udivsi3(n: u32, d: u32) u32 {...@@ -599,7 +598,7 @@ extern fn __udivsi3(n: u32, d: u32) u32 {
599 // special cases598 // special cases
600 if (d == 0) return 0; // ?!599 if (d == 0) return 0; // ?!
601 if (n == 0) return 0;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 // 0 <= sr <= n_uword_bits - 1 or sr large602 // 0 <= sr <= n_uword_bits - 1 or sr large
604 if (sr > n_uword_bits - 1) {603 if (sr > n_uword_bits - 1) {
605 // d > r604 // d > r
std/special/compiler_rt/addXf3.zig+4-4
...@@ -36,11 +36,11 @@ pub extern fn __subtf3(a: f128, b: f128) f128 {...@@ -36,11 +36,11 @@ pub extern fn __subtf3(a: f128, b: f128) f128 {
36// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/215436// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
37fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {37fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
38 const Z = @IntType(false, T.bit_count);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 const significandBits = std.math.floatMantissaBits(T);40 const significandBits = std.math.floatMantissaBits(T);
41 const implicitBit = Z(1) << significandBits;41 const implicitBit = Z(1) << significandBits;
4242
43 const shift = @clz(significand.*) - @clz(implicitBit);43 const shift = @clz(@IntType(false, T.bit_count), significand.*) - @clz(Z, implicitBit);
44 significand.* <<= @intCast(S, shift);44 significand.* <<= @intCast(S, shift);
45 return 1 - shift;45 return 1 - shift;
46}46}
...@@ -48,7 +48,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {...@@ -48,7 +48,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
48// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/215448// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
49fn addXf3(comptime T: type, a: T, b: T) T {49fn addXf3(comptime T: type, a: T, b: T) T {
50 const Z = @IntType(false, T.bit_count);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));
5252
53 const typeWidth = T.bit_count;53 const typeWidth = T.bit_count;
54 const significandBits = std.math.floatMantissaBits(T);54 const significandBits = std.math.floatMantissaBits(T);
...@@ -162,7 +162,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {...@@ -162,7 +162,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {
162 // If partial cancellation occured, we need to left-shift the result162 // If partial cancellation occured, we need to left-shift the result
163 // and adjust the exponent:163 // and adjust the exponent:
164 if (aSignificand < implicitBit << 3) {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 aSignificand <<= @intCast(S, shift);166 aSignificand <<= @intCast(S, shift);
167 aExponent -= shift;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,7 +318,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
318 const significandBits = std.math.floatMantissaBits(T);318 const significandBits = std.math.floatMantissaBits(T);
319 const implicitBit = Z(1) << significandBits;319 const implicitBit = Z(1) << significandBits;
320320
321 const shift = @clz(significand.*) - @clz(implicitBit);321 const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
322 significand.* <<= @intCast(std.math.Log2Int(Z), shift);322 significand.* <<= @intCast(std.math.Log2Int(Z), shift);
323 return 1 - shift;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,7 +191,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
191 const significandBits = std.math.floatMantissaBits(T);191 const significandBits = std.math.floatMantissaBits(T);
192 const implicitBit = Z(1) << significandBits;192 const implicitBit = Z(1) << significandBits;
193193
194 const shift = @clz(significand.*) - @clz(implicitBit);194 const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
195 significand.* <<= @intCast(std.math.Log2Int(Z), shift);195 significand.* <<= @intCast(std.math.Log2Int(Z), shift);
196 return 1 - shift;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,7 +75,8 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t
75 // a is denormal.75 // a is denormal.
76 // renormalize the significand and clear the leading bit, then insert76 // renormalize the significand and clear the leading bit, then insert
77 // the correct adjusted exponent in the destination type.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 absResult = dst_rep_t(aAbs) << @intCast(DstShift, dstSigBits - srcSigBits + scale);80 absResult = dst_rep_t(aAbs) << @intCast(DstShift, dstSigBits - srcSigBits + scale);
80 absResult ^= dstMinNormal;81 absResult ^= dstMinNormal;
81 const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1;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,7 +6,7 @@ fn floatsiXf(comptime T: type, a: i32) T {
6 @setRuntimeSafety(builtin.is_test);6 @setRuntimeSafety(builtin.is_test);
77
8 const Z = @IntType(false, T.bit_count);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));
1010
11 if (a == 0) {11 if (a == 0) {
12 return T(0.0);12 return T(0.0);
...@@ -23,7 +23,7 @@ fn floatsiXf(comptime T: type, a: i32) T {...@@ -23,7 +23,7 @@ fn floatsiXf(comptime T: type, a: i32) T {
23 // Take absolute value of a via abs(x) = (x^(x >> 31)) - (x >> 31).23 // Take absolute value of a via abs(x) = (x^(x >> 31)) - (x >> 31).
24 const abs_a = (a ^ sign) -% sign;24 const abs_a = (a ^ sign) -% sign;
25 // The exponent is the width of abs(a)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));
2727
28 const sign_bit = if (sign < 0) signBit else 0;28 const sign_bit = if (sign < 0) signBit else 0;
2929
std/special/compiler_rt/floattidf.zig+1-1
...@@ -17,7 +17,7 @@ pub extern fn __floattidf(arg: i128) f64 {...@@ -17,7 +17,7 @@ pub extern fn __floattidf(arg: i128) f64 {
17 ai = ((ai ^ si) -% si);17 ai = ((ai ^ si) -% si);
18 var a = @bitCast(u128, ai);18 var a = @bitCast(u128, ai);
1919
20 const sd = @bitCast(i32, N - @clz(a)); // number of significant digits20 const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits
21 var e: i32 = sd - 1; // exponent21 var e: i32 = sd - 1; // exponent
22 if (sd > DBL_MANT_DIG) {22 if (sd > DBL_MANT_DIG) {
23 // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx23 // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
std/special/compiler_rt/floattisf.zig+1-1
...@@ -17,7 +17,7 @@ pub extern fn __floattisf(arg: i128) f32 {...@@ -17,7 +17,7 @@ pub extern fn __floattisf(arg: i128) f32 {
17 ai = ((ai ^ si) -% si);17 ai = ((ai ^ si) -% si);
18 var a = @bitCast(u128, ai);18 var a = @bitCast(u128, ai);
1919
20 const sd = @bitCast(i32, N - @clz(a)); // number of significant digits20 const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits
21 var e: i32 = sd - 1; // exponent21 var e: i32 = sd - 1; // exponent
2222
23 if (sd > FLT_MANT_DIG) {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,7 +17,7 @@ pub extern fn __floattitf(arg: i128) f128 {
17 ai = ((ai ^ si) -% si);17 ai = ((ai ^ si) -% si);
18 var a = @bitCast(u128, ai);18 var a = @bitCast(u128, ai);
1919
20 const sd = @bitCast(i32, N - @clz(a)); // number of significant digits20 const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits
21 var e: i32 = sd - 1; // exponent21 var e: i32 = sd - 1; // exponent
22 if (sd > LDBL_MANT_DIG) {22 if (sd > LDBL_MANT_DIG) {
23 // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx23 // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
std/special/compiler_rt/floatunditf.zig+1-1
...@@ -14,7 +14,7 @@ pub extern fn __floatunditf(a: u128) f128 {...@@ -14,7 +14,7 @@ pub extern fn __floatunditf(a: u128) f128 {
14 const exponent_bias = (1 << (exponent_bits - 1)) - 1;14 const exponent_bias = (1 << (exponent_bits - 1)) - 1;
15 const implicit_bit = 1 << mantissa_bits;15 const implicit_bit = 1 << mantissa_bits;
1616
17 const exp = (u128.bit_count - 1) - @clz(a);17 const exp = (u128.bit_count - 1) - @clz(u128, a);
18 const shift = mantissa_bits - @intCast(u7, exp);18 const shift = mantissa_bits - @intCast(u7, exp);
1919
20 var result: u128 align(16) = (a << shift) ^ implicit_bit;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,7 +10,7 @@ pub extern fn __floatunsidf(arg: u32) f64 {
10 if (arg == 0) return 0.0;10 if (arg == 0) return 0.0;
1111
12 // The exponent is the width of abs(a)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 // Shift a into the significand field and clear the implicit bit14 // Shift a into the significand field and clear the implicit bit
15 const shift = @intCast(u6, 52 - exp);15 const shift = @intCast(u6, 52 - exp);
16 const mant = u64(arg) << shift ^ implicitBit;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,7 +14,7 @@ pub extern fn __floatunsitf(a: u64) f128 {
14 const exponent_bias = (1 << (exponent_bits - 1)) - 1;14 const exponent_bias = (1 << (exponent_bits - 1)) - 1;
15 const implicit_bit = 1 << mantissa_bits;15 const implicit_bit = 1 << mantissa_bits;
1616
17 const exp = (u64.bit_count - 1) - @clz(a);17 const exp = (u64.bit_count - 1) - @clz(u64, a);
18 const shift = mantissa_bits - @intCast(u7, exp);18 const shift = mantissa_bits - @intCast(u7, exp);
1919
20 // TODO(#1148): @bitCast alignment error20 // 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,7 +13,7 @@ pub extern fn __floatuntidf(arg: u128) f64 {
1313
14 var a = arg;14 var a = arg;
15 const N: u32 = @sizeOf(u128) * 8;15 const N: u32 = @sizeOf(u128) * 8;
16 const sd = @bitCast(i32, N - @clz(a)); // number of significant digits16 const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits
17 var e: i32 = sd - 1; // exponent17 var e: i32 = sd - 1; // exponent
18 if (sd > DBL_MANT_DIG) {18 if (sd > DBL_MANT_DIG) {
19 // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx19 // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
std/special/compiler_rt/floatuntisf.zig+1-1
...@@ -13,7 +13,7 @@ pub extern fn __floatuntisf(arg: u128) f32 {...@@ -13,7 +13,7 @@ pub extern fn __floatuntisf(arg: u128) f32 {
1313
14 var a = arg;14 var a = arg;
15 const N: u32 = @sizeOf(u128) * 8;15 const N: u32 = @sizeOf(u128) * 8;
16 const sd = @bitCast(i32, N - @clz(a)); // number of significant digits16 const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits
17 var e: i32 = sd - 1; // exponent17 var e: i32 = sd - 1; // exponent
18 if (sd > FLT_MANT_DIG) {18 if (sd > FLT_MANT_DIG) {
19 // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx19 // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
std/special/compiler_rt/floatuntitf.zig+1-1
...@@ -13,7 +13,7 @@ pub extern fn __floatuntitf(arg: u128) f128 {...@@ -13,7 +13,7 @@ pub extern fn __floatuntitf(arg: u128) f128 {
1313
14 var a = arg;14 var a = arg;
15 const N: u32 = @sizeOf(u128) * 8;15 const N: u32 = @sizeOf(u128) * 8;
16 const sd = @bitCast(i32, N - @clz(a)); // number of significant digits16 const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits
17 var e: i32 = sd - 1; // exponent17 var e: i32 = sd - 1; // exponent
18 if (sd > LDBL_MANT_DIG) {18 if (sd > LDBL_MANT_DIG) {
19 // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx19 // 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,7 +260,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
260 const significandBits = std.math.floatMantissaBits(T);260 const significandBits = std.math.floatMantissaBits(T);
261 const implicitBit = Z(1) << significandBits;261 const implicitBit = Z(1) << significandBits;
262262
263 const shift = @clz(significand.*) - @clz(implicitBit);263 const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
264 significand.* <<= @intCast(std.math.Log2Int(Z), shift);264 significand.* <<= @intCast(std.math.Log2Int(Z), shift);
265 return 1 - shift;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,12 +71,12 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
71 r[high] = n[high] & (d[high] - 1);71 r[high] = n[high] & (d[high] - 1);
72 rem.* = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #42172 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 // K K76 // K K
77 // ---77 // ---
78 // K 078 // 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 // 0 <= sr <= SingleInt.bit_count - 2 or sr large80 // 0 <= sr <= SingleInt.bit_count - 2 or sr large
81 if (sr > SingleInt.bit_count - 2) {81 if (sr > SingleInt.bit_count - 2) {
82 if (maybe_rem) |rem| {82 if (maybe_rem) |rem| {
...@@ -106,7 +106,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -106,7 +106,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
106 if (d[low] == 1) {106 if (d[low] == 1) {
107 return a;107 return a;
108 }108 }
109 sr = @ctz(d[low]);109 sr = @ctz(SingleInt, d[low]);
110 q[high] = n[high] >> @intCast(Log2SingleInt, sr);110 q[high] = n[high] >> @intCast(Log2SingleInt, sr);
111 q[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr));111 q[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr));
112 return @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &q[0]).*; // TODO issue #421112 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,7 +114,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
114 // K X114 // K X
115 // ---115 // ---
116 // 0 K116 // 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 // 2 <= sr <= DoubleInt.bit_count - 1118 // 2 <= sr <= DoubleInt.bit_count - 1
119 // q.all = a << (DoubleInt.bit_count - sr);119 // q.all = a << (DoubleInt.bit_count - sr);
120 // r.all = a >> sr;120 // r.all = a >> sr;
...@@ -140,7 +140,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:...@@ -140,7 +140,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
140 // K X140 // K X
141 // ---141 // ---
142 // K K142 // 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 // 0 <= sr <= SingleInt.bit_count - 1 or sr large144 // 0 <= sr <= SingleInt.bit_count - 1 or sr large
145 if (sr > SingleInt.bit_count - 1) {145 if (sr > SingleInt.bit_count - 1) {
146 if (maybe_rem) |rem| {146 if (maybe_rem) |rem| {
test/compile_errors.zig+1-10
...@@ -1363,21 +1363,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1363,21 +1363,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1363 cases.add(1363 cases.add(
1364 "@popCount - non-integer",1364 "@popCount - non-integer",
1365 \\export fn entry(x: f32) u32 {1365 \\export fn entry(x: f32) u32 {
1366 \\ return @popCount(x);1366 \\ return @popCount(f32, x);
1367 \\}1367 \\}
1368 ,1368 ,
1369 "tmp.zig:2:22: error: expected integer type, found 'f32'",1369 "tmp.zig:2:22: error: expected integer type, found 'f32'",
1370 );1370 );
13711371
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 cases.addCase(x: {1372 cases.addCase(x: {
1382 const tc = cases.create(1373 const tc = cases.create(
1383 "wrong same named struct",1374 "wrong same named struct",
test/stage1/behavior.zig+1-1
...@@ -8,7 +8,7 @@ comptime {...@@ -8,7 +8,7 @@ comptime {
8 _ = @import("behavior/bitcast.zig");8 _ = @import("behavior/bitcast.zig");
9 _ = @import("behavior/bitreverse.zig");9 _ = @import("behavior/bitreverse.zig");
10 _ = @import("behavior/bool.zig");10 _ = @import("behavior/bool.zig");
11 _ = @import("behavior/bswap.zig");11 _ = @import("behavior/byteswap.zig");
12 _ = @import("behavior/bugs/1025.zig");12 _ = @import("behavior/bugs/1025.zig");
13 _ = @import("behavior/bugs/1076.zig");13 _ = @import("behavior/bugs/1076.zig");
14 _ = @import("behavior/bugs/1111.zig");14 _ = @import("behavior/bugs/1111.zig");
test/stage1/behavior/bitreverse.zig+38-50
...@@ -2,80 +2,68 @@ const std = @import("std");...@@ -2,80 +2,68 @@ const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
3const minInt = std.math.minInt;3const minInt = std.math.minInt;
44
5test "@bitreverse" {5test "@bitReverse" {
6 comptime testBitReverse();6 comptime testBitReverse();
7 testBitReverse();7 testBitReverse();
8}8}
99
10fn testBitReverse() void {10fn testBitReverse() void {
11 // using comptime_ints, unsigned11 // using comptime_ints, unsigned
12 expect(@bitreverse(u0, 0) == 0);12 expect(@bitReverse(u0, u0(0)) == 0);
13 expect(@bitreverse(u5, 0x12) == 0x9);13 expect(@bitReverse(u5, u5(0x12)) == 0x9);
14 expect(@bitreverse(u8, 0x12) == 0x48);14 expect(@bitReverse(u8, u8(0x12)) == 0x48);
15 expect(@bitreverse(u16, 0x1234) == 0x2c48);15 expect(@bitReverse(u16, u16(0x1234)) == 0x2c48);
16 expect(@bitreverse(u24, 0x123456) == 0x6a2c48);16 expect(@bitReverse(u24, u24(0x123456)) == 0x6a2c48);
17 expect(@bitreverse(u32, 0x12345678) == 0x1e6a2c48);17 expect(@bitReverse(u32, u32(0x12345678)) == 0x1e6a2c48);
18 expect(@bitreverse(u40, 0x123456789a) == 0x591e6a2c48);18 expect(@bitReverse(u40, u40(0x123456789a)) == 0x591e6a2c48);
19 expect(@bitreverse(u48, 0x123456789abc) == 0x3d591e6a2c48);19 expect(@bitReverse(u48, u48(0x123456789abc)) == 0x3d591e6a2c48);
20 expect(@bitreverse(u56, 0x123456789abcde) == 0x7b3d591e6a2c48);20 expect(@bitReverse(u56, u56(0x123456789abcde)) == 0x7b3d591e6a2c48);
21 expect(@bitreverse(u64, 0x123456789abcdef1) == 0x8f7b3d591e6a2c48);21 expect(@bitReverse(u64, u64(0x123456789abcdef1)) == 0x8f7b3d591e6a2c48);
22 expect(@bitreverse(u128, 0x123456789abcdef11121314151617181) == 0x818e868a828c84888f7b3d591e6a2c48);22 expect(@bitReverse(u128, u128(0x123456789abcdef11121314151617181)) == 0x818e868a828c84888f7b3d591e6a2c48);
2323
24 // using runtime uints, unsigned24 // using runtime uints, unsigned
25 var num0: u0 = 0;25 var num0: u0 = 0;
26 expect(@bitreverse(u0, num0) == 0);26 expect(@bitReverse(u0, num0) == 0);
27 var num5: u5 = 0x12;27 var num5: u5 = 0x12;
28 expect(@bitreverse(u5, num5) == 0x9);28 expect(@bitReverse(u5, num5) == 0x9);
29 var num8: u8 = 0x12;29 var num8: u8 = 0x12;
30 expect(@bitreverse(u8, num8) == 0x48);30 expect(@bitReverse(u8, num8) == 0x48);
31 var num16: u16 = 0x1234;31 var num16: u16 = 0x1234;
32 expect(@bitreverse(u16, num16) == 0x2c48);32 expect(@bitReverse(u16, num16) == 0x2c48);
33 var num24: u24 = 0x123456;33 var num24: u24 = 0x123456;
34 expect(@bitreverse(u24, num24) == 0x6a2c48);34 expect(@bitReverse(u24, num24) == 0x6a2c48);
35 var num32: u32 = 0x12345678;35 var num32: u32 = 0x12345678;
36 expect(@bitreverse(u32, num32) == 0x1e6a2c48);36 expect(@bitReverse(u32, num32) == 0x1e6a2c48);
37 var num40: u40 = 0x123456789a;37 var num40: u40 = 0x123456789a;
38 expect(@bitreverse(u40, num40) == 0x591e6a2c48);38 expect(@bitReverse(u40, num40) == 0x591e6a2c48);
39 var num48: u48 = 0x123456789abc;39 var num48: u48 = 0x123456789abc;
40 expect(@bitreverse(u48, num48) == 0x3d591e6a2c48);40 expect(@bitReverse(u48, num48) == 0x3d591e6a2c48);
41 var num56: u56 = 0x123456789abcde;41 var num56: u56 = 0x123456789abcde;
42 expect(@bitreverse(u56, num56) == 0x7b3d591e6a2c48);42 expect(@bitReverse(u56, num56) == 0x7b3d591e6a2c48);
43 var num64: u64 = 0x123456789abcdef1;43 var num64: u64 = 0x123456789abcdef1;
44 expect(@bitreverse(u64, num64) == 0x8f7b3d591e6a2c48);44 expect(@bitReverse(u64, num64) == 0x8f7b3d591e6a2c48);
45 var num128: u128 = 0x123456789abcdef11121314151617181;45 var num128: u128 = 0x123456789abcdef11121314151617181;
46 expect(@bitreverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48);46 expect(@bitReverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48);
4747
48 // using comptime_ints, signed, positive48 // using comptime_ints, signed, positive
49 expect(@bitreverse(i0, 0) == 0);49 expect(@bitReverse(u8, u8(0)) == 0);
50 expect(@bitreverse(i8, @bitCast(i8, u8(0x92))) == @bitCast(i8, u8(0x49)));50 expect(@bitReverse(i8, @bitCast(i8, u8(0x92))) == @bitCast(i8, u8(0x49)));
51 expect(@bitreverse(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x2c48)));51 expect(@bitReverse(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x2c48)));
52 expect(@bitreverse(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x6a2c48)));52 expect(@bitReverse(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x6a2c48)));
53 expect(@bitreverse(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x1e6a2c48)));53 expect(@bitReverse(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x1e6a2c48)));
54 expect(@bitreverse(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x591e6a2c48)));54 expect(@bitReverse(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x591e6a2c48)));
55 expect(@bitreverse(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0x3d591e6a2c48)));55 expect(@bitReverse(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0x3d591e6a2c48)));
56 expect(@bitreverse(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0x7b3d591e6a2c48)));56 expect(@bitReverse(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0x7b3d591e6a2c48)));
57 expect(@bitreverse(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0x8f7b3d591e6a2c48)));57 expect(@bitReverse(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0x8f7b3d591e6a2c48)));
58 expect(@bitreverse(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == @bitCast(i128, u128(0x818e868a828c84888f7b3d591e6a2c48)));58 expect(@bitReverse(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == @bitCast(i128, u128(0x818e868a828c84888f7b3d591e6a2c48)));
5959
60 // using comptime_ints, signed, negative. Compare to runtime ints returned from llvm.60 // using 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));
63 var neg8: i8 = -18;61 var neg8: i8 = -18;
64 expect(@bitreverse(i8, -18) == @bitreverse(i8, neg8));62 expect(@bitReverse(i8, i8(-18)) == @bitReverse(i8, neg8));
65 var neg16: i16 = -32694;63 var neg16: i16 = -32694;
66 expect(@bitreverse(i16, -32694) == @bitreverse(i16, neg16));64 expect(@bitReverse(i16, i16(-32694)) == @bitReverse(i16, neg16));
67 var neg24: i24 = -6773785;65 var neg24: i24 = -6773785;
68 expect(@bitreverse(i24, -6773785) == @bitreverse(i24, neg24));66 expect(@bitReverse(i24, i24(-6773785)) == @bitReverse(i24, neg24));
69 var neg32: i32 = -16773785;67 var neg32: i32 = -16773785;
70 expect(@bitreverse(i32, -16773785) == @bitreverse(i32, neg32));68 expect(@bitReverse(i32, 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));
81}69}
test/stage1/behavior/bswap.zig deleted-32
...@@ -1,32 +0,0 @@
1const std = @import("std");
2const expect = std.testing.expect;
3
4test "@bswap" {
5 comptime testByteSwap();
6 testByteSwap();
7}
8
9fn 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,7 +3,7 @@ const expect = std.testing.expect;
3const math = std.math;3const math = std.math;
44
5fn ctz(x: var) usize {5fn ctz(x: var) usize {
6 return @ctz(x);6 return @ctz(u128, x);
7}7}
88
9test "fixed" {9test "fixed" {
test/stage1/behavior/byteswap.zig created+32
...@@ -0,0 +1,32 @@
1const std = @import("std");
2const expect = std.testing.expect;
3
4test "@byteSwap" {
5 comptime testByteSwap();
6 testByteSwap();
7}
8
9fn 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,15 +114,16 @@ test "@clz" {
114}114}
115115
116fn testClz() void {116fn testClz() void {
117 expect(clz(u8(0b00001010)) == 4);117 expect(clz(u8, u8(0b10001010)) == 0);
118 expect(clz(u8(0b10001010)) == 0);118 expect(clz(u8, u8(0b00001010)) == 4);
119 expect(clz(u8(0b00000000)) == 8);119 expect(clz(u8, u8(0b00011010)) == 3);
120 expect(clz(u128(0xffffffffffffffff)) == 64);120 expect(clz(u8, u8(0b00000000)) == 8);
121 expect(clz(u128(0x10000000000000000)) == 63);121 expect(clz(u128, u128(0xffffffffffffffff)) == 64);
122 expect(clz(u128, u128(0x10000000000000000)) == 63);
122}123}
123124
124fn clz(x: var) usize {125fn clz(comptime T: type, x: T) usize {
125 return @clz(x);126 return @clz(T, x);
126}127}
127128
128test "@ctz" {129test "@ctz" {
...@@ -131,13 +132,25 @@ test "@ctz" {...@@ -131,13 +132,25 @@ test "@ctz" {
131}132}
132133
133fn testCtz() void {134fn testCtz() void {
134 expect(ctz(u8(0b10100000)) == 5);135 expect(ctz(u8, u8(0b10100000)) == 5);
135 expect(ctz(u8(0b10001010)) == 1);136 expect(ctz(u8, u8(0b10001010)) == 1);
136 expect(ctz(u8(0b00000000)) == 8);137 expect(ctz(u8, u8(0b00000000)) == 8);
138 expect(ctz(u16, u16(0b00000000)) == 16);
137}139}
138140
139fn ctz(x: var) usize {141fn ctz(comptime T: type, x: T) usize {
140 return @ctz(x);142 return @ctz(T, x);
143}
144
145pub 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}
142155
143test "assignment operators" {156test "assignment operators" {
test/stage1/behavior/popcount.zig+23-4
...@@ -6,20 +6,39 @@ test "@popCount" {...@@ -6,20 +6,39 @@ test "@popCount" {
6}6}
77
8fn testPopCount() void {8fn 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 var x: u32 = 0xaa;18 var x: u32 = 0xaa;
11 expect(@popCount(x) == 4);19 expect(@popCount(u32, x) == 4);
12 }20 }
13 {21 {
14 var x: u32 = 0xaaaaaaaa;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 var x: i16 = -1;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 comptime {40 comptime {
22 expect(@popCount(0b11111111000110001100010000100001000011000011100101010001) == 24);41 expect(@popCount(i128, u128(0b11111111000110001100010000100001000011000011100101010001)) == 24);
23 }42 }
24}43}
2544