Commit 1fdb24827f
Changed files (38)
std
math
big
special
test
doc/langref.html.in
@@ -6239,8 +6239,8 @@ comptime {
{#header_close#}
- {#header_open|@bswap#}
- <pre>{#syntax#}@bswap(comptime T: type, value: T) T{#endsyntax#}</pre>
+ {#header_open|@byteSwap#}
+ <pre>{#syntax#}@byteSwap(comptime T: type, integer: T) T{#endsyntax#}</pre>
<p>{#syntax#}T{#endsyntax#} must be an integer type with bit count evenly divisible by 8.</p>
<p>
Swaps the byte order of the integer. This converts a big endian integer to a little endian integer,
@@ -6248,8 +6248,8 @@ comptime {
</p>
{#header_close#}
- {#header_open|@bitreverse#}
- <pre>{#syntax#}@bitreverse(comptime T: type, value: T) T{#endsyntax#}</pre>
+ {#header_open|@bitReverse#}
+ <pre>{#syntax#}@bitReverse(comptime T: type, integer: T) T{#endsyntax#}</pre>
<p>{#syntax#}T{#endsyntax#} accepts any integer type.</p>
<p>
Reverses the bitpattern of an integer value, including the sign bit if applicable.
@@ -6337,14 +6337,15 @@ comptime {
{#header_close#}
{#header_open|@clz#}
- <pre>{#syntax#}@clz(x: T) U{#endsyntax#}</pre>
+ <pre>{#syntax#}@clz(comptime T: type, integer: T) math.Log2Int(@intType(false, @typeInfo(T).Int.bits + 1)){#endsyntax#}</pre>
<p>
This function counts the number of leading zeroes in {#syntax#}x{#endsyntax#} which is an integer
type {#syntax#}T{#endsyntax#}.
</p>
<p>
- The return type {#syntax#}U{#endsyntax#} is an unsigned integer with the minimum number
- of bits that can represent the value {#syntax#}T.bit_count{#endsyntax#}.
+ If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#endsyntax#}.
+ Otherwise, the return type is an unsigned integer with the minimum number
+ of bits that can represent the bit count of the integer type.
</p>
<p>
If {#syntax#}x{#endsyntax#} is zero, {#syntax#}@clz{#endsyntax#} returns {#syntax#}T.bit_count{#endsyntax#}.
@@ -6477,14 +6478,15 @@ test "main" {
{#header_close#}
{#header_open|@ctz#}
- <pre>{#syntax#}@ctz(x: T) U{#endsyntax#}</pre>
+ <pre>{#syntax#}@ctz(comptime T: type, integer: T) math.Log2Int(@intType(false, @typeInfo(T).Int.bits + 1)){#endsyntax#}</pre>
<p>
This function counts the number of trailing zeroes in {#syntax#}x{#endsyntax#} which is an integer
type {#syntax#}T{#endsyntax#}.
</p>
<p>
- The return type {#syntax#}U{#endsyntax#} is an unsigned integer with the minimum number
- of bits that can represent the value {#syntax#}T.bit_count{#endsyntax#}.
+ If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#endsyntax#}.
+ Otherwise, the return type is an unsigned integer with the minimum number
+ of bits that can represent the bit count of the integer type.
</p>
<p>
If {#syntax#}x{#endsyntax#} is zero, {#syntax#}@ctz{#endsyntax#} returns {#syntax#}T.bit_count{#endsyntax#}.
@@ -7034,7 +7036,7 @@ test "call foo" {
{#header_close#}
{#header_open|@popCount#}
- <pre>{#syntax#}@popCount(integer: var) var{#endsyntax#}</pre>
+ <pre>{#syntax#}@popCount(comptime T: type, integer: T) math.Log2Int(@intType(false, @typeInfo(T).Int.bits + 1)){#endsyntax#}</pre>
<p>Counts the number of bits set in an integer.</p>
<p>
If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#endsyntax#}.
src/all_types.hpp
@@ -1407,6 +1407,8 @@ enum BuiltinFnId {
BuiltinFnIdCtz,
BuiltinFnIdClz,
BuiltinFnIdPopCount,
+ BuiltinFnIdBswap,
+ BuiltinFnIdBitReverse,
BuiltinFnIdImport,
BuiltinFnIdCImport,
BuiltinFnIdErrName,
@@ -1469,8 +1471,6 @@ enum BuiltinFnId {
BuiltinFnIdErrorReturnTrace,
BuiltinFnIdAtomicRmw,
BuiltinFnIdAtomicLoad,
- BuiltinFnIdBswap,
- BuiltinFnIdBitReverse,
};
struct BuiltinFnEntry {
@@ -2191,6 +2191,8 @@ enum IrInstructionId {
IrInstructionIdClz,
IrInstructionIdCtz,
IrInstructionIdPopCount,
+ IrInstructionIdBswap,
+ IrInstructionIdBitReverse,
IrInstructionIdImport,
IrInstructionIdCImport,
IrInstructionIdCInclude,
@@ -2287,8 +2289,6 @@ enum IrInstructionId {
IrInstructionIdMergeErrRetTraces,
IrInstructionIdMarkErrRetTracePtr,
IrInstructionIdSqrt,
- IrInstructionIdBswap,
- IrInstructionIdBitReverse,
IrInstructionIdErrSetCast,
IrInstructionIdToBytes,
IrInstructionIdFromBytes,
@@ -2744,19 +2744,22 @@ struct IrInstructionOptionalUnwrapPtr {
struct IrInstructionCtz {
IrInstruction base;
- IrInstruction *value;
+ IrInstruction *type;
+ IrInstruction *op;
};
struct IrInstructionClz {
IrInstruction base;
- IrInstruction *value;
+ IrInstruction *type;
+ IrInstruction *op;
};
struct IrInstructionPopCount {
IrInstruction base;
- IrInstruction *value;
+ IrInstruction *type;
+ IrInstruction *op;
};
struct IrInstructionUnionTag {
src/analyze.cpp
@@ -213,15 +213,6 @@ static ZigType *new_container_type_entry(CodeGen *g, ZigTypeId id, AstNode *sour
return entry;
}
-static uint8_t bits_needed_for_unsigned(uint64_t x) {
- if (x == 0) {
- return 0;
- }
- uint8_t base = log2_u64(x);
- uint64_t upper = (((uint64_t)1) << base) - 1;
- return (upper >= x) ? base : (base + 1);
-}
-
AstNode *type_decl_node(ZigType *type_entry) {
switch (type_entry->id) {
case ZigTypeIdInvalid:
@@ -335,10 +326,33 @@ static bool is_slice(ZigType *type) {
return type->id == ZigTypeIdStruct && type->data.structure.is_slice;
}
+static uint8_t bits_needed_for_unsigned(uint64_t x) {
+ if (x == 0) {
+ return 0;
+ }
+ uint8_t base = log2_u64(x);
+ uint64_t upper = (((uint64_t)1) << base) - 1;
+ return (upper >= x) ? base : (base + 1);
+}
+
+static uint8_t bits_needed_for_popcount_unsigned(uint64_t x) {
+ uint8_t count = 0;
+ for (uint64_t s = x;s != 0;s >>= 1)
+ count++;
+
+ return count;
+}
+
ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) {
return get_int_type(g, false, bits_needed_for_unsigned(x));
}
+// This is not the same as above, because while shift by bit width is UB, @clz, @popCount, and @ctz
+// can return bit width
+ZigType *get_smallest_popcount_unsigned_int_type(CodeGen *g, uint64_t x) {
+ return get_int_type(g, false, bits_needed_for_popcount_unsigned(x));
+}
+
ZigType *get_promise_type(CodeGen *g, ZigType *result_type) {
if (result_type != nullptr && result_type->promise_parent != nullptr) {
return result_type->promise_parent;
src/analyze.hpp
@@ -34,6 +34,7 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type);
ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind,
AstNode *decl_node, const char *full_name, Buf *bare_name, ContainerLayout layout);
ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);
+ZigType *get_smallest_popcount_unsigned_int_type(CodeGen *g, uint64_t x);
ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payload_type);
ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry);
ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name);
src/codegen.cpp
@@ -4126,11 +4126,19 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI
char llvm_name[64];
sprintf(llvm_name, "llvm.%s.i%" PRIu32, fn_name, int_type->data.integral.bit_count);
- LLVMTypeRef param_types[] = {
- get_llvm_type(g, int_type),
- LLVMInt1Type(),
- };
- LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, int_type), param_types, n_args, false);
+ LLVMTypeRef param_types[3];
+ switch (n_args) {
+ case 1:
+ param_types[0] = get_llvm_type(g, int_type);
+ break;
+ case 2: // clz and ctz
+ param_types[0] = get_llvm_type(g, int_type);
+ param_types[1] = LLVMInt1Type();
+ break;
+ default:
+ zig_unreachable();
+ }
+ LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, int_type), ¶m_types[0], n_args, false);
LLVMValueRef fn_val = LLVMAddFunction(g->module, llvm_name, fn_type);
assert(LLVMGetIntrinsicID(fn_val));
@@ -4140,9 +4148,9 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI
}
static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstructionClz *instruction) {
- ZigType *int_type = instruction->value->value.type;
+ ZigType *int_type = instruction->op->value.type;
LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdClz);
- LLVMValueRef operand = ir_llvm_value(g, instruction->value);
+ LLVMValueRef operand = ir_llvm_value(g, instruction->op);
LLVMValueRef params[] {
operand,
LLVMConstNull(LLVMInt1Type()),
@@ -4152,9 +4160,9 @@ static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstru
}
static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstructionCtz *instruction) {
- ZigType *int_type = instruction->value->value.type;
+ ZigType *int_type = instruction->op->value.type;
LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdCtz);
- LLVMValueRef operand = ir_llvm_value(g, instruction->value);
+ LLVMValueRef operand = ir_llvm_value(g, instruction->op);
LLVMValueRef params[] {
operand,
LLVMConstNull(LLVMInt1Type()),
@@ -4164,9 +4172,9 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstru
}
static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutable *executable, IrInstructionPopCount *instruction) {
- ZigType *int_type = instruction->value->value.type;
+ ZigType *int_type = instruction->op->value.type;
LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount);
- LLVMValueRef operand = ir_llvm_value(g, instruction->value);
+ LLVMValueRef operand = ir_llvm_value(g, instruction->op);
LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, &operand, 1, "");
return gen_widen_or_shorten(g, false, int_type, instruction->base.value.type, wrong_size_int);
}
@@ -5650,6 +5658,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_pop_count(g, executable, (IrInstructionPopCount *)instruction);
case IrInstructionIdSwitchBr:
return ir_render_switch_br(g, executable, (IrInstructionSwitchBr *)instruction);
+ case IrInstructionIdBswap:
+ return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction);
+ case IrInstructionIdBitReverse:
+ return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction);
case IrInstructionIdPhi:
return ir_render_phi(g, executable, (IrInstructionPhi *)instruction);
case IrInstructionIdRef:
@@ -5766,10 +5778,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction);
case IrInstructionIdSqrt:
return ir_render_sqrt(g, executable, (IrInstructionSqrt *)instruction);
- case IrInstructionIdBswap:
- return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction);
- case IrInstructionIdBitReverse:
- return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction);
case IrInstructionIdArrayToVector:
return ir_render_array_to_vector(g, executable, (IrInstructionArrayToVector *)instruction);
case IrInstructionIdVectorToArray:
@@ -7332,9 +7340,11 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdCInclude, "cInclude", 1);
create_builtin_fn(g, BuiltinFnIdCDefine, "cDefine", 2);
create_builtin_fn(g, BuiltinFnIdCUndef, "cUndef", 1);
- create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 1);
- create_builtin_fn(g, BuiltinFnIdClz, "clz", 1);
- create_builtin_fn(g, BuiltinFnIdPopCount, "popCount", 1);
+ create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 2);
+ create_builtin_fn(g, BuiltinFnIdClz, "clz", 2);
+ create_builtin_fn(g, BuiltinFnIdPopCount, "popCount", 2);
+ create_builtin_fn(g, BuiltinFnIdBswap, "byteSwap", 2);
+ create_builtin_fn(g, BuiltinFnIdBitReverse, "bitReverse", 2);
create_builtin_fn(g, BuiltinFnIdImport, "import", 1);
create_builtin_fn(g, BuiltinFnIdCImport, "cImport", 1);
create_builtin_fn(g, BuiltinFnIdErrName, "errorName", 1);
@@ -7395,8 +7405,6 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);
create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);
create_builtin_fn(g, BuiltinFnIdThis, "This", 0);
- create_builtin_fn(g, BuiltinFnIdBswap, "bswap", 2);
- create_builtin_fn(g, BuiltinFnIdBitReverse, "bitreverse", 2);
}
static const char *bool_to_str(bool b) {
src/ir.cpp
@@ -575,6 +575,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) {
return IrInstructionIdPopCount;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) {
+ return IrInstructionIdBswap;
+}
+
+static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) {
+ return IrInstructionIdBitReverse;
+}
+
static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) {
return IrInstructionIdUnionTag;
}
@@ -983,14 +991,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) {
return IrInstructionIdSqrt;
}
-static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) {
- return IrInstructionIdBswap;
-}
-
-static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) {
- return IrInstructionIdBitReverse;
-}
-
static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) {
return IrInstructionIdCheckRuntimeScope;
}
@@ -1768,29 +1768,57 @@ static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNo
return &instruction->base;
}
-static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
+static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) {
IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, scope, source_node);
- instruction->value = value;
+ instruction->type = type;
+ instruction->op = op;
- ir_ref_instruction(value, irb->current_basic_block);
+ if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block);
+ ir_ref_instruction(op, irb->current_basic_block);
return &instruction->base;
}
-static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
+static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) {
IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, scope, source_node);
- instruction->value = value;
+ instruction->type = type;
+ instruction->op = op;
- ir_ref_instruction(value, irb->current_basic_block);
+ if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block);
+ ir_ref_instruction(op, irb->current_basic_block);
return &instruction->base;
}
-static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) {
+static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) {
IrInstructionPopCount *instruction = ir_build_instruction<IrInstructionPopCount>(irb, scope, source_node);
- instruction->value = value;
+ instruction->type = type;
+ instruction->op = op;
- ir_ref_instruction(value, irb->current_basic_block);
+ if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block);
+ ir_ref_instruction(op, irb->current_basic_block);
+
+ return &instruction->base;
+}
+
+static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) {
+ IrInstructionBswap *instruction = ir_build_instruction<IrInstructionBswap>(irb, scope, source_node);
+ instruction->type = type;
+ instruction->op = op;
+
+ if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block);
+ ir_ref_instruction(op, irb->current_basic_block);
+
+ return &instruction->base;
+}
+
+static IrInstruction *ir_build_bit_reverse(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) {
+ IrInstructionBitReverse *instruction = ir_build_instruction<IrInstructionBitReverse>(irb, scope, source_node);
+ instruction->type = type;
+ instruction->op = op;
+
+ if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block);
+ ir_ref_instruction(op, irb->current_basic_block);
return &instruction->base;
}
@@ -2986,28 +3014,6 @@ static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *sourc
return &instruction->base;
}
-static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) {
- IrInstructionBswap *instruction = ir_build_instruction<IrInstructionBswap>(irb, scope, source_node);
- instruction->type = type;
- instruction->op = op;
-
- if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block);
- ir_ref_instruction(op, irb->current_basic_block);
-
- return &instruction->base;
-}
-
-static IrInstruction *ir_build_bit_reverse(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) {
- IrInstructionBitReverse *instruction = ir_build_instruction<IrInstructionBitReverse>(irb, scope, source_node);
- instruction->type = type;
- instruction->op = op;
-
- if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block);
- ir_ref_instruction(op, irb->current_basic_block);
-
- return &instruction->base;
-}
-
static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) {
IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node);
instruction->scope_is_comptime = scope_is_comptime;
@@ -4082,36 +4088,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value);
return ir_lval_wrap(irb, scope, size_of, lval);
}
- case BuiltinFnIdCtz:
- {
- AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
- IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
- if (arg0_value == irb->codegen->invalid_instruction)
- return arg0_value;
-
- IrInstruction *ctz = ir_build_ctz(irb, scope, node, arg0_value);
- return ir_lval_wrap(irb, scope, ctz, lval);
- }
- case BuiltinFnIdPopCount:
- {
- AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
- IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
- if (arg0_value == irb->codegen->invalid_instruction)
- return arg0_value;
-
- IrInstruction *instr = ir_build_pop_count(irb, scope, node, arg0_value);
- return ir_lval_wrap(irb, scope, instr, lval);
- }
- case BuiltinFnIdClz:
- {
- AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
- IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
- if (arg0_value == irb->codegen->invalid_instruction)
- return arg0_value;
-
- IrInstruction *clz = ir_build_clz(irb, scope, node, arg0_value);
- return ir_lval_wrap(irb, scope, clz, lval);
- }
case BuiltinFnIdImport:
{
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
IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value);
return ir_lval_wrap(irb, scope, result, lval);
}
+ case BuiltinFnIdCtz:
+ case BuiltinFnIdPopCount:
+ case BuiltinFnIdClz:
case BuiltinFnIdBswap:
- {
- AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
- IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
- if (arg0_value == irb->codegen->invalid_instruction)
- return arg0_value;
-
- AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
- IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
- if (arg1_value == irb->codegen->invalid_instruction)
- return arg1_value;
-
- IrInstruction *result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value);
- return ir_lval_wrap(irb, scope, result, lval);
- }
case BuiltinFnIdBitReverse:
{
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
if (arg1_value == irb->codegen->invalid_instruction)
return arg1_value;
- IrInstruction *result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value);
+ IrInstruction *result;
+ switch (builtin_fn->id) {
+ case BuiltinFnIdCtz:
+ result = ir_build_ctz(irb, scope, node, arg0_value, arg1_value);
+ break;
+ case BuiltinFnIdPopCount:
+ result = ir_build_pop_count(irb, scope, node, arg0_value, arg1_value);
+ break;
+ case BuiltinFnIdClz:
+ result = ir_build_clz(irb, scope, node, arg0_value, arg1_value);
+ break;
+ case BuiltinFnIdBswap:
+ result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value);
+ break;
+ case BuiltinFnIdBitReverse:
+ result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value);
+ break;
+ default:
+ zig_unreachable();
+ }
return ir_lval_wrap(irb, scope, result, lval);
}
}
@@ -17040,92 +17024,125 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira,
return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on);
}
-static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *ctz_instruction) {
- IrInstruction *value = ctz_instruction->value->child;
- if (type_is_invalid(value->value.type)) {
+static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) {
+ ZigType *int_type = ir_resolve_type(ira, instruction->type->child);
+ if (type_is_invalid(int_type))
return ira->codegen->invalid_instruction;
- } else if (value->value.type->id == ZigTypeIdInt) {
- ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen,
- value->value.type->data.integral.bit_count);
- if (value->value.special != ConstValSpecialRuntime) {
- size_t result_usize = bigint_ctz(&value->value.data.x_bigint,
- value->value.type->data.integral.bit_count);
- IrInstruction *result = ir_const(ira, &ctz_instruction->base, return_type);
- bigint_init_unsigned(&result->value.data.x_bigint, result_usize);
- return result;
- }
- IrInstruction *result = ir_build_ctz(&ira->new_irb,
- ctz_instruction->base.scope, ctz_instruction->base.source_node, value);
- result->value.type = return_type;
- return result;
- } else {
- ir_add_error_node(ira, ctz_instruction->base.source_node,
- buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name)));
+ IrInstruction *op = instruction->op->child;
+
+ if (int_type->id != ZigTypeIdInt) {
+ ir_add_error(ira, instruction->type,
+ buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name)));
return ira->codegen->invalid_instruction;
}
-}
-static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *clz_instruction) {
- IrInstruction *value = clz_instruction->value->child;
- if (type_is_invalid(value->value.type)) {
+ IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type);
+ if (type_is_invalid(casted_op->value.type))
return ira->codegen->invalid_instruction;
- } else if (value->value.type->id == ZigTypeIdInt) {
- ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen,
- value->value.type->data.integral.bit_count);
- if (value->value.special != ConstValSpecialRuntime) {
- size_t result_usize = bigint_clz(&value->value.data.x_bigint,
- value->value.type->data.integral.bit_count);
- IrInstruction *result = ir_const(ira, &clz_instruction->base, return_type);
- bigint_init_unsigned(&result->value.data.x_bigint, result_usize);
- return result;
- }
- IrInstruction *result = ir_build_clz(&ira->new_irb,
- clz_instruction->base.scope, clz_instruction->base.source_node, value);
- result->value.type = return_type;
+ ZigType *return_type = get_smallest_popcount_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count);
+
+ if (int_type->data.integral.bit_count == 0) {
+ IrInstruction *result = ir_const(ira, &instruction->base, return_type);
+ bigint_init_unsigned(&result->value.data.x_bigint, 0);
return result;
- } else {
- ir_add_error_node(ira, clz_instruction->base.source_node,
- buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name)));
+ }
+
+ if (instr_is_comptime(casted_op)) {
+ size_t result_usize = bigint_ctz(&op->value.data.x_bigint,
+ op->value.type->data.integral.bit_count);
+ IrInstruction *result = ir_const(ira, &instruction->base, return_type);
+ bigint_init_unsigned(&result->value.data.x_bigint, result_usize);
+ return result;
+ }
+
+ IrInstruction *result = ir_build_ctz(&ira->new_irb, instruction->base.scope,
+ instruction->base.source_node, nullptr, casted_op);
+ result->value.type = return_type;
+ return result;
+}
+
+static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *instruction) {
+ ZigType *int_type = ir_resolve_type(ira, instruction->type->child);
+ if (type_is_invalid(int_type))
+ return ira->codegen->invalid_instruction;
+
+ IrInstruction *op = instruction->op->child;
+
+ if (int_type->id != ZigTypeIdInt) {
+ ir_add_error(ira, instruction->type,
+ buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name)));
return ira->codegen->invalid_instruction;
}
+
+ IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type);
+ if (type_is_invalid(casted_op->value.type))
+ return ira->codegen->invalid_instruction;
+
+ ZigType *return_type = get_smallest_popcount_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count);
+
+ if (int_type->data.integral.bit_count == 0) {
+ IrInstruction *result = ir_const(ira, &instruction->base, return_type);
+ bigint_init_unsigned(&result->value.data.x_bigint, 0);
+ return result;
+ }
+
+ if (instr_is_comptime(casted_op)) {
+ size_t result_usize = bigint_clz(&op->value.data.x_bigint,
+ op->value.type->data.integral.bit_count);
+ IrInstruction *result = ir_const(ira, &instruction->base, return_type);
+ bigint_init_unsigned(&result->value.data.x_bigint, result_usize);
+ return result;
+ }
+
+ IrInstruction *result = ir_build_clz(&ira->new_irb, instruction->base.scope,
+ instruction->base.source_node, nullptr, casted_op);
+ result->value.type = return_type;
+ return result;
}
static IrInstruction *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) {
- IrInstruction *value = instruction->value->child;
- if (type_is_invalid(value->value.type))
+ ZigType *int_type = ir_resolve_type(ira, instruction->type->child);
+ if (type_is_invalid(int_type))
return ira->codegen->invalid_instruction;
- if (value->value.type->id != ZigTypeIdInt && value->value.type->id != ZigTypeIdComptimeInt) {
- ir_add_error(ira, value,
- buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name)));
+ IrInstruction *op = instruction->op->child;
+
+ if (int_type->id != ZigTypeIdInt) {
+ ir_add_error(ira, instruction->type,
+ buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name)));
return ira->codegen->invalid_instruction;
}
- if (instr_is_comptime(value)) {
- ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
+ IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type);
+ if (type_is_invalid(casted_op->value.type))
+ return ira->codegen->invalid_instruction;
+
+ ZigType *return_type = get_smallest_popcount_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count);
+
+ if (int_type->data.integral.bit_count == 0) {
+ IrInstruction *result = ir_const(ira, &instruction->base, return_type);
+ bigint_init_unsigned(&result->value.data.x_bigint, 0);
+ return result;
+ }
+
+ if (instr_is_comptime(casted_op)) {
+ ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad);
if (!val)
return ira->codegen->invalid_instruction;
+
if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) {
size_t result = bigint_popcount_unsigned(&val->data.x_bigint);
return ir_const_unsigned(ira, &instruction->base, result);
}
- if (value->value.type->id == ZigTypeIdComptimeInt) {
- Buf *val_buf = buf_alloc();
- bigint_append_buf(val_buf, &val->data.x_bigint, 10);
- ir_add_error(ira, &instruction->base,
- buf_sprintf("@popCount on negative %s value %s",
- buf_ptr(&value->value.type->name), buf_ptr(val_buf)));
- return ira->codegen->invalid_instruction;
- }
- size_t result = bigint_popcount_signed(&val->data.x_bigint, value->value.type->data.integral.bit_count);
+ size_t result = bigint_popcount_signed(&val->data.x_bigint, op->value.type->data.integral.bit_count);
return ir_const_unsigned(ira, &instruction->base, result);
}
IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope,
- instruction->base.source_node, value);
- result->value.type = get_smallest_unsigned_int_type(ira->codegen, value->value.type->data.integral.bit_count);
+ instruction->base.source_node, nullptr, casted_op);
+ result->value.type = return_type;
return result;
}
@@ -22990,8 +23007,6 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction
return ira->codegen->invalid_instruction;
IrInstruction *op = instruction->op->child;
- if (type_is_invalid(op->value.type))
- return ira->codegen->invalid_instruction;
if (int_type->id != ZigTypeIdInt) {
ir_add_error(ira, instruction->type,
@@ -22999,17 +23014,17 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction
return ira->codegen->invalid_instruction;
}
+ IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type);
+ if (type_is_invalid(casted_op->value.type))
+ return ira->codegen->invalid_instruction;
+
if (int_type->data.integral.bit_count % 8 != 0) {
- ir_add_error(ira, instruction->type,
- buf_sprintf("@bswap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8",
+ ir_add_error(ira, instruction->op,
+ buf_sprintf("@byteSwap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8",
buf_ptr(&int_type->name), int_type->data.integral.bit_count));
return ira->codegen->invalid_instruction;
}
- IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type);
- if (type_is_invalid(casted_op->value.type))
- return ira->codegen->invalid_instruction;
-
if (int_type->data.integral.bit_count == 0) {
IrInstruction *result = ir_const(ira, &instruction->base, int_type);
bigint_init_unsigned(&result->value.data.x_bigint, 0);
@@ -23017,7 +23032,7 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction
}
if (int_type->data.integral.bit_count == 8) {
- return casted_op;
+ return op;
}
if (instr_is_comptime(casted_op)) {
@@ -23046,8 +23061,6 @@ static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstr
return ira->codegen->invalid_instruction;
IrInstruction *op = instruction->op->child;
- if (type_is_invalid(op->value.type))
- return ira->codegen->invalid_instruction;
if (int_type->id != ZigTypeIdInt) {
ir_add_error(ira, instruction->type,
@@ -23251,6 +23264,10 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
return ir_analyze_instruction_ctz(ira, (IrInstructionCtz *)instruction);
case IrInstructionIdPopCount:
return ir_analyze_instruction_pop_count(ira, (IrInstructionPopCount *)instruction);
+ case IrInstructionIdBswap:
+ return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction);
+ case IrInstructionIdBitReverse:
+ return ir_analyze_instruction_bit_reverse(ira, (IrInstructionBitReverse *)instruction);
case IrInstructionIdSwitchBr:
return ir_analyze_instruction_switch_br(ira, (IrInstructionSwitchBr *)instruction);
case IrInstructionIdSwitchTarget:
@@ -23443,10 +23460,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction);
case IrInstructionIdSqrt:
return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction);
- case IrInstructionIdBswap:
- return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction);
- case IrInstructionIdBitReverse:
- return ir_analyze_instruction_bit_reverse(ira, (IrInstructionBitReverse *)instruction);
case IrInstructionIdIntToErr:
return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction);
case IrInstructionIdErrToInt:
@@ -23621,6 +23634,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdClz:
case IrInstructionIdCtz:
case IrInstructionIdPopCount:
+ case IrInstructionIdBswap:
+ case IrInstructionIdBitReverse:
case IrInstructionIdSwitchVar:
case IrInstructionIdSwitchElseVar:
case IrInstructionIdSwitchTarget:
@@ -23679,8 +23694,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdCoroPromise:
case IrInstructionIdPromiseResultType:
case IrInstructionIdSqrt:
- case IrInstructionIdBswap:
- case IrInstructionIdBitReverse:
case IrInstructionIdAtomicLoad:
case IrInstructionIdIntCast:
case IrInstructionIdFloatCast:
src/ir_print.cpp
@@ -504,19 +504,61 @@ static void ir_print_optional_unwrap_ptr(IrPrint *irp, IrInstructionOptionalUnwr
static void ir_print_clz(IrPrint *irp, IrInstructionClz *instruction) {
fprintf(irp->f, "@clz(");
- ir_print_other_instruction(irp, instruction->value);
+ if (instruction->type != nullptr) {
+ ir_print_other_instruction(irp, instruction->type);
+ } else {
+ fprintf(irp->f, "null");
+ }
+ fprintf(irp->f, ",");
+ ir_print_other_instruction(irp, instruction->op);
fprintf(irp->f, ")");
}
static void ir_print_ctz(IrPrint *irp, IrInstructionCtz *instruction) {
fprintf(irp->f, "@ctz(");
- ir_print_other_instruction(irp, instruction->value);
+ if (instruction->type != nullptr) {
+ ir_print_other_instruction(irp, instruction->type);
+ } else {
+ fprintf(irp->f, "null");
+ }
+ fprintf(irp->f, ",");
+ ir_print_other_instruction(irp, instruction->op);
fprintf(irp->f, ")");
}
static void ir_print_pop_count(IrPrint *irp, IrInstructionPopCount *instruction) {
fprintf(irp->f, "@popCount(");
- ir_print_other_instruction(irp, instruction->value);
+ if (instruction->type != nullptr) {
+ ir_print_other_instruction(irp, instruction->type);
+ } else {
+ fprintf(irp->f, "null");
+ }
+ fprintf(irp->f, ",");
+ ir_print_other_instruction(irp, instruction->op);
+ fprintf(irp->f, ")");
+}
+
+static void ir_print_bswap(IrPrint *irp, IrInstructionBswap *instruction) {
+ fprintf(irp->f, "@byteSwap(");
+ if (instruction->type != nullptr) {
+ ir_print_other_instruction(irp, instruction->type);
+ } else {
+ fprintf(irp->f, "null");
+ }
+ fprintf(irp->f, ",");
+ ir_print_other_instruction(irp, instruction->op);
+ fprintf(irp->f, ")");
+}
+
+static void ir_print_bit_reverse(IrPrint *irp, IrInstructionBitReverse *instruction) {
+ fprintf(irp->f, "@bitReverse(");
+ if (instruction->type != nullptr) {
+ ir_print_other_instruction(irp, instruction->type);
+ } else {
+ fprintf(irp->f, "null");
+ }
+ fprintf(irp->f, ",");
+ ir_print_other_instruction(irp, instruction->op);
fprintf(irp->f, ")");
}
@@ -1411,30 +1453,6 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va
}
}
-static void ir_print_bswap(IrPrint *irp, IrInstructionBswap *instruction) {
- fprintf(irp->f, "@bswap(");
- if (instruction->type != nullptr) {
- ir_print_other_instruction(irp, instruction->type);
- } else {
- fprintf(irp->f, "null");
- }
- fprintf(irp->f, ",");
- ir_print_other_instruction(irp, instruction->op);
- fprintf(irp->f, ")");
-}
-
-static void ir_print_bit_reverse(IrPrint *irp, IrInstructionBitReverse *instruction) {
- fprintf(irp->f, "@bitreverse(");
- if (instruction->type != nullptr) {
- ir_print_other_instruction(irp, instruction->type);
- } else {
- fprintf(irp->f, "null");
- }
- fprintf(irp->f, ",");
- ir_print_other_instruction(irp, instruction->op);
- fprintf(irp->f, ")");
-}
-
static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
ir_print_prefix(irp, instruction);
switch (instruction->id) {
@@ -1551,15 +1569,21 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdOptionalUnwrapPtr:
ir_print_optional_unwrap_ptr(irp, (IrInstructionOptionalUnwrapPtr *)instruction);
break;
- case IrInstructionIdCtz:
- ir_print_ctz(irp, (IrInstructionCtz *)instruction);
- break;
case IrInstructionIdPopCount:
ir_print_pop_count(irp, (IrInstructionPopCount *)instruction);
break;
case IrInstructionIdClz:
ir_print_clz(irp, (IrInstructionClz *)instruction);
break;
+ case IrInstructionIdCtz:
+ ir_print_ctz(irp, (IrInstructionCtz *)instruction);
+ break;
+ case IrInstructionIdBswap:
+ ir_print_bswap(irp, (IrInstructionBswap *)instruction);
+ break;
+ case IrInstructionIdBitReverse:
+ ir_print_bit_reverse(irp, (IrInstructionBitReverse *)instruction);
+ break;
case IrInstructionIdSwitchBr:
ir_print_switch_br(irp, (IrInstructionSwitchBr *)instruction);
break;
@@ -1869,12 +1893,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdSqrt:
ir_print_sqrt(irp, (IrInstructionSqrt *)instruction);
break;
- case IrInstructionIdBswap:
- ir_print_bswap(irp, (IrInstructionBswap *)instruction);
- break;
- case IrInstructionIdBitReverse:
- ir_print_bit_reverse(irp, (IrInstructionBitReverse *)instruction);
- break;
case IrInstructionIdAtomicLoad:
ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction);
break;
std/math/big/int.zig
@@ -207,7 +207,7 @@ pub const Int = struct {
/// Returns the number of bits required to represent the absolute value an Int.
fn bitCountAbs(self: Int) usize {
- return (self.len() - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len() - 1]));
+ return (self.len() - 1) * Limb.bit_count + (Limb.bit_count - @clz(Limb, self.limbs[self.len() - 1]));
}
/// Returns the number of bits required to represent the integer in twos-complement form.
@@ -226,9 +226,9 @@ pub const Int = struct {
if (!self.isPositive()) block: {
bits += 1;
- if (@popCount(self.limbs[self.len() - 1]) == 1) {
+ if (@popCount(Limb, self.limbs[self.len() - 1]) == 1) {
for (self.limbs[0 .. self.len() - 1]) |limb| {
- if (@popCount(limb) != 0) {
+ if (@popCount(Limb, limb) != 0) {
break :block;
}
}
@@ -962,7 +962,7 @@ pub const Int = struct {
defer tmp.deinit();
// Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) and even
- var norm_shift = @clz(y.limbs[y.len() - 1]);
+ var norm_shift = @clz(Limb, y.limbs[y.len() - 1]);
if (norm_shift == 0 and y.isOdd()) {
norm_shift = Limb.bit_count;
}
std/special/compiler_rt/addXf3.zig
@@ -36,11 +36,11 @@ pub extern fn __subtf3(a: f128, b: f128) f128 {
// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
const Z = @IntType(false, T.bit_count);
- const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1));
+ const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1));
const significandBits = std.math.floatMantissaBits(T);
const implicitBit = Z(1) << significandBits;
- const shift = @clz(significand.*) - @clz(implicitBit);
+ const shift = @clz(@IntType(false, T.bit_count), significand.*) - @clz(Z, implicitBit);
significand.* <<= @intCast(S, shift);
return 1 - shift;
}
@@ -48,7 +48,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
fn addXf3(comptime T: type, a: T, b: T) T {
const Z = @IntType(false, T.bit_count);
- const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1));
+ const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1));
const typeWidth = T.bit_count;
const significandBits = std.math.floatMantissaBits(T);
@@ -162,7 +162,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {
// If partial cancellation occured, we need to left-shift the result
// and adjust the exponent:
if (aSignificand < implicitBit << 3) {
- const shift = @intCast(i32, @clz(aSignificand)) - @intCast(i32, @clz(implicitBit << 3));
+ const shift = @intCast(i32, @clz(Z, aSignificand)) - @intCast(i32, @clz(@IntType(false, T.bit_count), implicitBit << 3));
aSignificand <<= @intCast(S, shift);
aExponent -= shift;
}
std/special/compiler_rt/divdf3.zig
@@ -318,7 +318,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
const significandBits = std.math.floatMantissaBits(T);
const implicitBit = Z(1) << significandBits;
- const shift = @clz(significand.*) - @clz(implicitBit);
+ const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
significand.* <<= @intCast(std.math.Log2Int(Z), shift);
return 1 - shift;
}
std/special/compiler_rt/divsf3.zig
@@ -191,7 +191,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
const significandBits = std.math.floatMantissaBits(T);
const implicitBit = Z(1) << significandBits;
- const shift = @clz(significand.*) - @clz(implicitBit);
+ const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
significand.* <<= @intCast(std.math.Log2Int(Z), shift);
return 1 - shift;
}
std/special/compiler_rt/extendXfYf2.zig
@@ -75,7 +75,8 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t
// a is denormal.
// renormalize the significand and clear the leading bit, then insert
// the correct adjusted exponent in the destination type.
- const scale: u32 = @clz(aAbs) - @clz(src_rep_t(srcMinNormal));
+ const scale: u32 = @clz(src_rep_t, aAbs) -
+ @clz(src_rep_t, src_rep_t(srcMinNormal));
absResult = dst_rep_t(aAbs) << @intCast(DstShift, dstSigBits - srcSigBits + scale);
absResult ^= dstMinNormal;
const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1;
std/special/compiler_rt/floatsiXf.zig
@@ -6,7 +6,7 @@ fn floatsiXf(comptime T: type, a: i32) T {
@setRuntimeSafety(builtin.is_test);
const Z = @IntType(false, T.bit_count);
- const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1));
+ const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1));
if (a == 0) {
return T(0.0);
@@ -23,7 +23,7 @@ fn floatsiXf(comptime T: type, a: i32) T {
// Take absolute value of a via abs(x) = (x^(x >> 31)) - (x >> 31).
const abs_a = (a ^ sign) -% sign;
// The exponent is the width of abs(a)
- const exp = Z(31 - @clz(abs_a));
+ const exp = Z(31 - @clz(i32, abs_a));
const sign_bit = if (sign < 0) signBit else 0;
std/special/compiler_rt/floattidf.zig
@@ -17,7 +17,7 @@ pub extern fn __floattidf(arg: i128) f64 {
ai = ((ai ^ si) -% si);
var a = @bitCast(u128, ai);
- const sd = @bitCast(i32, N - @clz(a)); // number of significant digits
+ const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits
var e: i32 = sd - 1; // exponent
if (sd > DBL_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
std/special/compiler_rt/floattisf.zig
@@ -17,7 +17,7 @@ pub extern fn __floattisf(arg: i128) f32 {
ai = ((ai ^ si) -% si);
var a = @bitCast(u128, ai);
- const sd = @bitCast(i32, N - @clz(a)); // number of significant digits
+ const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits
var e: i32 = sd - 1; // exponent
if (sd > FLT_MANT_DIG) {
std/special/compiler_rt/floattitf.zig
@@ -17,7 +17,7 @@ pub extern fn __floattitf(arg: i128) f128 {
ai = ((ai ^ si) -% si);
var a = @bitCast(u128, ai);
- const sd = @bitCast(i32, N - @clz(a)); // number of significant digits
+ const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits
var e: i32 = sd - 1; // exponent
if (sd > LDBL_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
std/special/compiler_rt/floatunditf.zig
@@ -14,7 +14,7 @@ pub extern fn __floatunditf(a: u128) f128 {
const exponent_bias = (1 << (exponent_bits - 1)) - 1;
const implicit_bit = 1 << mantissa_bits;
- const exp = (u128.bit_count - 1) - @clz(a);
+ const exp = (u128.bit_count - 1) - @clz(u128, a);
const shift = mantissa_bits - @intCast(u7, exp);
var result: u128 align(16) = (a << shift) ^ implicit_bit;
std/special/compiler_rt/floatunsidf.zig
@@ -10,7 +10,7 @@ pub extern fn __floatunsidf(arg: u32) f64 {
if (arg == 0) return 0.0;
// The exponent is the width of abs(a)
- const exp = u64(31) - @clz(arg);
+ const exp = u64(31) - @clz(u32, arg);
// Shift a into the significand field and clear the implicit bit
const shift = @intCast(u6, 52 - exp);
const mant = u64(arg) << shift ^ implicitBit;
std/special/compiler_rt/floatunsitf.zig
@@ -14,7 +14,7 @@ pub extern fn __floatunsitf(a: u64) f128 {
const exponent_bias = (1 << (exponent_bits - 1)) - 1;
const implicit_bit = 1 << mantissa_bits;
- const exp = (u64.bit_count - 1) - @clz(a);
+ const exp = (u64.bit_count - 1) - @clz(u64, a);
const shift = mantissa_bits - @intCast(u7, exp);
// TODO(#1148): @bitCast alignment error
std/special/compiler_rt/floatuntidf.zig
@@ -13,7 +13,7 @@ pub extern fn __floatuntidf(arg: u128) f64 {
var a = arg;
const N: u32 = @sizeOf(u128) * 8;
- const sd = @bitCast(i32, N - @clz(a)); // number of significant digits
+ const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits
var e: i32 = sd - 1; // exponent
if (sd > DBL_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
std/special/compiler_rt/floatuntisf.zig
@@ -13,7 +13,7 @@ pub extern fn __floatuntisf(arg: u128) f32 {
var a = arg;
const N: u32 = @sizeOf(u128) * 8;
- const sd = @bitCast(i32, N - @clz(a)); // number of significant digits
+ const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits
var e: i32 = sd - 1; // exponent
if (sd > FLT_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
std/special/compiler_rt/floatuntitf.zig
@@ -13,7 +13,7 @@ pub extern fn __floatuntitf(arg: u128) f128 {
var a = arg;
const N: u32 = @sizeOf(u128) * 8;
- const sd = @bitCast(i32, N - @clz(a)); // number of significant digits
+ const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits
var e: i32 = sd - 1; // exponent
if (sd > LDBL_MANT_DIG) {
// start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx
std/special/compiler_rt/mulXf3.zig
@@ -260,7 +260,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {
const significandBits = std.math.floatMantissaBits(T);
const implicitBit = Z(1) << significandBits;
- const shift = @clz(significand.*) - @clz(implicitBit);
+ const shift = @clz(Z, significand.*) - @clz(Z, implicitBit);
significand.* <<= @intCast(std.math.Log2Int(Z), shift);
return 1 - shift;
}
std/special/compiler_rt/udivmod.zig
@@ -71,12 +71,12 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
r[high] = n[high] & (d[high] - 1);
rem.* = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421
}
- return n[high] >> @intCast(Log2SingleInt, @ctz(d[high]));
+ return n[high] >> @intCast(Log2SingleInt, @ctz(SingleInt, d[high]));
}
// K K
// ---
// K 0
- sr = @bitCast(c_uint, c_int(@clz(d[high])) - c_int(@clz(n[high])));
+ sr = @bitCast(c_uint, c_int(@clz(SingleInt, d[high])) - c_int(@clz(SingleInt, n[high])));
// 0 <= sr <= SingleInt.bit_count - 2 or sr large
if (sr > SingleInt.bit_count - 2) {
if (maybe_rem) |rem| {
@@ -106,7 +106,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
if (d[low] == 1) {
return a;
}
- sr = @ctz(d[low]);
+ sr = @ctz(SingleInt, d[low]);
q[high] = n[high] >> @intCast(Log2SingleInt, sr);
q[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr));
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:
// K X
// ---
// 0 K
- sr = 1 + SingleInt.bit_count + c_uint(@clz(d[low])) - c_uint(@clz(n[high]));
+ sr = 1 + SingleInt.bit_count + c_uint(@clz(SingleInt, d[low])) - c_uint(@clz(SingleInt, n[high]));
// 2 <= sr <= DoubleInt.bit_count - 1
// q.all = a << (DoubleInt.bit_count - sr);
// r.all = a >> sr;
@@ -140,7 +140,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem:
// K X
// ---
// K K
- sr = @bitCast(c_uint, c_int(@clz(d[high])) - c_int(@clz(n[high])));
+ sr = @bitCast(c_uint, c_int(@clz(SingleInt, d[high])) - c_int(@clz(SingleInt, n[high])));
// 0 <= sr <= SingleInt.bit_count - 1 or sr large
if (sr > SingleInt.bit_count - 1) {
if (maybe_rem) |rem| {
std/special/compiler_rt.zig
@@ -19,7 +19,6 @@ comptime {
@export("__getf2", @import("compiler_rt/comparetf2.zig").__getf2, linkage);
if (!is_test) {
- // only create these aliases when not testing
@export("__cmpsf2", @import("compiler_rt/comparesf2.zig").__lesf2, linkage);
@export("__cmpdf2", @import("compiler_rt/comparedf2.zig").__ledf2, linkage);
@export("__cmptf2", @import("compiler_rt/comparetf2.zig").__letf2, linkage);
@@ -599,7 +598,7 @@ extern fn __udivsi3(n: u32, d: u32) u32 {
// special cases
if (d == 0) return 0; // ?!
if (n == 0) return 0;
- var sr = @bitCast(c_uint, c_int(@clz(d)) - c_int(@clz(n)));
+ var sr = @bitCast(c_uint, c_int(@clz(u32, d)) - c_int(@clz(u32, n)));
// 0 <= sr <= n_uword_bits - 1 or sr large
if (sr > n_uword_bits - 1) {
// d > r
std/heap.zig
@@ -894,7 +894,7 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo
const large_align = u29(os.page_size << 2);
var align_mask: usize = undefined;
- _ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(large_align)), &align_mask);
+ _ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(u29, large_align)), &align_mask);
var slice = try allocator.alignedAlloc(u8, large_align, 500);
testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr));
std/math.zig
@@ -698,7 +698,7 @@ test "math.floorPowerOfTwo" {
pub fn log2_int(comptime T: type, x: T) Log2Int(T) {
assert(x != 0);
- return @intCast(Log2Int(T), T.bit_count - 1 - @clz(x));
+ return @intCast(Log2Int(T), T.bit_count - 1 - @clz(T, x));
}
pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) {
std/mem.zig
@@ -513,7 +513,7 @@ pub fn readIntNative(comptime T: type, bytes: *const [@divExact(T.bit_count, 8)]
/// This function cannot fail and cannot cause undefined behavior.
/// Assumes the endianness of memory is foreign, so it must byte-swap.
pub fn readIntForeign(comptime T: type, bytes: *const [@divExact(T.bit_count, 8)]u8) T {
- return @bswap(T, readIntNative(T, bytes));
+ return @byteSwap(T, readIntNative(T, bytes));
}
pub const readIntLittle = switch (builtin.endian) {
@@ -543,7 +543,7 @@ pub fn readIntSliceNative(comptime T: type, bytes: []const u8) T {
/// The bit count of T must be evenly divisible by 8.
/// Assumes the endianness of memory is foreign, so it must byte-swap.
pub fn readIntSliceForeign(comptime T: type, bytes: []const u8) T {
- return @bswap(T, readIntSliceNative(T, bytes));
+ return @byteSwap(T, readIntSliceNative(T, bytes));
}
pub const readIntSliceLittle = switch (builtin.endian) {
@@ -624,9 +624,9 @@ pub fn writeIntNative(comptime T: type, buf: *[(T.bit_count + 7) / 8]u8, value:
/// Writes an integer to memory, storing it in twos-complement.
/// This function always succeeds, has defined behavior for all inputs, but
/// the integer bit width must be divisible by 8.
-/// This function stores in foreign endian, which means it does a @bswap first.
+/// This function stores in foreign endian, which means it does a @byteSwap first.
pub fn writeIntForeign(comptime T: type, buf: *[@divExact(T.bit_count, 8)]u8, value: T) void {
- writeIntNative(T, buf, @bswap(T, value));
+ writeIntNative(T, buf, @byteSwap(T, value));
}
pub const writeIntLittle = switch (builtin.endian) {
@@ -1229,14 +1229,14 @@ test "std.mem.rotate" {
pub fn littleToNative(comptime T: type, x: T) T {
return switch (builtin.endian) {
builtin.Endian.Little => x,
- builtin.Endian.Big => @bswap(T, x),
+ builtin.Endian.Big => @byteSwap(T, x),
};
}
/// Converts a big-endian integer to host endianness.
pub fn bigToNative(comptime T: type, x: T) T {
return switch (builtin.endian) {
- builtin.Endian.Little => @bswap(T, x),
+ builtin.Endian.Little => @byteSwap(T, x),
builtin.Endian.Big => x,
};
}
@@ -1261,14 +1261,14 @@ pub fn nativeTo(comptime T: type, x: T, desired_endianness: builtin.Endian) T {
pub fn nativeToLittle(comptime T: type, x: T) T {
return switch (builtin.endian) {
builtin.Endian.Little => x,
- builtin.Endian.Big => @bswap(T, x),
+ builtin.Endian.Big => @byteSwap(T, x),
};
}
/// Converts an integer which has host endianness to big endian.
pub fn nativeToBig(comptime T: type, x: T) T {
return switch (builtin.endian) {
- builtin.Endian.Little => @bswap(T, x),
+ builtin.Endian.Little => @byteSwap(T, x),
builtin.Endian.Big => x,
};
}
std/os.zig
@@ -3377,7 +3377,7 @@ pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize {
const result = set[0 .. rc / @sizeOf(usize)];
var sum: usize = 0;
for (result) |x| {
- sum += @popCount(x);
+ sum += @popCount(usize, x);
}
return sum;
} else {
std/packed_int_array.zig
@@ -66,7 +66,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type {
const value_ptr = @ptrCast(*align(1) const Container, &bytes[start_byte]);
var value = value_ptr.*;
- if (endian != builtin.endian) value = @bswap(Container, value);
+ if (endian != builtin.endian) value = @byteSwap(Container, value);
switch (endian) {
.Big => {
@@ -114,7 +114,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type {
const target_ptr = @ptrCast(*align(1) Container, &bytes[start_byte]);
var target = target_ptr.*;
- if (endian != builtin.endian) target = @bswap(Container, target);
+ if (endian != builtin.endian) target = @byteSwap(Container, target);
//zero the bits we want to replace in the existing bytes
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 {
//merge the new value
target |= value;
- if (endian != builtin.endian) target = @bswap(Container, target);
+ if (endian != builtin.endian) target = @byteSwap(Container, target);
//save it back
target_ptr.* = target;
test/stage1/behavior/bugs/2114.zig
@@ -3,7 +3,7 @@ const expect = std.testing.expect;
const math = std.math;
fn ctz(x: var) usize {
- return @ctz(x);
+ return @ctz(u128, x);
}
test "fixed" {
test/stage1/behavior/bitreverse.zig
@@ -2,80 +2,68 @@ const std = @import("std");
const expect = std.testing.expect;
const minInt = std.math.minInt;
-test "@bitreverse" {
+test "@bitReverse" {
comptime testBitReverse();
testBitReverse();
}
fn testBitReverse() void {
// using comptime_ints, unsigned
- expect(@bitreverse(u0, 0) == 0);
- expect(@bitreverse(u5, 0x12) == 0x9);
- expect(@bitreverse(u8, 0x12) == 0x48);
- expect(@bitreverse(u16, 0x1234) == 0x2c48);
- expect(@bitreverse(u24, 0x123456) == 0x6a2c48);
- expect(@bitreverse(u32, 0x12345678) == 0x1e6a2c48);
- expect(@bitreverse(u40, 0x123456789a) == 0x591e6a2c48);
- expect(@bitreverse(u48, 0x123456789abc) == 0x3d591e6a2c48);
- expect(@bitreverse(u56, 0x123456789abcde) == 0x7b3d591e6a2c48);
- expect(@bitreverse(u64, 0x123456789abcdef1) == 0x8f7b3d591e6a2c48);
- expect(@bitreverse(u128, 0x123456789abcdef11121314151617181) == 0x818e868a828c84888f7b3d591e6a2c48);
+ expect(@bitReverse(u0, u0(0)) == 0);
+ expect(@bitReverse(u5, u5(0x12)) == 0x9);
+ expect(@bitReverse(u8, u8(0x12)) == 0x48);
+ expect(@bitReverse(u16, u16(0x1234)) == 0x2c48);
+ expect(@bitReverse(u24, u24(0x123456)) == 0x6a2c48);
+ expect(@bitReverse(u32, u32(0x12345678)) == 0x1e6a2c48);
+ expect(@bitReverse(u40, u40(0x123456789a)) == 0x591e6a2c48);
+ expect(@bitReverse(u48, u48(0x123456789abc)) == 0x3d591e6a2c48);
+ expect(@bitReverse(u56, u56(0x123456789abcde)) == 0x7b3d591e6a2c48);
+ expect(@bitReverse(u64, u64(0x123456789abcdef1)) == 0x8f7b3d591e6a2c48);
+ expect(@bitReverse(u128, u128(0x123456789abcdef11121314151617181)) == 0x818e868a828c84888f7b3d591e6a2c48);
// using runtime uints, unsigned
var num0: u0 = 0;
- expect(@bitreverse(u0, num0) == 0);
+ expect(@bitReverse(u0, num0) == 0);
var num5: u5 = 0x12;
- expect(@bitreverse(u5, num5) == 0x9);
+ expect(@bitReverse(u5, num5) == 0x9);
var num8: u8 = 0x12;
- expect(@bitreverse(u8, num8) == 0x48);
+ expect(@bitReverse(u8, num8) == 0x48);
var num16: u16 = 0x1234;
- expect(@bitreverse(u16, num16) == 0x2c48);
+ expect(@bitReverse(u16, num16) == 0x2c48);
var num24: u24 = 0x123456;
- expect(@bitreverse(u24, num24) == 0x6a2c48);
+ expect(@bitReverse(u24, num24) == 0x6a2c48);
var num32: u32 = 0x12345678;
- expect(@bitreverse(u32, num32) == 0x1e6a2c48);
+ expect(@bitReverse(u32, num32) == 0x1e6a2c48);
var num40: u40 = 0x123456789a;
- expect(@bitreverse(u40, num40) == 0x591e6a2c48);
+ expect(@bitReverse(u40, num40) == 0x591e6a2c48);
var num48: u48 = 0x123456789abc;
- expect(@bitreverse(u48, num48) == 0x3d591e6a2c48);
+ expect(@bitReverse(u48, num48) == 0x3d591e6a2c48);
var num56: u56 = 0x123456789abcde;
- expect(@bitreverse(u56, num56) == 0x7b3d591e6a2c48);
+ expect(@bitReverse(u56, num56) == 0x7b3d591e6a2c48);
var num64: u64 = 0x123456789abcdef1;
- expect(@bitreverse(u64, num64) == 0x8f7b3d591e6a2c48);
+ expect(@bitReverse(u64, num64) == 0x8f7b3d591e6a2c48);
var num128: u128 = 0x123456789abcdef11121314151617181;
- expect(@bitreverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48);
+ expect(@bitReverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48);
// using comptime_ints, signed, positive
- expect(@bitreverse(i0, 0) == 0);
- expect(@bitreverse(i8, @bitCast(i8, u8(0x92))) == @bitCast(i8, u8(0x49)));
- expect(@bitreverse(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x2c48)));
- expect(@bitreverse(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x6a2c48)));
- expect(@bitreverse(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x1e6a2c48)));
- expect(@bitreverse(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x591e6a2c48)));
- expect(@bitreverse(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0x3d591e6a2c48)));
- expect(@bitreverse(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0x7b3d591e6a2c48)));
- expect(@bitreverse(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0x8f7b3d591e6a2c48)));
- expect(@bitreverse(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == @bitCast(i128, u128(0x818e868a828c84888f7b3d591e6a2c48)));
+ expect(@bitReverse(u8, u8(0)) == 0);
+ expect(@bitReverse(i8, @bitCast(i8, u8(0x92))) == @bitCast(i8, u8(0x49)));
+ expect(@bitReverse(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x2c48)));
+ expect(@bitReverse(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x6a2c48)));
+ expect(@bitReverse(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x1e6a2c48)));
+ expect(@bitReverse(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x591e6a2c48)));
+ expect(@bitReverse(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0x3d591e6a2c48)));
+ expect(@bitReverse(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0x7b3d591e6a2c48)));
+ expect(@bitReverse(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0x8f7b3d591e6a2c48)));
+ expect(@bitReverse(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == @bitCast(i128, u128(0x818e868a828c84888f7b3d591e6a2c48)));
- // using comptime_ints, signed, negative. Compare to runtime ints returned from llvm.
- var neg5: i5 = minInt(i5) + 1;
- expect(@bitreverse(i5, minInt(i5) + 1) == @bitreverse(i5, neg5));
+ // using signed, negative. Compare to runtime ints returned from llvm.
var neg8: i8 = -18;
- expect(@bitreverse(i8, -18) == @bitreverse(i8, neg8));
+ expect(@bitReverse(i8, i8(-18)) == @bitReverse(i8, neg8));
var neg16: i16 = -32694;
- expect(@bitreverse(i16, -32694) == @bitreverse(i16, neg16));
+ expect(@bitReverse(i16, i16(-32694)) == @bitReverse(i16, neg16));
var neg24: i24 = -6773785;
- expect(@bitreverse(i24, -6773785) == @bitreverse(i24, neg24));
+ expect(@bitReverse(i24, i24(-6773785)) == @bitReverse(i24, neg24));
var neg32: i32 = -16773785;
- expect(@bitreverse(i32, -16773785) == @bitreverse(i32, neg32));
- var neg40: i40 = minInt(i40) + 12345;
- expect(@bitreverse(i40, minInt(i40) + 12345) == @bitreverse(i40, neg40));
- var neg48: i48 = minInt(i48) + 12345;
- expect(@bitreverse(i48, minInt(i48) + 12345) == @bitreverse(i48, neg48));
- var neg56: i56 = minInt(i56) + 12345;
- expect(@bitreverse(i56, minInt(i56) + 12345) == @bitreverse(i56, neg56));
- var neg64: i64 = minInt(i64) + 12345;
- expect(@bitreverse(i64, minInt(i64) + 12345) == @bitreverse(i64, neg64));
- var neg128: i128 = minInt(i128) + 12345;
- expect(@bitreverse(i128, minInt(i128) + 12345) == @bitreverse(i128, neg128));
+ expect(@bitReverse(i32, i32(-16773785)) == @bitReverse(i32, neg32));
}
test/stage1/behavior/bswap.zig
@@ -1,32 +0,0 @@
-const std = @import("std");
-const expect = std.testing.expect;
-
-test "@bswap" {
- comptime testByteSwap();
- testByteSwap();
-}
-
-fn testByteSwap() void {
- expect(@bswap(u0, 0) == 0);
- expect(@bswap(u8, 0x12) == 0x12);
- expect(@bswap(u16, 0x1234) == 0x3412);
- expect(@bswap(u24, 0x123456) == 0x563412);
- expect(@bswap(u32, 0x12345678) == 0x78563412);
- expect(@bswap(u40, 0x123456789a) == 0x9a78563412);
- expect(@bswap(u48, 0x123456789abc) == 0xbc9a78563412);
- expect(@bswap(u56, 0x123456789abcde) == 0xdebc9a78563412);
- expect(@bswap(u64, 0x123456789abcdef1) == 0xf1debc9a78563412);
- expect(@bswap(u128, 0x123456789abcdef11121314151617181) == 0x8171615141312111f1debc9a78563412);
-
- expect(@bswap(i0, 0) == 0);
- expect(@bswap(i8, -50) == -50);
- expect(@bswap(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x3412)));
- expect(@bswap(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x563412)));
- expect(@bswap(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x78563412)));
- expect(@bswap(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x9a78563412)));
- expect(@bswap(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0xbc9a78563412)));
- expect(@bswap(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0xdebc9a78563412)));
- expect(@bswap(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0xf1debc9a78563412)));
- expect(@bswap(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) ==
- @bitCast(i128, u128(0x8171615141312111f1debc9a78563412)));
-}
test/stage1/behavior/byteswap.zig
@@ -0,0 +1,32 @@
+const std = @import("std");
+const expect = std.testing.expect;
+
+test "@byteSwap" {
+ comptime testByteSwap();
+ testByteSwap();
+}
+
+fn testByteSwap() void {
+ expect(@byteSwap(u0, u0(0)) == 0);
+ expect(@byteSwap(u8, u8(0x12)) == 0x12);
+ expect(@byteSwap(u16, u16(0x1234)) == 0x3412);
+ expect(@byteSwap(u24, u24(0x123456)) == 0x563412);
+ expect(@byteSwap(u32, u32(0x12345678)) == 0x78563412);
+ expect(@byteSwap(u40, u40(0x123456789a)) == 0x9a78563412);
+ expect(@byteSwap(i48, u48(0x123456789abc)) == @bitCast(i48, u48(0xbc9a78563412)));
+ expect(@byteSwap(u56, u56(0x123456789abcde)) == 0xdebc9a78563412);
+ expect(@byteSwap(u64, u64(0x123456789abcdef1)) == 0xf1debc9a78563412);
+ expect(@byteSwap(u128, u128(0x123456789abcdef11121314151617181)) == 0x8171615141312111f1debc9a78563412);
+
+ expect(@byteSwap(u0, u0(0)) == 0);
+ expect(@byteSwap(i8, i8(-50)) == -50);
+ expect(@byteSwap(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x3412)));
+ expect(@byteSwap(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x563412)));
+ expect(@byteSwap(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x78563412)));
+ expect(@byteSwap(u40, @bitCast(i40, u40(0x123456789a))) == u40(0x9a78563412));
+ expect(@byteSwap(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0xbc9a78563412)));
+ expect(@byteSwap(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0xdebc9a78563412)));
+ expect(@byteSwap(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0xf1debc9a78563412)));
+ expect(@byteSwap(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) ==
+ @bitCast(i128, u128(0x8171615141312111f1debc9a78563412)));
+}
test/stage1/behavior/math.zig
@@ -114,15 +114,16 @@ test "@clz" {
}
fn testClz() void {
- expect(clz(u8(0b00001010)) == 4);
- expect(clz(u8(0b10001010)) == 0);
- expect(clz(u8(0b00000000)) == 8);
- expect(clz(u128(0xffffffffffffffff)) == 64);
- expect(clz(u128(0x10000000000000000)) == 63);
+ expect(clz(u8, u8(0b10001010)) == 0);
+ expect(clz(u8, u8(0b00001010)) == 4);
+ expect(clz(u8, u8(0b00011010)) == 3);
+ expect(clz(u8, u8(0b00000000)) == 8);
+ expect(clz(u128, u128(0xffffffffffffffff)) == 64);
+ expect(clz(u128, u128(0x10000000000000000)) == 63);
}
-fn clz(x: var) usize {
- return @clz(x);
+fn clz(comptime T: type, x: T) usize {
+ return @clz(T, x);
}
test "@ctz" {
@@ -131,13 +132,25 @@ test "@ctz" {
}
fn testCtz() void {
- expect(ctz(u8(0b10100000)) == 5);
- expect(ctz(u8(0b10001010)) == 1);
- expect(ctz(u8(0b00000000)) == 8);
+ expect(ctz(u8, u8(0b10100000)) == 5);
+ expect(ctz(u8, u8(0b10001010)) == 1);
+ expect(ctz(u8, u8(0b00000000)) == 8);
+ expect(ctz(u16, u16(0b00000000)) == 16);
}
-fn ctz(x: var) usize {
- return @ctz(x);
+fn ctz(comptime T: type, x: T) usize {
+ return @ctz(T, x);
+}
+
+pub fn Log2Int(comptime T: type) type {
+ // comptime ceil log2
+ comptime var count = 0;
+ comptime var s = T.bit_count - 1;
+ inline while (s != 0) : (s >>= 1) {
+ count += 1;
+ }
+
+ return @IntType(false, count);
}
test "assignment operators" {
test/stage1/behavior/popcount.zig
@@ -6,20 +6,39 @@ test "@popCount" {
}
fn testPopCount() void {
+ {
+ var x: u32 = 0xffffffff;
+ expect(@popCount(u32, x) == 32);
+ }
+ {
+ var x: u5 = 0x1f;
+ expect(@popCount(u5, x) == 5);
+ }
{
var x: u32 = 0xaa;
- expect(@popCount(x) == 4);
+ expect(@popCount(u32, x) == 4);
}
{
var x: u32 = 0xaaaaaaaa;
- expect(@popCount(x) == 16);
+ expect(@popCount(u32, x) == 16);
+ }
+ {
+ var x: u32 = 0xaaaaaaaa;
+ expect(@popCount(u32, x) == 16);
}
{
var x: i16 = -1;
- expect(@popCount(x) == 16);
+ expect(@popCount(i16, x) == 16);
+ }
+ {
+ var x: i8 = -120;
+ expect(@popCount(i8, x) == 2);
+ }
+ comptime {
+ expect(@popCount(u8, @bitCast(u8, i8(-120))) == 2);
}
comptime {
- expect(@popCount(0b11111111000110001100010000100001000011000011100101010001) == 24);
+ expect(@popCount(i128, u128(0b11111111000110001100010000100001000011000011100101010001)) == 24);
}
}
test/stage1/behavior.zig
@@ -8,7 +8,7 @@ comptime {
_ = @import("behavior/bitcast.zig");
_ = @import("behavior/bitreverse.zig");
_ = @import("behavior/bool.zig");
- _ = @import("behavior/bswap.zig");
+ _ = @import("behavior/byteswap.zig");
_ = @import("behavior/bugs/1025.zig");
_ = @import("behavior/bugs/1076.zig");
_ = @import("behavior/bugs/1111.zig");
test/compile_errors.zig
@@ -1363,21 +1363,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.add(
"@popCount - non-integer",
\\export fn entry(x: f32) u32 {
- \\ return @popCount(x);
+ \\ return @popCount(f32, x);
\\}
,
"tmp.zig:2:22: error: expected integer type, found 'f32'",
);
- cases.add(
- "@popCount - negative comptime_int",
- \\comptime {
- \\ _ = @popCount(-1);
- \\}
- ,
- "tmp.zig:2:9: error: @popCount on negative comptime_int value -1",
- );
-
cases.addCase(x: {
const tc = cases.create(
"wrong same named struct",