Merge branch 'shawnl-builtins'

This commit is contained in:
Andrew Kelley 2019-05-16 16:38:06 -04:00
commit e09c05f689
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
36 changed files with 431 additions and 421 deletions

View File

@ -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,17 +6337,19 @@ comptime {
{#header_close#}
{#header_open|@clz#}
<pre>{#syntax#}@clz(x: T) U{#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>
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#}.
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#}
@ -6477,17 +6479,19 @@ test "main" {
{#header_close#}
{#header_open|@ctz#}
<pre>{#syntax#}@ctz(x: T) U{#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>
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#}.
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#}
@ -7034,10 +7038,11 @@ test "call foo" {
{#header_close#}
{#header_open|@popCount#}
<pre>{#syntax#}@popCount(integer: var) var{#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

@ -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 {

View File

@ -4140,9 +4140,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 +4152,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 +4164,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 +5650,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 +5770,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 +7332,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 +7397,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) {

View File

@ -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);
}
}
@ -10488,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;
@ -17040,92 +17038,95 @@ 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_int_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 = 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)
return ir_const_unsigned(ira, &instruction->base, 0);
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, op);
result->value.type = return_type;
return result;
}
static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *clz_instruction) {
IrInstruction *value = clz_instruction->value->child;
if (type_is_invalid(value->value.type)) {
static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *instruction) {
ZigType *int_type = ir_resolve_int_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_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;
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)));
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)
return ir_const_unsigned(ira, &instruction->base, 0);
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, 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_int_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 = ir_implicit_cast(ira, instruction->op->child, int_type);
if (type_is_invalid(op->value.type))
return ira->codegen->invalid_instruction;
}
if (instr_is_comptime(value)) {
ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
if (!val)
if (int_type->data.integral.bit_count == 0)
return ir_const_unsigned(ira, &instruction->base, 0);
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);
}
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, 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, value);
result->value.type = get_smallest_unsigned_int_type(ira->codegen, value->value.type->data.integral.bit_count);
instruction->base.source_node, nullptr, op);
result->value.type = return_type;
return result;
}
@ -22985,45 +22986,36 @@ 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;
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->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 (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",
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);
return result;
}
if (int_type->data.integral.bit_count == 8) {
return casted_op;
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,
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;
}
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;
@ -23035,40 +23027,32 @@ 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;
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->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;
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 (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;
@ -23098,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;
}
@ -23251,6 +23235,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 +23431,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 +23605,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 +23665,6 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdCoroPromise:
case IrInstructionIdPromiseResultType:
case IrInstructionIdSqrt:
case IrInstructionIdBswap:
case IrInstructionIdBitReverse:
case IrInstructionIdAtomicLoad:
case IrInstructionIdIntCast:
case IrInstructionIdFloatCast:

View File

@ -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;

View File

@ -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));

View File

@ -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) {

View File

@ -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;
}

View File

@ -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,
};
}

View File

@ -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 {

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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| {

View File

@ -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",

View File

@ -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");

View File

@ -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, 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;
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));
}

View File

@ -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)));
}

View File

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

View File

@ -0,0 +1,32 @@
const std = @import("std");
const expect = std.testing.expect;
test "@byteSwap" {
comptime testByteSwap();
testByteSwap();
}
fn testByteSwap() void {
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);
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)));
}

View File

@ -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, 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(x: var) usize {
return @clz(x);
fn clz(comptime T: type, x: T) usize {
return @clz(T, x);
}
test "@ctz" {
@ -131,13 +132,14 @@ test "@ctz" {
}
fn testCtz() void {
expect(ctz(u8(0b10100000)) == 5);
expect(ctz(u8(0b10001010)) == 1);
expect(ctz(u8(0b00000000)) == 8);
expect(ctz(u8, 0b10100000) == 5);
expect(ctz(u8, 0b10001010) == 1);
expect(ctz(u8, 0b00000000) == 8);
expect(ctz(u16, 0b00000000) == 16);
}
fn ctz(x: var) usize {
return @ctz(x);
fn ctz(comptime T: type, x: T) usize {
return @ctz(T, x);
}
test "assignment operators" {

View File

@ -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(0b11111111000110001100010000100001000011000011100101010001) == 24);
expect(@popCount(u8, @bitCast(u8, i8(-120))) == 2);
}
comptime {
expect(@popCount(i128, 0b11111111000110001100010000100001000011000011100101010001) == 24);
}
}