mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
Merge branch 'shawnl-builtins'
This commit is contained in:
commit
e09c05f689
@ -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>
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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) {
|
||||
|
||||
366
src/ir.cpp
366
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);
|
||||
}
|
||||
}
|
||||
@ -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:
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
16
std/mem.zig
16
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,
|
||||
};
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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| {
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
@ -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)));
|
||||
}
|
||||
@ -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" {
|
||||
|
||||
32
test/stage1/behavior/byteswap.zig
Normal file
32
test/stage1/behavior/byteswap.zig
Normal 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)));
|
||||
}
|
||||
@ -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" {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user