diff --git a/doc/langref.html.in b/doc/langref.html.in index e5212afb9d..d578be4ba8 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -6239,8 +6239,8 @@ comptime { {#header_close#} - {#header_open|@bswap#} -
{#syntax#}@bswap(comptime T: type, value: T) T{#endsyntax#}
+ {#header_open|@byteSwap#} +
{#syntax#}@byteSwap(comptime T: type, integer: T) T{#endsyntax#}

{#syntax#}T{#endsyntax#} must be an integer type with bit count evenly divisible by 8.

Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, @@ -6248,8 +6248,8 @@ comptime {

{#header_close#} - {#header_open|@bitreverse#} -
{#syntax#}@bitreverse(comptime T: type, value: T) T{#endsyntax#}
+ {#header_open|@bitReverse#} +
{#syntax#}@bitReverse(comptime T: type, integer: T) T{#endsyntax#}

{#syntax#}T{#endsyntax#} accepts any integer type.

Reverses the bitpattern of an integer value, including the sign bit if applicable. @@ -6337,17 +6337,19 @@ comptime { {#header_close#} {#header_open|@clz#} -

{#syntax#}@clz(x: T) U{#endsyntax#}
+
{#syntax#}@clz(comptime T: type, integer: T){#endsyntax#}

- 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#}.

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

- 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#}.

{#see_also|@ctz|@popCount#} {#header_close#} @@ -6477,17 +6479,19 @@ test "main" { {#header_close#} {#header_open|@ctz#} -
{#syntax#}@ctz(x: T) U{#endsyntax#}
+
{#syntax#}@ctz(comptime T: type, integer: T){#endsyntax#}

- 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#}.

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

- 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#}.

{#see_also|@clz|@popCount#} {#header_close#} @@ -7034,10 +7038,11 @@ test "call foo" { {#header_close#} {#header_open|@popCount#} -
{#syntax#}@popCount(integer: var) var{#endsyntax#}
+
{#syntax#}@popCount(comptime T: type, integer: T){#endsyntax#}

Counts the number of bits set in an integer.

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

diff --git a/src/all_types.hpp b/src/all_types.hpp index 13df0e6f36..3b6ac32ea5 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1407,6 +1407,8 @@ enum BuiltinFnId { BuiltinFnIdCtz, BuiltinFnIdClz, BuiltinFnIdPopCount, + BuiltinFnIdBswap, + BuiltinFnIdBitReverse, BuiltinFnIdImport, BuiltinFnIdCImport, BuiltinFnIdErrName, @@ -1469,8 +1471,6 @@ enum BuiltinFnId { BuiltinFnIdErrorReturnTrace, BuiltinFnIdAtomicRmw, BuiltinFnIdAtomicLoad, - BuiltinFnIdBswap, - BuiltinFnIdBitReverse, }; struct BuiltinFnEntry { @@ -2191,6 +2191,8 @@ enum IrInstructionId { IrInstructionIdClz, IrInstructionIdCtz, IrInstructionIdPopCount, + IrInstructionIdBswap, + IrInstructionIdBitReverse, IrInstructionIdImport, IrInstructionIdCImport, IrInstructionIdCInclude, @@ -2287,8 +2289,6 @@ enum IrInstructionId { IrInstructionIdMergeErrRetTraces, IrInstructionIdMarkErrRetTracePtr, IrInstructionIdSqrt, - IrInstructionIdBswap, - IrInstructionIdBitReverse, IrInstructionIdErrSetCast, IrInstructionIdToBytes, IrInstructionIdFromBytes, @@ -2744,19 +2744,22 @@ struct IrInstructionOptionalUnwrapPtr { struct IrInstructionCtz { IrInstruction base; - IrInstruction *value; + IrInstruction *type; + IrInstruction *op; }; struct IrInstructionClz { IrInstruction base; - IrInstruction *value; + IrInstruction *type; + IrInstruction *op; }; struct IrInstructionPopCount { IrInstruction base; - IrInstruction *value; + IrInstruction *type; + IrInstruction *op; }; struct IrInstructionUnionTag { diff --git a/src/codegen.cpp b/src/codegen.cpp index 7e7c1432e9..c8903b7dbf 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -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) { diff --git a/src/ir.cpp b/src/ir.cpp index f70d5d475c..8a3fd55c7e 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -575,6 +575,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) { return IrInstructionIdPopCount; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) { + return IrInstructionIdBswap; +} + +static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) { + return IrInstructionIdBitReverse; +} + static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) { return IrInstructionIdUnionTag; } @@ -983,14 +991,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) { return IrInstructionIdSqrt; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) { - return IrInstructionIdBswap; -} - -static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) { - return IrInstructionIdBitReverse; -} - static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { return IrInstructionIdCheckRuntimeScope; } @@ -1768,29 +1768,57 @@ static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNo return &instruction->base; } -static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { +static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { IrInstructionClz *instruction = ir_build_instruction(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(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(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(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(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(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(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(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: diff --git a/src/ir_print.cpp b/src/ir_print.cpp index bf01e9479c..a922ab1a43 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -504,19 +504,61 @@ static void ir_print_optional_unwrap_ptr(IrPrint *irp, IrInstructionOptionalUnwr static void ir_print_clz(IrPrint *irp, IrInstructionClz *instruction) { fprintf(irp->f, "@clz("); - ir_print_other_instruction(irp, instruction->value); + if (instruction->type != nullptr) { + ir_print_other_instruction(irp, instruction->type); + } else { + fprintf(irp->f, "null"); + } + fprintf(irp->f, ","); + ir_print_other_instruction(irp, instruction->op); fprintf(irp->f, ")"); } static void ir_print_ctz(IrPrint *irp, IrInstructionCtz *instruction) { fprintf(irp->f, "@ctz("); - ir_print_other_instruction(irp, instruction->value); + if (instruction->type != nullptr) { + ir_print_other_instruction(irp, instruction->type); + } else { + fprintf(irp->f, "null"); + } + fprintf(irp->f, ","); + ir_print_other_instruction(irp, instruction->op); fprintf(irp->f, ")"); } static void ir_print_pop_count(IrPrint *irp, IrInstructionPopCount *instruction) { fprintf(irp->f, "@popCount("); - ir_print_other_instruction(irp, instruction->value); + if (instruction->type != nullptr) { + ir_print_other_instruction(irp, instruction->type); + } else { + fprintf(irp->f, "null"); + } + fprintf(irp->f, ","); + ir_print_other_instruction(irp, instruction->op); + fprintf(irp->f, ")"); +} + +static void ir_print_bswap(IrPrint *irp, IrInstructionBswap *instruction) { + fprintf(irp->f, "@byteSwap("); + if (instruction->type != nullptr) { + ir_print_other_instruction(irp, instruction->type); + } else { + fprintf(irp->f, "null"); + } + fprintf(irp->f, ","); + ir_print_other_instruction(irp, instruction->op); + fprintf(irp->f, ")"); +} + +static void ir_print_bit_reverse(IrPrint *irp, IrInstructionBitReverse *instruction) { + fprintf(irp->f, "@bitReverse("); + if (instruction->type != nullptr) { + ir_print_other_instruction(irp, instruction->type); + } else { + fprintf(irp->f, "null"); + } + fprintf(irp->f, ","); + ir_print_other_instruction(irp, instruction->op); fprintf(irp->f, ")"); } @@ -1411,30 +1453,6 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va } } -static void ir_print_bswap(IrPrint *irp, IrInstructionBswap *instruction) { - fprintf(irp->f, "@bswap("); - if (instruction->type != nullptr) { - ir_print_other_instruction(irp, instruction->type); - } else { - fprintf(irp->f, "null"); - } - fprintf(irp->f, ","); - ir_print_other_instruction(irp, instruction->op); - fprintf(irp->f, ")"); -} - -static void ir_print_bit_reverse(IrPrint *irp, IrInstructionBitReverse *instruction) { - fprintf(irp->f, "@bitreverse("); - if (instruction->type != nullptr) { - ir_print_other_instruction(irp, instruction->type); - } else { - fprintf(irp->f, "null"); - } - fprintf(irp->f, ","); - ir_print_other_instruction(irp, instruction->op); - fprintf(irp->f, ")"); -} - static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { ir_print_prefix(irp, instruction); switch (instruction->id) { @@ -1551,15 +1569,21 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { case IrInstructionIdOptionalUnwrapPtr: ir_print_optional_unwrap_ptr(irp, (IrInstructionOptionalUnwrapPtr *)instruction); break; - case IrInstructionIdCtz: - ir_print_ctz(irp, (IrInstructionCtz *)instruction); - break; case IrInstructionIdPopCount: ir_print_pop_count(irp, (IrInstructionPopCount *)instruction); break; case IrInstructionIdClz: ir_print_clz(irp, (IrInstructionClz *)instruction); break; + case IrInstructionIdCtz: + ir_print_ctz(irp, (IrInstructionCtz *)instruction); + break; + case IrInstructionIdBswap: + ir_print_bswap(irp, (IrInstructionBswap *)instruction); + break; + case IrInstructionIdBitReverse: + ir_print_bit_reverse(irp, (IrInstructionBitReverse *)instruction); + break; case IrInstructionIdSwitchBr: ir_print_switch_br(irp, (IrInstructionSwitchBr *)instruction); break; @@ -1869,12 +1893,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { case IrInstructionIdSqrt: ir_print_sqrt(irp, (IrInstructionSqrt *)instruction); break; - case IrInstructionIdBswap: - ir_print_bswap(irp, (IrInstructionBswap *)instruction); - break; - case IrInstructionIdBitReverse: - ir_print_bit_reverse(irp, (IrInstructionBitReverse *)instruction); - break; case IrInstructionIdAtomicLoad: ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction); break; diff --git a/std/heap.zig b/std/heap.zig index 8e3cccc365..3bbb35e65d 100644 --- a/std/heap.zig +++ b/std/heap.zig @@ -894,7 +894,7 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo const large_align = u29(os.page_size << 2); var align_mask: usize = undefined; - _ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(large_align)), &align_mask); + _ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(u29, large_align)), &align_mask); var slice = try allocator.alignedAlloc(u8, large_align, 500); testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr)); diff --git a/std/math.zig b/std/math.zig index 92373388c2..04f0d0a49a 100644 --- a/std/math.zig +++ b/std/math.zig @@ -698,7 +698,7 @@ test "math.floorPowerOfTwo" { pub fn log2_int(comptime T: type, x: T) Log2Int(T) { assert(x != 0); - return @intCast(Log2Int(T), T.bit_count - 1 - @clz(x)); + return @intCast(Log2Int(T), T.bit_count - 1 - @clz(T, x)); } pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) { diff --git a/std/math/big/int.zig b/std/math/big/int.zig index beac3c85fe..008780b228 100644 --- a/std/math/big/int.zig +++ b/std/math/big/int.zig @@ -207,7 +207,7 @@ pub const Int = struct { /// Returns the number of bits required to represent the absolute value an Int. fn bitCountAbs(self: Int) usize { - return (self.len() - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len() - 1])); + return (self.len() - 1) * Limb.bit_count + (Limb.bit_count - @clz(Limb, self.limbs[self.len() - 1])); } /// Returns the number of bits required to represent the integer in twos-complement form. @@ -226,9 +226,9 @@ pub const Int = struct { if (!self.isPositive()) block: { bits += 1; - if (@popCount(self.limbs[self.len() - 1]) == 1) { + if (@popCount(Limb, self.limbs[self.len() - 1]) == 1) { for (self.limbs[0 .. self.len() - 1]) |limb| { - if (@popCount(limb) != 0) { + if (@popCount(Limb, limb) != 0) { break :block; } } @@ -962,7 +962,7 @@ pub const Int = struct { defer tmp.deinit(); // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) and even - var norm_shift = @clz(y.limbs[y.len() - 1]); + var norm_shift = @clz(Limb, y.limbs[y.len() - 1]); if (norm_shift == 0 and y.isOdd()) { norm_shift = Limb.bit_count; } diff --git a/std/mem.zig b/std/mem.zig index 2407b56f07..64fe270eda 100644 --- a/std/mem.zig +++ b/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, }; } diff --git a/std/os.zig b/std/os.zig index fe97c1aa61..9b452e89ae 100644 --- a/std/os.zig +++ b/std/os.zig @@ -3377,7 +3377,7 @@ pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize { const result = set[0 .. rc / @sizeOf(usize)]; var sum: usize = 0; for (result) |x| { - sum += @popCount(x); + sum += @popCount(usize, x); } return sum; } else { diff --git a/std/packed_int_array.zig b/std/packed_int_array.zig index d4ed68c6ee..065f1becd8 100644 --- a/std/packed_int_array.zig +++ b/std/packed_int_array.zig @@ -66,7 +66,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { const value_ptr = @ptrCast(*align(1) const Container, &bytes[start_byte]); var value = value_ptr.*; - if (endian != builtin.endian) value = @bswap(Container, value); + if (endian != builtin.endian) value = @byteSwap(Container, value); switch (endian) { .Big => { @@ -114,7 +114,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { const target_ptr = @ptrCast(*align(1) Container, &bytes[start_byte]); var target = target_ptr.*; - if (endian != builtin.endian) target = @bswap(Container, target); + if (endian != builtin.endian) target = @byteSwap(Container, target); //zero the bits we want to replace in the existing bytes const inv_mask = @intCast(Container, std.math.maxInt(UnInt)) << keep_shift; @@ -124,7 +124,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { //merge the new value target |= value; - if (endian != builtin.endian) target = @bswap(Container, target); + if (endian != builtin.endian) target = @byteSwap(Container, target); //save it back target_ptr.* = target; diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig index 3f9324547e..8654507bad 100644 --- a/std/special/compiler_rt.zig +++ b/std/special/compiler_rt.zig @@ -19,7 +19,6 @@ comptime { @export("__getf2", @import("compiler_rt/comparetf2.zig").__getf2, linkage); if (!is_test) { - // only create these aliases when not testing @export("__cmpsf2", @import("compiler_rt/comparesf2.zig").__lesf2, linkage); @export("__cmpdf2", @import("compiler_rt/comparedf2.zig").__ledf2, linkage); @export("__cmptf2", @import("compiler_rt/comparetf2.zig").__letf2, linkage); @@ -599,7 +598,7 @@ extern fn __udivsi3(n: u32, d: u32) u32 { // special cases if (d == 0) return 0; // ?! if (n == 0) return 0; - var sr = @bitCast(c_uint, c_int(@clz(d)) - c_int(@clz(n))); + var sr = @bitCast(c_uint, c_int(@clz(u32, d)) - c_int(@clz(u32, n))); // 0 <= sr <= n_uword_bits - 1 or sr large if (sr > n_uword_bits - 1) { // d > r diff --git a/std/special/compiler_rt/addXf3.zig b/std/special/compiler_rt/addXf3.zig index 5852f3e50d..1654c1f08b 100644 --- a/std/special/compiler_rt/addXf3.zig +++ b/std/special/compiler_rt/addXf3.zig @@ -36,11 +36,11 @@ pub extern fn __subtf3(a: f128, b: f128) f128 { // TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154 fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { const Z = @IntType(false, T.bit_count); - const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1)); + const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1)); const significandBits = std.math.floatMantissaBits(T); const implicitBit = Z(1) << significandBits; - const shift = @clz(significand.*) - @clz(implicitBit); + const shift = @clz(@IntType(false, T.bit_count), significand.*) - @clz(Z, implicitBit); significand.* <<= @intCast(S, shift); return 1 - shift; } @@ -48,7 +48,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { // TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154 fn addXf3(comptime T: type, a: T, b: T) T { const Z = @IntType(false, T.bit_count); - const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1)); + const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1)); const typeWidth = T.bit_count; const significandBits = std.math.floatMantissaBits(T); @@ -162,7 +162,7 @@ fn addXf3(comptime T: type, a: T, b: T) T { // If partial cancellation occured, we need to left-shift the result // and adjust the exponent: if (aSignificand < implicitBit << 3) { - const shift = @intCast(i32, @clz(aSignificand)) - @intCast(i32, @clz(implicitBit << 3)); + const shift = @intCast(i32, @clz(Z, aSignificand)) - @intCast(i32, @clz(@IntType(false, T.bit_count), implicitBit << 3)); aSignificand <<= @intCast(S, shift); aExponent -= shift; } diff --git a/std/special/compiler_rt/divdf3.zig b/std/special/compiler_rt/divdf3.zig index 9039b6a461..072feaec67 100644 --- a/std/special/compiler_rt/divdf3.zig +++ b/std/special/compiler_rt/divdf3.zig @@ -318,7 +318,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { const significandBits = std.math.floatMantissaBits(T); const implicitBit = Z(1) << significandBits; - const shift = @clz(significand.*) - @clz(implicitBit); + const shift = @clz(Z, significand.*) - @clz(Z, implicitBit); significand.* <<= @intCast(std.math.Log2Int(Z), shift); return 1 - shift; } diff --git a/std/special/compiler_rt/divsf3.zig b/std/special/compiler_rt/divsf3.zig index 49215bccfb..447653fbe1 100644 --- a/std/special/compiler_rt/divsf3.zig +++ b/std/special/compiler_rt/divsf3.zig @@ -191,7 +191,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { const significandBits = std.math.floatMantissaBits(T); const implicitBit = Z(1) << significandBits; - const shift = @clz(significand.*) - @clz(implicitBit); + const shift = @clz(Z, significand.*) - @clz(Z, implicitBit); significand.* <<= @intCast(std.math.Log2Int(Z), shift); return 1 - shift; } diff --git a/std/special/compiler_rt/extendXfYf2.zig b/std/special/compiler_rt/extendXfYf2.zig index 42559784bb..1c07414ca4 100644 --- a/std/special/compiler_rt/extendXfYf2.zig +++ b/std/special/compiler_rt/extendXfYf2.zig @@ -75,7 +75,8 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t // a is denormal. // renormalize the significand and clear the leading bit, then insert // the correct adjusted exponent in the destination type. - const scale: u32 = @clz(aAbs) - @clz(src_rep_t(srcMinNormal)); + const scale: u32 = @clz(src_rep_t, aAbs) - + @clz(src_rep_t, src_rep_t(srcMinNormal)); absResult = dst_rep_t(aAbs) << @intCast(DstShift, dstSigBits - srcSigBits + scale); absResult ^= dstMinNormal; const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1; diff --git a/std/special/compiler_rt/floatsiXf.zig b/std/special/compiler_rt/floatsiXf.zig index 83b3940c1e..7e05a3ebf7 100644 --- a/std/special/compiler_rt/floatsiXf.zig +++ b/std/special/compiler_rt/floatsiXf.zig @@ -6,7 +6,7 @@ fn floatsiXf(comptime T: type, a: i32) T { @setRuntimeSafety(builtin.is_test); const Z = @IntType(false, T.bit_count); - const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1)); + const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1)); if (a == 0) { return T(0.0); @@ -23,7 +23,7 @@ fn floatsiXf(comptime T: type, a: i32) T { // Take absolute value of a via abs(x) = (x^(x >> 31)) - (x >> 31). const abs_a = (a ^ sign) -% sign; // The exponent is the width of abs(a) - const exp = Z(31 - @clz(abs_a)); + const exp = Z(31 - @clz(i32, abs_a)); const sign_bit = if (sign < 0) signBit else 0; diff --git a/std/special/compiler_rt/floattidf.zig b/std/special/compiler_rt/floattidf.zig index 1fe984c64c..42ef6df7e4 100644 --- a/std/special/compiler_rt/floattidf.zig +++ b/std/special/compiler_rt/floattidf.zig @@ -17,7 +17,7 @@ pub extern fn __floattidf(arg: i128) f64 { ai = ((ai ^ si) -% si); var a = @bitCast(u128, ai); - const sd = @bitCast(i32, N - @clz(a)); // number of significant digits + const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits var e: i32 = sd - 1; // exponent if (sd > DBL_MANT_DIG) { // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx diff --git a/std/special/compiler_rt/floattisf.zig b/std/special/compiler_rt/floattisf.zig index 57fcedcc78..f397d130ef 100644 --- a/std/special/compiler_rt/floattisf.zig +++ b/std/special/compiler_rt/floattisf.zig @@ -17,7 +17,7 @@ pub extern fn __floattisf(arg: i128) f32 { ai = ((ai ^ si) -% si); var a = @bitCast(u128, ai); - const sd = @bitCast(i32, N - @clz(a)); // number of significant digits + const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits var e: i32 = sd - 1; // exponent if (sd > FLT_MANT_DIG) { diff --git a/std/special/compiler_rt/floattitf.zig b/std/special/compiler_rt/floattitf.zig index 64a7c3aa58..b05282e293 100644 --- a/std/special/compiler_rt/floattitf.zig +++ b/std/special/compiler_rt/floattitf.zig @@ -17,7 +17,7 @@ pub extern fn __floattitf(arg: i128) f128 { ai = ((ai ^ si) -% si); var a = @bitCast(u128, ai); - const sd = @bitCast(i32, N - @clz(a)); // number of significant digits + const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits var e: i32 = sd - 1; // exponent if (sd > LDBL_MANT_DIG) { // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx diff --git a/std/special/compiler_rt/floatunditf.zig b/std/special/compiler_rt/floatunditf.zig index afc545448a..9af83a2b5d 100644 --- a/std/special/compiler_rt/floatunditf.zig +++ b/std/special/compiler_rt/floatunditf.zig @@ -14,7 +14,7 @@ pub extern fn __floatunditf(a: u128) f128 { const exponent_bias = (1 << (exponent_bits - 1)) - 1; const implicit_bit = 1 << mantissa_bits; - const exp = (u128.bit_count - 1) - @clz(a); + const exp = (u128.bit_count - 1) - @clz(u128, a); const shift = mantissa_bits - @intCast(u7, exp); var result: u128 align(16) = (a << shift) ^ implicit_bit; diff --git a/std/special/compiler_rt/floatunsidf.zig b/std/special/compiler_rt/floatunsidf.zig index db02894448..efeb4c2672 100644 --- a/std/special/compiler_rt/floatunsidf.zig +++ b/std/special/compiler_rt/floatunsidf.zig @@ -10,7 +10,7 @@ pub extern fn __floatunsidf(arg: u32) f64 { if (arg == 0) return 0.0; // The exponent is the width of abs(a) - const exp = u64(31) - @clz(arg); + const exp = u64(31) - @clz(u32, arg); // Shift a into the significand field and clear the implicit bit const shift = @intCast(u6, 52 - exp); const mant = u64(arg) << shift ^ implicitBit; diff --git a/std/special/compiler_rt/floatunsitf.zig b/std/special/compiler_rt/floatunsitf.zig index 19a5918bd0..18397f8ad0 100644 --- a/std/special/compiler_rt/floatunsitf.zig +++ b/std/special/compiler_rt/floatunsitf.zig @@ -14,7 +14,7 @@ pub extern fn __floatunsitf(a: u64) f128 { const exponent_bias = (1 << (exponent_bits - 1)) - 1; const implicit_bit = 1 << mantissa_bits; - const exp = (u64.bit_count - 1) - @clz(a); + const exp = (u64.bit_count - 1) - @clz(u64, a); const shift = mantissa_bits - @intCast(u7, exp); // TODO(#1148): @bitCast alignment error diff --git a/std/special/compiler_rt/floatuntidf.zig b/std/special/compiler_rt/floatuntidf.zig index e0e149e0ca..2cd38c7308 100644 --- a/std/special/compiler_rt/floatuntidf.zig +++ b/std/special/compiler_rt/floatuntidf.zig @@ -13,7 +13,7 @@ pub extern fn __floatuntidf(arg: u128) f64 { var a = arg; const N: u32 = @sizeOf(u128) * 8; - const sd = @bitCast(i32, N - @clz(a)); // number of significant digits + const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits var e: i32 = sd - 1; // exponent if (sd > DBL_MANT_DIG) { // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx diff --git a/std/special/compiler_rt/floatuntisf.zig b/std/special/compiler_rt/floatuntisf.zig index 35623a40fa..1b42b267d9 100644 --- a/std/special/compiler_rt/floatuntisf.zig +++ b/std/special/compiler_rt/floatuntisf.zig @@ -13,7 +13,7 @@ pub extern fn __floatuntisf(arg: u128) f32 { var a = arg; const N: u32 = @sizeOf(u128) * 8; - const sd = @bitCast(i32, N - @clz(a)); // number of significant digits + const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits var e: i32 = sd - 1; // exponent if (sd > FLT_MANT_DIG) { // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx diff --git a/std/special/compiler_rt/floatuntitf.zig b/std/special/compiler_rt/floatuntitf.zig index a34e472c88..eddcf92efd 100644 --- a/std/special/compiler_rt/floatuntitf.zig +++ b/std/special/compiler_rt/floatuntitf.zig @@ -13,7 +13,7 @@ pub extern fn __floatuntitf(arg: u128) f128 { var a = arg; const N: u32 = @sizeOf(u128) * 8; - const sd = @bitCast(i32, N - @clz(a)); // number of significant digits + const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits var e: i32 = sd - 1; // exponent if (sd > LDBL_MANT_DIG) { // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx diff --git a/std/special/compiler_rt/mulXf3.zig b/std/special/compiler_rt/mulXf3.zig index 23a72db27b..51d40ad26f 100644 --- a/std/special/compiler_rt/mulXf3.zig +++ b/std/special/compiler_rt/mulXf3.zig @@ -260,7 +260,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { const significandBits = std.math.floatMantissaBits(T); const implicitBit = Z(1) << significandBits; - const shift = @clz(significand.*) - @clz(implicitBit); + const shift = @clz(Z, significand.*) - @clz(Z, implicitBit); significand.* <<= @intCast(std.math.Log2Int(Z), shift); return 1 - shift; } diff --git a/std/special/compiler_rt/udivmod.zig b/std/special/compiler_rt/udivmod.zig index e6b4ee0482..c3066153f3 100644 --- a/std/special/compiler_rt/udivmod.zig +++ b/std/special/compiler_rt/udivmod.zig @@ -71,12 +71,12 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: r[high] = n[high] & (d[high] - 1); rem.* = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421 } - return n[high] >> @intCast(Log2SingleInt, @ctz(d[high])); + return n[high] >> @intCast(Log2SingleInt, @ctz(SingleInt, d[high])); } // K K // --- // K 0 - sr = @bitCast(c_uint, c_int(@clz(d[high])) - c_int(@clz(n[high]))); + sr = @bitCast(c_uint, c_int(@clz(SingleInt, d[high])) - c_int(@clz(SingleInt, n[high]))); // 0 <= sr <= SingleInt.bit_count - 2 or sr large if (sr > SingleInt.bit_count - 2) { if (maybe_rem) |rem| { @@ -106,7 +106,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: if (d[low] == 1) { return a; } - sr = @ctz(d[low]); + sr = @ctz(SingleInt, d[low]); q[high] = n[high] >> @intCast(Log2SingleInt, sr); q[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr)); return @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &q[0]).*; // TODO issue #421 @@ -114,7 +114,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: // K X // --- // 0 K - sr = 1 + SingleInt.bit_count + c_uint(@clz(d[low])) - c_uint(@clz(n[high])); + sr = 1 + SingleInt.bit_count + c_uint(@clz(SingleInt, d[low])) - c_uint(@clz(SingleInt, n[high])); // 2 <= sr <= DoubleInt.bit_count - 1 // q.all = a << (DoubleInt.bit_count - sr); // r.all = a >> sr; @@ -140,7 +140,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: // K X // --- // K K - sr = @bitCast(c_uint, c_int(@clz(d[high])) - c_int(@clz(n[high]))); + sr = @bitCast(c_uint, c_int(@clz(SingleInt, d[high])) - c_int(@clz(SingleInt, n[high]))); // 0 <= sr <= SingleInt.bit_count - 1 or sr large if (sr > SingleInt.bit_count - 1) { if (maybe_rem) |rem| { diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 13b48ce103..932a550eab 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -1363,21 +1363,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { cases.add( "@popCount - non-integer", \\export fn entry(x: f32) u32 { - \\ return @popCount(x); + \\ return @popCount(f32, x); \\} , "tmp.zig:2:22: error: expected integer type, found 'f32'", ); - cases.add( - "@popCount - negative comptime_int", - \\comptime { - \\ _ = @popCount(-1); - \\} - , - "tmp.zig:2:9: error: @popCount on negative comptime_int value -1", - ); - cases.addCase(x: { const tc = cases.create( "wrong same named struct", diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig index bc3be172ab..8aa885d337 100644 --- a/test/stage1/behavior.zig +++ b/test/stage1/behavior.zig @@ -8,7 +8,7 @@ comptime { _ = @import("behavior/bitcast.zig"); _ = @import("behavior/bitreverse.zig"); _ = @import("behavior/bool.zig"); - _ = @import("behavior/bswap.zig"); + _ = @import("behavior/byteswap.zig"); _ = @import("behavior/bugs/1025.zig"); _ = @import("behavior/bugs/1076.zig"); _ = @import("behavior/bugs/1111.zig"); diff --git a/test/stage1/behavior/bitreverse.zig b/test/stage1/behavior/bitreverse.zig index 3897a3eab7..2b0eb71fb6 100644 --- a/test/stage1/behavior/bitreverse.zig +++ b/test/stage1/behavior/bitreverse.zig @@ -2,80 +2,68 @@ const std = @import("std"); const expect = std.testing.expect; const minInt = std.math.minInt; -test "@bitreverse" { +test "@bitReverse" { comptime testBitReverse(); testBitReverse(); } fn testBitReverse() void { // using comptime_ints, unsigned - expect(@bitreverse(u0, 0) == 0); - expect(@bitreverse(u5, 0x12) == 0x9); - expect(@bitreverse(u8, 0x12) == 0x48); - expect(@bitreverse(u16, 0x1234) == 0x2c48); - expect(@bitreverse(u24, 0x123456) == 0x6a2c48); - expect(@bitreverse(u32, 0x12345678) == 0x1e6a2c48); - expect(@bitreverse(u40, 0x123456789a) == 0x591e6a2c48); - expect(@bitreverse(u48, 0x123456789abc) == 0x3d591e6a2c48); - expect(@bitreverse(u56, 0x123456789abcde) == 0x7b3d591e6a2c48); - expect(@bitreverse(u64, 0x123456789abcdef1) == 0x8f7b3d591e6a2c48); - expect(@bitreverse(u128, 0x123456789abcdef11121314151617181) == 0x818e868a828c84888f7b3d591e6a2c48); + expect(@bitReverse(u0, 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)); } diff --git a/test/stage1/behavior/bswap.zig b/test/stage1/behavior/bswap.zig deleted file mode 100644 index beffa0f73a..0000000000 --- a/test/stage1/behavior/bswap.zig +++ /dev/null @@ -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))); -} diff --git a/test/stage1/behavior/bugs/2114.zig b/test/stage1/behavior/bugs/2114.zig index 61ea2675b9..e266279564 100644 --- a/test/stage1/behavior/bugs/2114.zig +++ b/test/stage1/behavior/bugs/2114.zig @@ -3,7 +3,7 @@ const expect = std.testing.expect; const math = std.math; fn ctz(x: var) usize { - return @ctz(x); + return @ctz(@typeOf(x), x); } test "fixed" { diff --git a/test/stage1/behavior/byteswap.zig b/test/stage1/behavior/byteswap.zig new file mode 100644 index 0000000000..3e7c34cb85 --- /dev/null +++ b/test/stage1/behavior/byteswap.zig @@ -0,0 +1,32 @@ +const std = @import("std"); +const expect = std.testing.expect; + +test "@byteSwap" { + comptime testByteSwap(); + testByteSwap(); +} + +fn testByteSwap() void { + expect(@byteSwap(u0, 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))); +} diff --git a/test/stage1/behavior/math.zig b/test/stage1/behavior/math.zig index acbd9209df..18e7fc9dcb 100644 --- a/test/stage1/behavior/math.zig +++ b/test/stage1/behavior/math.zig @@ -114,15 +114,16 @@ test "@clz" { } fn testClz() void { - expect(clz(u8(0b00001010)) == 4); - expect(clz(u8(0b10001010)) == 0); - expect(clz(u8(0b00000000)) == 8); - expect(clz(u128(0xffffffffffffffff)) == 64); - expect(clz(u128(0x10000000000000000)) == 63); + expect(clz(u8, 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" { diff --git a/test/stage1/behavior/popcount.zig b/test/stage1/behavior/popcount.zig index 2b63284720..327bee62a1 100644 --- a/test/stage1/behavior/popcount.zig +++ b/test/stage1/behavior/popcount.zig @@ -6,20 +6,39 @@ test "@popCount" { } fn testPopCount() void { + { + var x: u32 = 0xffffffff; + expect(@popCount(u32, x) == 32); + } + { + var x: u5 = 0x1f; + expect(@popCount(u5, x) == 5); + } { var x: u32 = 0xaa; - expect(@popCount(x) == 4); + expect(@popCount(u32, x) == 4); } { var x: u32 = 0xaaaaaaaa; - expect(@popCount(x) == 16); + expect(@popCount(u32, x) == 16); + } + { + var x: u32 = 0xaaaaaaaa; + expect(@popCount(u32, x) == 16); } { var x: i16 = -1; - expect(@popCount(x) == 16); + expect(@popCount(i16, x) == 16); + } + { + var x: i8 = -120; + expect(@popCount(i8, x) == 2); } comptime { - expect(@popCount(0b11111111000110001100010000100001000011000011100101010001) == 24); + expect(@popCount(u8, @bitCast(u8, i8(-120))) == 2); + } + comptime { + expect(@popCount(i128, 0b11111111000110001100010000100001000011000011100101010001) == 24); } }