fixups to the previous commit

This commit is contained in:
Andrew Kelley 2019-05-16 16:32:24 -04:00
parent 1fdb24827f
commit 80983ca1ca
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
10 changed files with 144 additions and 204 deletions

View File

@ -6337,18 +6337,19 @@ comptime {
{#header_close#}
{#header_open|@clz#}
<pre>{#syntax#}@clz(comptime T: type, integer: T) math.Log2Int(@intType(false, @typeInfo(T).Int.bits + 1)){#endsyntax#}</pre>
<pre>{#syntax#}@clz(comptime T: type, integer: T){#endsyntax#}</pre>
<p>
This function counts the number of leading zeroes in {#syntax#}x{#endsyntax#} which is an integer
type {#syntax#}T{#endsyntax#}.
This function counts the number of leading zeroes in {#syntax#}integer{#endsyntax#}.
</p>
<p>
If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#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#}.
If {#syntax#}integer{#endsyntax#} is zero, {#syntax#}@clz{#endsyntax#} returns the bit width
of integer type {#syntax#}T{#endsyntax#}.
</p>
{#see_also|@ctz|@popCount#}
{#header_close#}
@ -6478,18 +6479,19 @@ test "main" {
{#header_close#}
{#header_open|@ctz#}
<pre>{#syntax#}@ctz(comptime T: type, integer: T) math.Log2Int(@intType(false, @typeInfo(T).Int.bits + 1)){#endsyntax#}</pre>
<pre>{#syntax#}@ctz(comptime T: type, integer: T){#endsyntax#}</pre>
<p>
This function counts the number of trailing zeroes in {#syntax#}x{#endsyntax#} which is an integer
type {#syntax#}T{#endsyntax#}.
This function counts the number of trailing zeroes in {#syntax#}integer{#endsyntax#}.
</p>
<p>
If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#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#}.
If {#syntax#}integer{#endsyntax#} is zero, {#syntax#}@ctz{#endsyntax#} returns
the bit width of integer type {#syntax#}T{#endsyntax#}.
</p>
{#see_also|@clz|@popCount#}
{#header_close#}
@ -7036,10 +7038,11 @@ test "call foo" {
{#header_close#}
{#header_open|@popCount#}
<pre>{#syntax#}@popCount(comptime T: type, integer: T) math.Log2Int(@intType(false, @typeInfo(T).Int.bits + 1)){#endsyntax#}</pre>
<pre>{#syntax#}@popCount(comptime T: type, integer: T){#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#}.
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>

View File

@ -213,6 +213,15 @@ 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:
@ -326,33 +335,10 @@ 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;

View File

@ -34,7 +34,6 @@ 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);

View File

@ -4126,19 +4126,11 @@ 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[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), &param_types[0], n_args, false);
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);
LLVMValueRef fn_val = LLVMAddFunction(g->module, llvm_name, fn_type);
assert(LLVMGetIntrinsicID(fn_val));

View File

@ -10472,6 +10472,20 @@ static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) {
return const_val->data.x_type;
}
static ZigType *ir_resolve_int_type(IrAnalyze *ira, IrInstruction *type_value) {
ZigType *ty = ir_resolve_type(ira, type_value);
if (type_is_invalid(ty))
return ira->codegen->builtin_types.entry_invalid;
if (ty->id != ZigTypeIdInt) {
ir_add_error(ira, type_value,
buf_sprintf("expected integer type, found '%s'", buf_ptr(&ty->name)));
return ira->codegen->builtin_types.entry_invalid;
}
return ty;
}
static ZigType *ir_resolve_error_set_type(IrAnalyze *ira, IrInstruction *op_source, IrInstruction *type_value) {
if (type_is_invalid(type_value->value.type))
return ira->codegen->builtin_types.entry_invalid;
@ -17025,123 +17039,93 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira,
}
static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) {
ZigType *int_type = ir_resolve_type(ira, instruction->type->child);
ZigType *int_type = ir_resolve_int_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))
IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type);
if (type_is_invalid(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)
return ir_const_unsigned(ira, &instruction->base, 0);
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_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;
if (instr_is_comptime(op)) {
ConstExprValue *val = ir_resolve_const(ira, op, UndefOk);
if (val == nullptr)
return ira->codegen->invalid_instruction;
if (val->special == ConstValSpecialUndef)
return ir_const_undef(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int);
size_t result_usize = bigint_ctz(&op->value.data.x_bigint, int_type->data.integral.bit_count);
return ir_const_unsigned(ira, &instruction->base, result_usize);
}
ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count);
IrInstruction *result = ir_build_ctz(&ira->new_irb, instruction->base.scope,
instruction->base.source_node, nullptr, casted_op);
instruction->base.source_node, nullptr, 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);
ZigType *int_type = ir_resolve_int_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))
IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type);
if (type_is_invalid(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)
return ir_const_unsigned(ira, &instruction->base, 0);
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;
if (instr_is_comptime(op)) {
ConstExprValue *val = ir_resolve_const(ira, op, UndefOk);
if (val == nullptr)
return ira->codegen->invalid_instruction;
if (val->special == ConstValSpecialUndef)
return ir_const_undef(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int);
size_t result_usize = bigint_clz(&op->value.data.x_bigint, int_type->data.integral.bit_count);
return ir_const_unsigned(ira, &instruction->base, result_usize);
}
ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count);
IrInstruction *result = ir_build_clz(&ira->new_irb, instruction->base.scope,
instruction->base.source_node, nullptr, casted_op);
instruction->base.source_node, nullptr, op);
result->value.type = return_type;
return result;
}
static IrInstruction *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) {
ZigType *int_type = ir_resolve_type(ira, instruction->type->child);
ZigType *int_type = ir_resolve_int_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))
IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type);
if (type_is_invalid(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)
return ir_const_unsigned(ira, &instruction->base, 0);
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)
if (instr_is_comptime(op)) {
ConstExprValue *val = ir_resolve_const(ira, op, UndefOk);
if (val == nullptr)
return ira->codegen->invalid_instruction;
if (val->special == ConstValSpecialUndef)
return ir_const_undef(ira, &instruction->base, ira->codegen->builtin_types.entry_num_lit_int);
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);
}
size_t result = bigint_popcount_signed(&val->data.x_bigint, op->value.type->data.integral.bit_count);
size_t result = bigint_popcount_signed(&val->data.x_bigint, int_type->data.integral.bit_count);
return ir_const_unsigned(ira, &instruction->base, result);
}
ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count);
IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope,
instruction->base.source_node, nullptr, casted_op);
instruction->base.source_node, nullptr, op);
result->value.type = return_type;
return result;
}
@ -23002,21 +22986,22 @@ static IrInstruction *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstructionS
}
static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstructionBswap *instruction) {
ZigType *int_type = ir_resolve_type(ira, instruction->type->child);
ZigType *int_type = ir_resolve_int_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)));
IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type);
if (type_is_invalid(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);
return result;
}
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)
return op;
if (int_type->data.integral.bit_count % 8 != 0) {
ir_add_error(ira, instruction->op,
@ -23025,20 +23010,12 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction
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);
return result;
}
if (int_type->data.integral.bit_count == 8) {
return op;
}
if (instr_is_comptime(casted_op)) {
ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad);
if (!val)
if (instr_is_comptime(op)) {
ConstExprValue *val = ir_resolve_const(ira, op, UndefOk);
if (val == nullptr)
return ira->codegen->invalid_instruction;
if (val->special == ConstValSpecialUndef)
return ir_const_undef(ira, &instruction->base, int_type);
IrInstruction *result = ir_const(ira, &instruction->base, int_type);
size_t buf_size = int_type->data.integral.bit_count / 8;
@ -23050,26 +23027,18 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction
}
IrInstruction *result = ir_build_bswap(&ira->new_irb, instruction->base.scope,
instruction->base.source_node, nullptr, casted_op);
instruction->base.source_node, nullptr, op);
result->value.type = int_type;
return result;
}
static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstructionBitReverse *instruction) {
ZigType *int_type = ir_resolve_type(ira, instruction->type->child);
ZigType *int_type = ir_resolve_int_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))
IrInstruction *op = ir_implicit_cast(ira, instruction->op->child, int_type);
if (type_is_invalid(op->value.type))
return ira->codegen->invalid_instruction;
if (int_type->data.integral.bit_count == 0) {
@ -23078,10 +23047,12 @@ static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstr
return result;
}
if (instr_is_comptime(casted_op)) {
ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad);
if (!val)
if (instr_is_comptime(op)) {
ConstExprValue *val = ir_resolve_const(ira, op, UndefOk);
if (val == nullptr)
return ira->codegen->invalid_instruction;
if (val->special == ConstValSpecialUndef)
return ir_const_undef(ira, &instruction->base, int_type);
IrInstruction *result = ir_const(ira, &instruction->base, int_type);
size_t num_bits = int_type->data.integral.bit_count;
@ -23111,7 +23082,7 @@ static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstr
}
IrInstruction *result = ir_build_bit_reverse(&ira->new_irb, instruction->base.scope,
instruction->base.source_node, nullptr, casted_op);
instruction->base.source_node, nullptr, op);
result->value.type = int_type;
return result;
}

View File

@ -9,17 +9,17 @@ test "@bitReverse" {
fn testBitReverse() void {
// using comptime_ints, unsigned
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);
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);
// using runtime uints, unsigned
var num0: u0 = 0;

View File

@ -3,7 +3,7 @@ const expect = std.testing.expect;
const math = std.math;
fn ctz(x: var) usize {
return @ctz(u128, x);
return @ctz(@typeOf(x), x);
}
test "fixed" {

View File

@ -7,16 +7,16 @@ test "@byteSwap" {
}
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, 0) == 0);
expect(@byteSwap(u8, 0x12) == 0x12);
expect(@byteSwap(u16, 0x1234) == 0x3412);
expect(@byteSwap(u24, 0x123456) == 0x563412);
expect(@byteSwap(u32, 0x12345678) == 0x78563412);
expect(@byteSwap(u40, 0x123456789a) == 0x9a78563412);
expect(@byteSwap(i48, 0x123456789abc) == @bitCast(i48, u48(0xbc9a78563412)));
expect(@byteSwap(u56, 0x123456789abcde) == 0xdebc9a78563412);
expect(@byteSwap(u64, 0x123456789abcdef1) == 0xf1debc9a78563412);
expect(@byteSwap(u128, 0x123456789abcdef11121314151617181) == 0x8171615141312111f1debc9a78563412);
expect(@byteSwap(u0, u0(0)) == 0);
expect(@byteSwap(i8, i8(-50)) == -50);

View File

@ -114,12 +114,12 @@ test "@clz" {
}
fn testClz() void {
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);
expect(clz(u8, 0b10001010) == 0);
expect(clz(u8, 0b00001010) == 4);
expect(clz(u8, 0b00011010) == 3);
expect(clz(u8, 0b00000000) == 8);
expect(clz(u128, 0xffffffffffffffff) == 64);
expect(clz(u128, 0x10000000000000000) == 63);
}
fn clz(comptime T: type, x: T) usize {
@ -132,27 +132,16 @@ test "@ctz" {
}
fn testCtz() void {
expect(ctz(u8, u8(0b10100000)) == 5);
expect(ctz(u8, u8(0b10001010)) == 1);
expect(ctz(u8, u8(0b00000000)) == 8);
expect(ctz(u16, u16(0b00000000)) == 16);
expect(ctz(u8, 0b10100000) == 5);
expect(ctz(u8, 0b10001010) == 1);
expect(ctz(u8, 0b00000000) == 8);
expect(ctz(u16, 0b00000000) == 16);
}
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" {
var i: u32 = 0;
i += 5;

View File

@ -38,7 +38,7 @@ fn testPopCount() void {
expect(@popCount(u8, @bitCast(u8, i8(-120))) == 2);
}
comptime {
expect(@popCount(i128, u128(0b11111111000110001100010000100001000011000011100101010001)) == 24);
expect(@popCount(i128, 0b11111111000110001100010000100001000011000011100101010001) == 24);
}
}