| author | |
| committer | |
| log | 1fdb24827fb51351d5e31103069619668fae31c4 |
| tree | eccc305b5cbbdfe7e9d6cbbad945f4f32c6aa136 |
| parent | 56a905c7d16c79138b4581a84f1f844bce2f00eb |
| signature |
* `@clz`, `@ctz`, `@popCount`, `@bswap`, `@bitreverse` now
have a type parameter
* rename @bitreverse to @bitReverse
* rename @bswap to @byteSwap
Closes #2119
Closes #212038 files changed, 466 insertions(+), 396 deletions(-)
doc/langref.html.in+13-11| ... | @@ -6239,8 +6239,8 @@ comptime { | ... | @@ -6239,8 +6239,8 @@ comptime { |
| 6239 | 6239 | ||
| 6240 | {#header_close#} | 6240 | {#header_close#} |
| 6241 | 6241 | ||
| 6242 | {#header_open|@bswap#} | 6242 | {#header_open|@byteSwap#} |
| 6243 | <pre>{#syntax#}@bswap(comptime T: type, value: T) T{#endsyntax#}</pre> | 6243 | <pre>{#syntax#}@byteSwap(comptime T: type, integer: T) T{#endsyntax#}</pre> |
| 6244 | <p>{#syntax#}T{#endsyntax#} must be an integer type with bit count evenly divisible by 8.</p> | 6244 | <p>{#syntax#}T{#endsyntax#} must be an integer type with bit count evenly divisible by 8.</p> |
| 6245 | <p> | 6245 | <p> |
| 6246 | Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, | 6246 | Swaps the byte order of the integer. This converts a big endian integer to a little endian integer, |
| ... | @@ -6248,8 +6248,8 @@ comptime { | ... | @@ -6248,8 +6248,8 @@ comptime { |
| 6248 | </p> | 6248 | </p> |
| 6249 | {#header_close#} | 6249 | {#header_close#} |
| 6250 | 6250 | ||
| 6251 | {#header_open|@bitreverse#} | 6251 | {#header_open|@bitReverse#} |
| 6252 | <pre>{#syntax#}@bitreverse(comptime T: type, value: T) T{#endsyntax#}</pre> | 6252 | <pre>{#syntax#}@bitReverse(comptime T: type, integer: T) T{#endsyntax#}</pre> |
| 6253 | <p>{#syntax#}T{#endsyntax#} accepts any integer type.</p> | 6253 | <p>{#syntax#}T{#endsyntax#} accepts any integer type.</p> |
| 6254 | <p> | 6254 | <p> |
| 6255 | Reverses the bitpattern of an integer value, including the sign bit if applicable. | 6255 | Reverses the bitpattern of an integer value, including the sign bit if applicable. |
| ... | @@ -6337,14 +6337,15 @@ comptime { | ... | @@ -6337,14 +6337,15 @@ comptime { |
| 6337 | {#header_close#} | 6337 | {#header_close#} |
| 6338 | 6338 | ||
| 6339 | {#header_open|@clz#} | 6339 | {#header_open|@clz#} |
| 6340 | <pre>{#syntax#}@clz(x: T) U{#endsyntax#}</pre> | 6340 | <pre>{#syntax#}@clz(comptime T: type, integer: T) math.Log2Int(@intType(false, @typeInfo(T).Int.bits + 1)){#endsyntax#}</pre> |
| 6341 | <p> | 6341 | <p> |
| 6342 | This function counts the number of leading zeroes in {#syntax#}x{#endsyntax#} which is an integer | 6342 | This function counts the number of leading zeroes in {#syntax#}x{#endsyntax#} which is an integer |
| 6343 | type {#syntax#}T{#endsyntax#}. | 6343 | type {#syntax#}T{#endsyntax#}. |
| 6344 | </p> | 6344 | </p> |
| 6345 | <p> | 6345 | <p> |
| 6346 | The return type {#syntax#}U{#endsyntax#} is an unsigned integer with the minimum number | 6346 | If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#endsyntax#}. |
| 6347 | of bits that can represent the value {#syntax#}T.bit_count{#endsyntax#}. | 6347 | Otherwise, the return type is an unsigned integer with the minimum number |
| 6348 | of bits that can represent the bit count of the integer type. | ||
| 6348 | </p> | 6349 | </p> |
| 6349 | <p> | 6350 | <p> |
| 6350 | If {#syntax#}x{#endsyntax#} is zero, {#syntax#}@clz{#endsyntax#} returns {#syntax#}T.bit_count{#endsyntax#}. | 6351 | If {#syntax#}x{#endsyntax#} is zero, {#syntax#}@clz{#endsyntax#} returns {#syntax#}T.bit_count{#endsyntax#}. |
| ... | @@ -6477,14 +6478,15 @@ test "main" { | ... | @@ -6477,14 +6478,15 @@ test "main" { |
| 6477 | {#header_close#} | 6478 | {#header_close#} |
| 6478 | 6479 | ||
| 6479 | {#header_open|@ctz#} | 6480 | {#header_open|@ctz#} |
| 6480 | <pre>{#syntax#}@ctz(x: T) U{#endsyntax#}</pre> | 6481 | <pre>{#syntax#}@ctz(comptime T: type, integer: T) math.Log2Int(@intType(false, @typeInfo(T).Int.bits + 1)){#endsyntax#}</pre> |
| 6481 | <p> | 6482 | <p> |
| 6482 | This function counts the number of trailing zeroes in {#syntax#}x{#endsyntax#} which is an integer | 6483 | This function counts the number of trailing zeroes in {#syntax#}x{#endsyntax#} which is an integer |
| 6483 | type {#syntax#}T{#endsyntax#}. | 6484 | type {#syntax#}T{#endsyntax#}. |
| 6484 | </p> | 6485 | </p> |
| 6485 | <p> | 6486 | <p> |
| 6486 | The return type {#syntax#}U{#endsyntax#} is an unsigned integer with the minimum number | 6487 | If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#endsyntax#}. |
| 6487 | of bits that can represent the value {#syntax#}T.bit_count{#endsyntax#}. | 6488 | Otherwise, the return type is an unsigned integer with the minimum number |
| 6489 | of bits that can represent the bit count of the integer type. | ||
| 6488 | </p> | 6490 | </p> |
| 6489 | <p> | 6491 | <p> |
| 6490 | If {#syntax#}x{#endsyntax#} is zero, {#syntax#}@ctz{#endsyntax#} returns {#syntax#}T.bit_count{#endsyntax#}. | 6492 | If {#syntax#}x{#endsyntax#} is zero, {#syntax#}@ctz{#endsyntax#} returns {#syntax#}T.bit_count{#endsyntax#}. |
| ... | @@ -7034,7 +7036,7 @@ test "call foo" { | ... | @@ -7034,7 +7036,7 @@ test "call foo" { |
| 7034 | {#header_close#} | 7036 | {#header_close#} |
| 7035 | 7037 | ||
| 7036 | {#header_open|@popCount#} | 7038 | {#header_open|@popCount#} |
| 7037 | <pre>{#syntax#}@popCount(integer: var) var{#endsyntax#}</pre> | 7039 | <pre>{#syntax#}@popCount(comptime T: type, integer: T) math.Log2Int(@intType(false, @typeInfo(T).Int.bits + 1)){#endsyntax#}</pre> |
| 7038 | <p>Counts the number of bits set in an integer.</p> | 7040 | <p>Counts the number of bits set in an integer.</p> |
| 7039 | <p> | 7041 | <p> |
| 7040 | If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#endsyntax#}. | 7042 | If {#syntax#}integer{#endsyntax#} is known at {#link|comptime#}, the return type is {#syntax#}comptime_int{#endsyntax#}. |
src/all_types.hpp+10-7| ... | @@ -1407,6 +1407,8 @@ enum BuiltinFnId { | ... | @@ -1407,6 +1407,8 @@ enum BuiltinFnId { |
| 1407 | BuiltinFnIdCtz, | 1407 | BuiltinFnIdCtz, |
| 1408 | BuiltinFnIdClz, | 1408 | BuiltinFnIdClz, |
| 1409 | BuiltinFnIdPopCount, | 1409 | BuiltinFnIdPopCount, |
| 1410 | BuiltinFnIdBswap, | ||
| 1411 | BuiltinFnIdBitReverse, | ||
| 1410 | BuiltinFnIdImport, | 1412 | BuiltinFnIdImport, |
| 1411 | BuiltinFnIdCImport, | 1413 | BuiltinFnIdCImport, |
| 1412 | BuiltinFnIdErrName, | 1414 | BuiltinFnIdErrName, |
| ... | @@ -1469,8 +1471,6 @@ enum BuiltinFnId { | ... | @@ -1469,8 +1471,6 @@ enum BuiltinFnId { |
| 1469 | BuiltinFnIdErrorReturnTrace, | 1471 | BuiltinFnIdErrorReturnTrace, |
| 1470 | BuiltinFnIdAtomicRmw, | 1472 | BuiltinFnIdAtomicRmw, |
| 1471 | BuiltinFnIdAtomicLoad, | 1473 | BuiltinFnIdAtomicLoad, |
| 1472 | BuiltinFnIdBswap, | ||
| 1473 | BuiltinFnIdBitReverse, | ||
| 1474 | }; | 1474 | }; |
| 1475 | 1475 | ||
| 1476 | struct BuiltinFnEntry { | 1476 | struct BuiltinFnEntry { |
| ... | @@ -2191,6 +2191,8 @@ enum IrInstructionId { | ... | @@ -2191,6 +2191,8 @@ enum IrInstructionId { |
| 2191 | IrInstructionIdClz, | 2191 | IrInstructionIdClz, |
| 2192 | IrInstructionIdCtz, | 2192 | IrInstructionIdCtz, |
| 2193 | IrInstructionIdPopCount, | 2193 | IrInstructionIdPopCount, |
| 2194 | IrInstructionIdBswap, | ||
| 2195 | IrInstructionIdBitReverse, | ||
| 2194 | IrInstructionIdImport, | 2196 | IrInstructionIdImport, |
| 2195 | IrInstructionIdCImport, | 2197 | IrInstructionIdCImport, |
| 2196 | IrInstructionIdCInclude, | 2198 | IrInstructionIdCInclude, |
| ... | @@ -2287,8 +2289,6 @@ enum IrInstructionId { | ... | @@ -2287,8 +2289,6 @@ enum IrInstructionId { |
| 2287 | IrInstructionIdMergeErrRetTraces, | 2289 | IrInstructionIdMergeErrRetTraces, |
| 2288 | IrInstructionIdMarkErrRetTracePtr, | 2290 | IrInstructionIdMarkErrRetTracePtr, |
| 2289 | IrInstructionIdSqrt, | 2291 | IrInstructionIdSqrt, |
| 2290 | IrInstructionIdBswap, | ||
| 2291 | IrInstructionIdBitReverse, | ||
| 2292 | IrInstructionIdErrSetCast, | 2292 | IrInstructionIdErrSetCast, |
| 2293 | IrInstructionIdToBytes, | 2293 | IrInstructionIdToBytes, |
| 2294 | IrInstructionIdFromBytes, | 2294 | IrInstructionIdFromBytes, |
| ... | @@ -2744,19 +2744,22 @@ struct IrInstructionOptionalUnwrapPtr { | ... | @@ -2744,19 +2744,22 @@ struct IrInstructionOptionalUnwrapPtr { |
| 2744 | struct IrInstructionCtz { | 2744 | struct IrInstructionCtz { |
| 2745 | IrInstruction base; | 2745 | IrInstruction base; |
| 2746 | 2746 | ||
| 2747 | IrInstruction *value; | 2747 | IrInstruction *type; |
| 2748 | IrInstruction *op; | ||
| 2748 | }; | 2749 | }; |
| 2749 | 2750 | ||
| 2750 | struct IrInstructionClz { | 2751 | struct IrInstructionClz { |
| 2751 | IrInstruction base; | 2752 | IrInstruction base; |
| 2752 | 2753 | ||
| 2753 | IrInstruction *value; | 2754 | IrInstruction *type; |
| 2755 | IrInstruction *op; | ||
| 2754 | }; | 2756 | }; |
| 2755 | 2757 | ||
| 2756 | struct IrInstructionPopCount { | 2758 | struct IrInstructionPopCount { |
| 2757 | IrInstruction base; | 2759 | IrInstruction base; |
| 2758 | 2760 | ||
| 2759 | IrInstruction *value; | 2761 | IrInstruction *type; |
| 2762 | IrInstruction *op; | ||
| 2760 | }; | 2763 | }; |
| 2761 | 2764 | ||
| 2762 | struct IrInstructionUnionTag { | 2765 | struct IrInstructionUnionTag { |
src/analyze.cpp+23-9| ... | @@ -213,15 +213,6 @@ static ZigType *new_container_type_entry(CodeGen *g, ZigTypeId id, AstNode *sour | ... | @@ -213,15 +213,6 @@ static ZigType *new_container_type_entry(CodeGen *g, ZigTypeId id, AstNode *sour |
| 213 | return entry; | 213 | return entry; |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | static uint8_t bits_needed_for_unsigned(uint64_t x) { | ||
| 217 | if (x == 0) { | ||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | uint8_t base = log2_u64(x); | ||
| 221 | uint64_t upper = (((uint64_t)1) << base) - 1; | ||
| 222 | return (upper >= x) ? base : (base + 1); | ||
| 223 | } | ||
| 224 | |||
| 225 | AstNode *type_decl_node(ZigType *type_entry) { | 216 | AstNode *type_decl_node(ZigType *type_entry) { |
| 226 | switch (type_entry->id) { | 217 | switch (type_entry->id) { |
| 227 | case ZigTypeIdInvalid: | 218 | case ZigTypeIdInvalid: |
| ... | @@ -335,10 +326,33 @@ static bool is_slice(ZigType *type) { | ... | @@ -335,10 +326,33 @@ static bool is_slice(ZigType *type) { |
| 335 | return type->id == ZigTypeIdStruct && type->data.structure.is_slice; | 326 | return type->id == ZigTypeIdStruct && type->data.structure.is_slice; |
| 336 | } | 327 | } |
| 337 | 328 | ||
| 329 | static uint8_t bits_needed_for_unsigned(uint64_t x) { | ||
| 330 | if (x == 0) { | ||
| 331 | return 0; | ||
| 332 | } | ||
| 333 | uint8_t base = log2_u64(x); | ||
| 334 | uint64_t upper = (((uint64_t)1) << base) - 1; | ||
| 335 | return (upper >= x) ? base : (base + 1); | ||
| 336 | } | ||
| 337 | |||
| 338 | static uint8_t bits_needed_for_popcount_unsigned(uint64_t x) { | ||
| 339 | uint8_t count = 0; | ||
| 340 | for (uint64_t s = x;s != 0;s >>= 1) | ||
| 341 | count++; | ||
| 342 | |||
| 343 | return count; | ||
| 344 | } | ||
| 345 | |||
| 338 | ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) { | 346 | ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x) { |
| 339 | return get_int_type(g, false, bits_needed_for_unsigned(x)); | 347 | return get_int_type(g, false, bits_needed_for_unsigned(x)); |
| 340 | } | 348 | } |
| 341 | 349 | ||
| 350 | // This is not the same as above, because while shift by bit width is UB, @clz, @popCount, and @ctz | ||
| 351 | // can return bit width | ||
| 352 | ZigType *get_smallest_popcount_unsigned_int_type(CodeGen *g, uint64_t x) { | ||
| 353 | return get_int_type(g, false, bits_needed_for_popcount_unsigned(x)); | ||
| 354 | } | ||
| 355 | |||
| 342 | ZigType *get_promise_type(CodeGen *g, ZigType *result_type) { | 356 | ZigType *get_promise_type(CodeGen *g, ZigType *result_type) { |
| 343 | if (result_type != nullptr && result_type->promise_parent != nullptr) { | 357 | if (result_type != nullptr && result_type->promise_parent != nullptr) { |
| 344 | return result_type->promise_parent; | 358 | return result_type->promise_parent; |
src/analyze.hpp+1| ... | @@ -34,6 +34,7 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type); | ... | @@ -34,6 +34,7 @@ ZigType *get_slice_type(CodeGen *g, ZigType *ptr_type); |
| 34 | ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, | 34 | ZigType *get_partial_container_type(CodeGen *g, Scope *scope, ContainerKind kind, |
| 35 | AstNode *decl_node, const char *full_name, Buf *bare_name, ContainerLayout layout); | 35 | AstNode *decl_node, const char *full_name, Buf *bare_name, ContainerLayout layout); |
| 36 | ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x); | 36 | ZigType *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x); |
| 37 | ZigType *get_smallest_popcount_unsigned_int_type(CodeGen *g, uint64_t x); | ||
| 37 | ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payload_type); | 38 | ZigType *get_error_union_type(CodeGen *g, ZigType *err_set_type, ZigType *payload_type); |
| 38 | ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry); | 39 | ZigType *get_bound_fn_type(CodeGen *g, ZigFn *fn_entry); |
| 39 | ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name); | 40 | ZigType *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *full_name, Buf *bare_name); |
src/codegen.cpp+28-20| ... | @@ -4126,11 +4126,19 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI | ... | @@ -4126,11 +4126,19 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI |
| 4126 | 4126 | ||
| 4127 | char llvm_name[64]; | 4127 | char llvm_name[64]; |
| 4128 | sprintf(llvm_name, "llvm.%s.i%" PRIu32, fn_name, int_type->data.integral.bit_count); | 4128 | sprintf(llvm_name, "llvm.%s.i%" PRIu32, fn_name, int_type->data.integral.bit_count); |
| 4129 | LLVMTypeRef param_types[] = { | 4129 | LLVMTypeRef param_types[3]; |
| 4130 | get_llvm_type(g, int_type), | 4130 | switch (n_args) { |
| 4131 | LLVMInt1Type(), | 4131 | case 1: |
| 4132 | }; | 4132 | param_types[0] = get_llvm_type(g, int_type); |
| 4133 | LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, int_type), param_types, n_args, false); | 4133 | break; |
| 4134 | case 2: // clz and ctz | ||
| 4135 | param_types[0] = get_llvm_type(g, int_type); | ||
| 4136 | param_types[1] = LLVMInt1Type(); | ||
| 4137 | break; | ||
| 4138 | default: | ||
| 4139 | zig_unreachable(); | ||
| 4140 | } | ||
| 4141 | LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, int_type), &param_types[0], n_args, false); | ||
| 4134 | LLVMValueRef fn_val = LLVMAddFunction(g->module, llvm_name, fn_type); | 4142 | LLVMValueRef fn_val = LLVMAddFunction(g->module, llvm_name, fn_type); |
| 4135 | assert(LLVMGetIntrinsicID(fn_val)); | 4143 | assert(LLVMGetIntrinsicID(fn_val)); |
| 4136 | 4144 | ||
| ... | @@ -4140,9 +4148,9 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI | ... | @@ -4140,9 +4148,9 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI |
| 4140 | } | 4148 | } |
| 4141 | 4149 | ||
| 4142 | static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstructionClz *instruction) { | 4150 | static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstructionClz *instruction) { |
| 4143 | ZigType *int_type = instruction->value->value.type; | 4151 | ZigType *int_type = instruction->op->value.type; |
| 4144 | LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdClz); | 4152 | LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdClz); |
| 4145 | LLVMValueRef operand = ir_llvm_value(g, instruction->value); | 4153 | LLVMValueRef operand = ir_llvm_value(g, instruction->op); |
| 4146 | LLVMValueRef params[] { | 4154 | LLVMValueRef params[] { |
| 4147 | operand, | 4155 | operand, |
| 4148 | LLVMConstNull(LLVMInt1Type()), | 4156 | LLVMConstNull(LLVMInt1Type()), |
| ... | @@ -4152,9 +4160,9 @@ static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstru | ... | @@ -4152,9 +4160,9 @@ static LLVMValueRef ir_render_clz(CodeGen *g, IrExecutable *executable, IrInstru |
| 4152 | } | 4160 | } |
| 4153 | 4161 | ||
| 4154 | static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstructionCtz *instruction) { | 4162 | static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstructionCtz *instruction) { |
| 4155 | ZigType *int_type = instruction->value->value.type; | 4163 | ZigType *int_type = instruction->op->value.type; |
| 4156 | LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdCtz); | 4164 | LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdCtz); |
| 4157 | LLVMValueRef operand = ir_llvm_value(g, instruction->value); | 4165 | LLVMValueRef operand = ir_llvm_value(g, instruction->op); |
| 4158 | LLVMValueRef params[] { | 4166 | LLVMValueRef params[] { |
| 4159 | operand, | 4167 | operand, |
| 4160 | LLVMConstNull(LLVMInt1Type()), | 4168 | LLVMConstNull(LLVMInt1Type()), |
| ... | @@ -4164,9 +4172,9 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstru | ... | @@ -4164,9 +4172,9 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, IrExecutable *executable, IrInstru |
| 4164 | } | 4172 | } |
| 4165 | 4173 | ||
| 4166 | static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutable *executable, IrInstructionPopCount *instruction) { | 4174 | static LLVMValueRef ir_render_pop_count(CodeGen *g, IrExecutable *executable, IrInstructionPopCount *instruction) { |
| 4167 | ZigType *int_type = instruction->value->value.type; | 4175 | ZigType *int_type = instruction->op->value.type; |
| 4168 | LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount); | 4176 | LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount); |
| 4169 | LLVMValueRef operand = ir_llvm_value(g, instruction->value); | 4177 | LLVMValueRef operand = ir_llvm_value(g, instruction->op); |
| 4170 | LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, &operand, 1, ""); | 4178 | LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, &operand, 1, ""); |
| 4171 | return gen_widen_or_shorten(g, false, int_type, instruction->base.value.type, wrong_size_int); | 4179 | return gen_widen_or_shorten(g, false, int_type, instruction->base.value.type, wrong_size_int); |
| 4172 | } | 4180 | } |
| ... | @@ -5650,6 +5658,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -5650,6 +5658,10 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 5650 | return ir_render_pop_count(g, executable, (IrInstructionPopCount *)instruction); | 5658 | return ir_render_pop_count(g, executable, (IrInstructionPopCount *)instruction); |
| 5651 | case IrInstructionIdSwitchBr: | 5659 | case IrInstructionIdSwitchBr: |
| 5652 | return ir_render_switch_br(g, executable, (IrInstructionSwitchBr *)instruction); | 5660 | return ir_render_switch_br(g, executable, (IrInstructionSwitchBr *)instruction); |
| 5661 | case IrInstructionIdBswap: | ||
| 5662 | return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction); | ||
| 5663 | case IrInstructionIdBitReverse: | ||
| 5664 | return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction); | ||
| 5653 | case IrInstructionIdPhi: | 5665 | case IrInstructionIdPhi: |
| 5654 | return ir_render_phi(g, executable, (IrInstructionPhi *)instruction); | 5666 | return ir_render_phi(g, executable, (IrInstructionPhi *)instruction); |
| 5655 | case IrInstructionIdRef: | 5667 | case IrInstructionIdRef: |
| ... | @@ -5766,10 +5778,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, | ... | @@ -5766,10 +5778,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 5766 | return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction); | 5778 | return ir_render_mark_err_ret_trace_ptr(g, executable, (IrInstructionMarkErrRetTracePtr *)instruction); |
| 5767 | case IrInstructionIdSqrt: | 5779 | case IrInstructionIdSqrt: |
| 5768 | return ir_render_sqrt(g, executable, (IrInstructionSqrt *)instruction); | 5780 | return ir_render_sqrt(g, executable, (IrInstructionSqrt *)instruction); |
| 5769 | case IrInstructionIdBswap: | ||
| 5770 | return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction); | ||
| 5771 | case IrInstructionIdBitReverse: | ||
| 5772 | return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction); | ||
| 5773 | case IrInstructionIdArrayToVector: | 5781 | case IrInstructionIdArrayToVector: |
| 5774 | return ir_render_array_to_vector(g, executable, (IrInstructionArrayToVector *)instruction); | 5782 | return ir_render_array_to_vector(g, executable, (IrInstructionArrayToVector *)instruction); |
| 5775 | case IrInstructionIdVectorToArray: | 5783 | case IrInstructionIdVectorToArray: |
| ... | @@ -7332,9 +7340,11 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -7332,9 +7340,11 @@ static void define_builtin_fns(CodeGen *g) { |
| 7332 | create_builtin_fn(g, BuiltinFnIdCInclude, "cInclude", 1); | 7340 | create_builtin_fn(g, BuiltinFnIdCInclude, "cInclude", 1); |
| 7333 | create_builtin_fn(g, BuiltinFnIdCDefine, "cDefine", 2); | 7341 | create_builtin_fn(g, BuiltinFnIdCDefine, "cDefine", 2); |
| 7334 | create_builtin_fn(g, BuiltinFnIdCUndef, "cUndef", 1); | 7342 | create_builtin_fn(g, BuiltinFnIdCUndef, "cUndef", 1); |
| 7335 | create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 1); | 7343 | create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 2); |
| 7336 | create_builtin_fn(g, BuiltinFnIdClz, "clz", 1); | 7344 | create_builtin_fn(g, BuiltinFnIdClz, "clz", 2); |
| 7337 | create_builtin_fn(g, BuiltinFnIdPopCount, "popCount", 1); | 7345 | create_builtin_fn(g, BuiltinFnIdPopCount, "popCount", 2); |
| 7346 | create_builtin_fn(g, BuiltinFnIdBswap, "byteSwap", 2); | ||
| 7347 | create_builtin_fn(g, BuiltinFnIdBitReverse, "bitReverse", 2); | ||
| 7338 | create_builtin_fn(g, BuiltinFnIdImport, "import", 1); | 7348 | create_builtin_fn(g, BuiltinFnIdImport, "import", 1); |
| 7339 | create_builtin_fn(g, BuiltinFnIdCImport, "cImport", 1); | 7349 | create_builtin_fn(g, BuiltinFnIdCImport, "cImport", 1); |
| 7340 | create_builtin_fn(g, BuiltinFnIdErrName, "errorName", 1); | 7350 | create_builtin_fn(g, BuiltinFnIdErrName, "errorName", 1); |
| ... | @@ -7395,8 +7405,6 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -7395,8 +7405,6 @@ static void define_builtin_fns(CodeGen *g) { |
| 7395 | create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1); | 7405 | create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1); |
| 7396 | create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2); | 7406 | create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2); |
| 7397 | create_builtin_fn(g, BuiltinFnIdThis, "This", 0); | 7407 | create_builtin_fn(g, BuiltinFnIdThis, "This", 0); |
| 7398 | create_builtin_fn(g, BuiltinFnIdBswap, "bswap", 2); | ||
| 7399 | create_builtin_fn(g, BuiltinFnIdBitReverse, "bitreverse", 2); | ||
| 7400 | } | 7408 | } |
| 7401 | 7409 | ||
| 7402 | static const char *bool_to_str(bool b) { | 7410 | static const char *bool_to_str(bool b) { |
src/ir.cpp+172-159| ... | @@ -575,6 +575,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) { | ... | @@ -575,6 +575,14 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) { |
| 575 | return IrInstructionIdPopCount; | 575 | return IrInstructionIdPopCount; |
| 576 | } | 576 | } |
| 577 | 577 | ||
| 578 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) { | ||
| 579 | return IrInstructionIdBswap; | ||
| 580 | } | ||
| 581 | |||
| 582 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) { | ||
| 583 | return IrInstructionIdBitReverse; | ||
| 584 | } | ||
| 585 | |||
| 578 | static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) { | 586 | static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) { |
| 579 | return IrInstructionIdUnionTag; | 587 | return IrInstructionIdUnionTag; |
| 580 | } | 588 | } |
| ... | @@ -983,14 +991,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) { | ... | @@ -983,14 +991,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) { |
| 983 | return IrInstructionIdSqrt; | 991 | return IrInstructionIdSqrt; |
| 984 | } | 992 | } |
| 985 | 993 | ||
| 986 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) { | ||
| 987 | return IrInstructionIdBswap; | ||
| 988 | } | ||
| 989 | |||
| 990 | static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) { | ||
| 991 | return IrInstructionIdBitReverse; | ||
| 992 | } | ||
| 993 | |||
| 994 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { | 994 | static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { |
| 995 | return IrInstructionIdCheckRuntimeScope; | 995 | return IrInstructionIdCheckRuntimeScope; |
| 996 | } | 996 | } |
| ... | @@ -1768,29 +1768,57 @@ static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -1768,29 +1768,57 @@ static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNo |
| 1768 | return &instruction->base; | 1768 | return &instruction->base; |
| 1769 | } | 1769 | } |
| 1770 | 1770 | ||
| 1771 | static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { | 1771 | static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { |
| 1772 | IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, scope, source_node); | 1772 | IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, scope, source_node); |
| 1773 | instruction->value = value; | 1773 | instruction->type = type; |
| 1774 | instruction->op = op; | ||
| 1774 | 1775 | ||
| 1775 | ir_ref_instruction(value, irb->current_basic_block); | 1776 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); |
| 1777 | ir_ref_instruction(op, irb->current_basic_block); | ||
| 1776 | 1778 | ||
| 1777 | return &instruction->base; | 1779 | return &instruction->base; |
| 1778 | } | 1780 | } |
| 1779 | 1781 | ||
| 1780 | static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { | 1782 | static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { |
| 1781 | IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, scope, source_node); | 1783 | IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, scope, source_node); |
| 1782 | instruction->value = value; | 1784 | instruction->type = type; |
| 1785 | instruction->op = op; | ||
| 1783 | 1786 | ||
| 1784 | ir_ref_instruction(value, irb->current_basic_block); | 1787 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); |
| 1788 | ir_ref_instruction(op, irb->current_basic_block); | ||
| 1785 | 1789 | ||
| 1786 | return &instruction->base; | 1790 | return &instruction->base; |
| 1787 | } | 1791 | } |
| 1788 | 1792 | ||
| 1789 | static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { | 1793 | static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { |
| 1790 | IrInstructionPopCount *instruction = ir_build_instruction<IrInstructionPopCount>(irb, scope, source_node); | 1794 | IrInstructionPopCount *instruction = ir_build_instruction<IrInstructionPopCount>(irb, scope, source_node); |
| 1791 | instruction->value = value; | 1795 | instruction->type = type; |
| 1796 | instruction->op = op; | ||
| 1792 | 1797 | ||
| 1793 | ir_ref_instruction(value, irb->current_basic_block); | 1798 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); |
| 1799 | ir_ref_instruction(op, irb->current_basic_block); | ||
| 1800 | |||
| 1801 | return &instruction->base; | ||
| 1802 | } | ||
| 1803 | |||
| 1804 | static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { | ||
| 1805 | IrInstructionBswap *instruction = ir_build_instruction<IrInstructionBswap>(irb, scope, source_node); | ||
| 1806 | instruction->type = type; | ||
| 1807 | instruction->op = op; | ||
| 1808 | |||
| 1809 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); | ||
| 1810 | ir_ref_instruction(op, irb->current_basic_block); | ||
| 1811 | |||
| 1812 | return &instruction->base; | ||
| 1813 | } | ||
| 1814 | |||
| 1815 | static IrInstruction *ir_build_bit_reverse(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { | ||
| 1816 | IrInstructionBitReverse *instruction = ir_build_instruction<IrInstructionBitReverse>(irb, scope, source_node); | ||
| 1817 | instruction->type = type; | ||
| 1818 | instruction->op = op; | ||
| 1819 | |||
| 1820 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); | ||
| 1821 | ir_ref_instruction(op, irb->current_basic_block); | ||
| 1794 | 1822 | ||
| 1795 | return &instruction->base; | 1823 | return &instruction->base; |
| 1796 | } | 1824 | } |
| ... | @@ -2986,28 +3014,6 @@ static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *sourc | ... | @@ -2986,28 +3014,6 @@ static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *sourc |
| 2986 | return &instruction->base; | 3014 | return &instruction->base; |
| 2987 | } | 3015 | } |
| 2988 | 3016 | ||
| 2989 | static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { | ||
| 2990 | IrInstructionBswap *instruction = ir_build_instruction<IrInstructionBswap>(irb, scope, source_node); | ||
| 2991 | instruction->type = type; | ||
| 2992 | instruction->op = op; | ||
| 2993 | |||
| 2994 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); | ||
| 2995 | ir_ref_instruction(op, irb->current_basic_block); | ||
| 2996 | |||
| 2997 | return &instruction->base; | ||
| 2998 | } | ||
| 2999 | |||
| 3000 | static IrInstruction *ir_build_bit_reverse(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { | ||
| 3001 | IrInstructionBitReverse *instruction = ir_build_instruction<IrInstructionBitReverse>(irb, scope, source_node); | ||
| 3002 | instruction->type = type; | ||
| 3003 | instruction->op = op; | ||
| 3004 | |||
| 3005 | if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); | ||
| 3006 | ir_ref_instruction(op, irb->current_basic_block); | ||
| 3007 | |||
| 3008 | return &instruction->base; | ||
| 3009 | } | ||
| 3010 | |||
| 3011 | static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) { | 3017 | static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) { |
| 3012 | IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node); | 3018 | IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node); |
| 3013 | instruction->scope_is_comptime = scope_is_comptime; | 3019 | instruction->scope_is_comptime = scope_is_comptime; |
| ... | @@ -4082,36 +4088,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo | ... | @@ -4082,36 +4088,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4082 | IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value); | 4088 | IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value); |
| 4083 | return ir_lval_wrap(irb, scope, size_of, lval); | 4089 | return ir_lval_wrap(irb, scope, size_of, lval); |
| 4084 | } | 4090 | } |
| 4085 | case BuiltinFnIdCtz: | ||
| 4086 | { | ||
| 4087 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 4088 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 4089 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 4090 | return arg0_value; | ||
| 4091 | |||
| 4092 | IrInstruction *ctz = ir_build_ctz(irb, scope, node, arg0_value); | ||
| 4093 | return ir_lval_wrap(irb, scope, ctz, lval); | ||
| 4094 | } | ||
| 4095 | case BuiltinFnIdPopCount: | ||
| 4096 | { | ||
| 4097 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 4098 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 4099 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 4100 | return arg0_value; | ||
| 4101 | |||
| 4102 | IrInstruction *instr = ir_build_pop_count(irb, scope, node, arg0_value); | ||
| 4103 | return ir_lval_wrap(irb, scope, instr, lval); | ||
| 4104 | } | ||
| 4105 | case BuiltinFnIdClz: | ||
| 4106 | { | ||
| 4107 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 4108 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 4109 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 4110 | return arg0_value; | ||
| 4111 | |||
| 4112 | IrInstruction *clz = ir_build_clz(irb, scope, node, arg0_value); | ||
| 4113 | return ir_lval_wrap(irb, scope, clz, lval); | ||
| 4114 | } | ||
| 4115 | case BuiltinFnIdImport: | 4091 | case BuiltinFnIdImport: |
| 4116 | { | 4092 | { |
| 4117 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 4093 | 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 | ... | @@ -5084,21 +5060,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5084 | IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); | 5060 | IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); |
| 5085 | return ir_lval_wrap(irb, scope, result, lval); | 5061 | return ir_lval_wrap(irb, scope, result, lval); |
| 5086 | } | 5062 | } |
| 5063 | case BuiltinFnIdCtz: | ||
| 5064 | case BuiltinFnIdPopCount: | ||
| 5065 | case BuiltinFnIdClz: | ||
| 5087 | case BuiltinFnIdBswap: | 5066 | case BuiltinFnIdBswap: |
| 5088 | { | ||
| 5089 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 5090 | IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); | ||
| 5091 | if (arg0_value == irb->codegen->invalid_instruction) | ||
| 5092 | return arg0_value; | ||
| 5093 | |||
| 5094 | AstNode *arg1_node = node->data.fn_call_expr.params.at(1); | ||
| 5095 | IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); | ||
| 5096 | if (arg1_value == irb->codegen->invalid_instruction) | ||
| 5097 | return arg1_value; | ||
| 5098 | |||
| 5099 | IrInstruction *result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value); | ||
| 5100 | return ir_lval_wrap(irb, scope, result, lval); | ||
| 5101 | } | ||
| 5102 | case BuiltinFnIdBitReverse: | 5067 | case BuiltinFnIdBitReverse: |
| 5103 | { | 5068 | { |
| 5104 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | 5069 | 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 | ... | @@ -5111,7 +5076,26 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 5111 | if (arg1_value == irb->codegen->invalid_instruction) | 5076 | if (arg1_value == irb->codegen->invalid_instruction) |
| 5112 | return arg1_value; | 5077 | return arg1_value; |
| 5113 | 5078 | ||
| 5114 | IrInstruction *result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value); | 5079 | IrInstruction *result; |
| 5080 | switch (builtin_fn->id) { | ||
| 5081 | case BuiltinFnIdCtz: | ||
| 5082 | result = ir_build_ctz(irb, scope, node, arg0_value, arg1_value); | ||
| 5083 | break; | ||
| 5084 | case BuiltinFnIdPopCount: | ||
| 5085 | result = ir_build_pop_count(irb, scope, node, arg0_value, arg1_value); | ||
| 5086 | break; | ||
| 5087 | case BuiltinFnIdClz: | ||
| 5088 | result = ir_build_clz(irb, scope, node, arg0_value, arg1_value); | ||
| 5089 | break; | ||
| 5090 | case BuiltinFnIdBswap: | ||
| 5091 | result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value); | ||
| 5092 | break; | ||
| 5093 | case BuiltinFnIdBitReverse: | ||
| 5094 | result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value); | ||
| 5095 | break; | ||
| 5096 | default: | ||
| 5097 | zig_unreachable(); | ||
| 5098 | } | ||
| 5115 | return ir_lval_wrap(irb, scope, result, lval); | 5099 | return ir_lval_wrap(irb, scope, result, lval); |
| 5116 | } | 5100 | } |
| 5117 | } | 5101 | } |
| ... | @@ -17040,92 +17024,125 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, | ... | @@ -17040,92 +17024,125 @@ static IrInstruction *ir_analyze_instruction_optional_unwrap_ptr(IrAnalyze *ira, |
| 17040 | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on); | 17024 | return ir_analyze_unwrap_optional_payload(ira, &instruction->base, base_ptr, instruction->safety_check_on); |
| 17041 | } | 17025 | } |
| 17042 | 17026 | ||
| 17043 | static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *ctz_instruction) { | 17027 | static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *instruction) { |
| 17044 | IrInstruction *value = ctz_instruction->value->child; | 17028 | ZigType *int_type = ir_resolve_type(ira, instruction->type->child); |
| 17045 | if (type_is_invalid(value->value.type)) { | 17029 | if (type_is_invalid(int_type)) |
| 17046 | return ira->codegen->invalid_instruction; | 17030 | return ira->codegen->invalid_instruction; |
| 17047 | } else if (value->value.type->id == ZigTypeIdInt) { | ||
| 17048 | ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, | ||
| 17049 | value->value.type->data.integral.bit_count); | ||
| 17050 | if (value->value.special != ConstValSpecialRuntime) { | ||
| 17051 | size_t result_usize = bigint_ctz(&value->value.data.x_bigint, | ||
| 17052 | value->value.type->data.integral.bit_count); | ||
| 17053 | IrInstruction *result = ir_const(ira, &ctz_instruction->base, return_type); | ||
| 17054 | bigint_init_unsigned(&result->value.data.x_bigint, result_usize); | ||
| 17055 | return result; | ||
| 17056 | } | ||
| 17057 | 17031 | ||
| 17058 | IrInstruction *result = ir_build_ctz(&ira->new_irb, | 17032 | IrInstruction *op = instruction->op->child; |
| 17059 | ctz_instruction->base.scope, ctz_instruction->base.source_node, value); | 17033 | |
| 17060 | result->value.type = return_type; | 17034 | if (int_type->id != ZigTypeIdInt) { |
| 17061 | return result; | 17035 | ir_add_error(ira, instruction->type, |
| 17062 | } else { | 17036 | buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name))); |
| 17063 | ir_add_error_node(ira, ctz_instruction->base.source_node, | ||
| 17064 | buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); | ||
| 17065 | return ira->codegen->invalid_instruction; | 17037 | return ira->codegen->invalid_instruction; |
| 17066 | } | 17038 | } |
| 17067 | } | ||
| 17068 | 17039 | ||
| 17069 | static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *clz_instruction) { | 17040 | IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type); |
| 17070 | IrInstruction *value = clz_instruction->value->child; | 17041 | if (type_is_invalid(casted_op->value.type)) |
| 17071 | if (type_is_invalid(value->value.type)) { | ||
| 17072 | return ira->codegen->invalid_instruction; | 17042 | return ira->codegen->invalid_instruction; |
| 17073 | } else if (value->value.type->id == ZigTypeIdInt) { | ||
| 17074 | ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, | ||
| 17075 | value->value.type->data.integral.bit_count); | ||
| 17076 | if (value->value.special != ConstValSpecialRuntime) { | ||
| 17077 | size_t result_usize = bigint_clz(&value->value.data.x_bigint, | ||
| 17078 | value->value.type->data.integral.bit_count); | ||
| 17079 | IrInstruction *result = ir_const(ira, &clz_instruction->base, return_type); | ||
| 17080 | bigint_init_unsigned(&result->value.data.x_bigint, result_usize); | ||
| 17081 | return result; | ||
| 17082 | } | ||
| 17083 | 17043 | ||
| 17084 | IrInstruction *result = ir_build_clz(&ira->new_irb, | 17044 | ZigType *return_type = get_smallest_popcount_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); |
| 17085 | clz_instruction->base.scope, clz_instruction->base.source_node, value); | 17045 | |
| 17086 | result->value.type = return_type; | 17046 | if (int_type->data.integral.bit_count == 0) { |
| 17047 | IrInstruction *result = ir_const(ira, &instruction->base, return_type); | ||
| 17048 | bigint_init_unsigned(&result->value.data.x_bigint, 0); | ||
| 17087 | return result; | 17049 | return result; |
| 17088 | } else { | 17050 | } |
| 17089 | ir_add_error_node(ira, clz_instruction->base.source_node, | 17051 | |
| 17090 | buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); | 17052 | if (instr_is_comptime(casted_op)) { |
| 17053 | size_t result_usize = bigint_ctz(&op->value.data.x_bigint, | ||
| 17054 | op->value.type->data.integral.bit_count); | ||
| 17055 | IrInstruction *result = ir_const(ira, &instruction->base, return_type); | ||
| 17056 | bigint_init_unsigned(&result->value.data.x_bigint, result_usize); | ||
| 17057 | return result; | ||
| 17058 | } | ||
| 17059 | |||
| 17060 | IrInstruction *result = ir_build_ctz(&ira->new_irb, instruction->base.scope, | ||
| 17061 | instruction->base.source_node, nullptr, casted_op); | ||
| 17062 | result->value.type = return_type; | ||
| 17063 | return result; | ||
| 17064 | } | ||
| 17065 | |||
| 17066 | static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *instruction) { | ||
| 17067 | ZigType *int_type = ir_resolve_type(ira, instruction->type->child); | ||
| 17068 | if (type_is_invalid(int_type)) | ||
| 17069 | return ira->codegen->invalid_instruction; | ||
| 17070 | |||
| 17071 | IrInstruction *op = instruction->op->child; | ||
| 17072 | |||
| 17073 | if (int_type->id != ZigTypeIdInt) { | ||
| 17074 | ir_add_error(ira, instruction->type, | ||
| 17075 | buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name))); | ||
| 17091 | return ira->codegen->invalid_instruction; | 17076 | return ira->codegen->invalid_instruction; |
| 17092 | } | 17077 | } |
| 17078 | |||
| 17079 | IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type); | ||
| 17080 | if (type_is_invalid(casted_op->value.type)) | ||
| 17081 | return ira->codegen->invalid_instruction; | ||
| 17082 | |||
| 17083 | ZigType *return_type = get_smallest_popcount_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); | ||
| 17084 | |||
| 17085 | if (int_type->data.integral.bit_count == 0) { | ||
| 17086 | IrInstruction *result = ir_const(ira, &instruction->base, return_type); | ||
| 17087 | bigint_init_unsigned(&result->value.data.x_bigint, 0); | ||
| 17088 | return result; | ||
| 17089 | } | ||
| 17090 | |||
| 17091 | if (instr_is_comptime(casted_op)) { | ||
| 17092 | size_t result_usize = bigint_clz(&op->value.data.x_bigint, | ||
| 17093 | op->value.type->data.integral.bit_count); | ||
| 17094 | IrInstruction *result = ir_const(ira, &instruction->base, return_type); | ||
| 17095 | bigint_init_unsigned(&result->value.data.x_bigint, result_usize); | ||
| 17096 | return result; | ||
| 17097 | } | ||
| 17098 | |||
| 17099 | IrInstruction *result = ir_build_clz(&ira->new_irb, instruction->base.scope, | ||
| 17100 | instruction->base.source_node, nullptr, casted_op); | ||
| 17101 | result->value.type = return_type; | ||
| 17102 | return result; | ||
| 17093 | } | 17103 | } |
| 17094 | 17104 | ||
| 17095 | static IrInstruction *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) { | 17105 | static IrInstruction *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) { |
| 17096 | IrInstruction *value = instruction->value->child; | 17106 | ZigType *int_type = ir_resolve_type(ira, instruction->type->child); |
| 17097 | if (type_is_invalid(value->value.type)) | 17107 | if (type_is_invalid(int_type)) |
| 17098 | return ira->codegen->invalid_instruction; | 17108 | return ira->codegen->invalid_instruction; |
| 17099 | 17109 | ||
| 17100 | if (value->value.type->id != ZigTypeIdInt && value->value.type->id != ZigTypeIdComptimeInt) { | 17110 | IrInstruction *op = instruction->op->child; |
| 17101 | ir_add_error(ira, value, | 17111 | |
| 17102 | buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); | 17112 | if (int_type->id != ZigTypeIdInt) { |
| 17113 | ir_add_error(ira, instruction->type, | ||
| 17114 | buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name))); | ||
| 17103 | return ira->codegen->invalid_instruction; | 17115 | return ira->codegen->invalid_instruction; |
| 17104 | } | 17116 | } |
| 17105 | 17117 | ||
| 17106 | if (instr_is_comptime(value)) { | 17118 | IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type); |
| 17107 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); | 17119 | if (type_is_invalid(casted_op->value.type)) |
| 17120 | return ira->codegen->invalid_instruction; | ||
| 17121 | |||
| 17122 | ZigType *return_type = get_smallest_popcount_unsigned_int_type(ira->codegen, int_type->data.integral.bit_count); | ||
| 17123 | |||
| 17124 | if (int_type->data.integral.bit_count == 0) { | ||
| 17125 | IrInstruction *result = ir_const(ira, &instruction->base, return_type); | ||
| 17126 | bigint_init_unsigned(&result->value.data.x_bigint, 0); | ||
| 17127 | return result; | ||
| 17128 | } | ||
| 17129 | |||
| 17130 | if (instr_is_comptime(casted_op)) { | ||
| 17131 | ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad); | ||
| 17108 | if (!val) | 17132 | if (!val) |
| 17109 | return ira->codegen->invalid_instruction; | 17133 | return ira->codegen->invalid_instruction; |
| 17134 | |||
| 17110 | if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { | 17135 | if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { |
| 17111 | size_t result = bigint_popcount_unsigned(&val->data.x_bigint); | 17136 | size_t result = bigint_popcount_unsigned(&val->data.x_bigint); |
| 17112 | return ir_const_unsigned(ira, &instruction->base, result); | 17137 | return ir_const_unsigned(ira, &instruction->base, result); |
| 17113 | } | 17138 | } |
| 17114 | if (value->value.type->id == ZigTypeIdComptimeInt) { | 17139 | size_t result = bigint_popcount_signed(&val->data.x_bigint, op->value.type->data.integral.bit_count); |
| 17115 | Buf *val_buf = buf_alloc(); | ||
| 17116 | bigint_append_buf(val_buf, &val->data.x_bigint, 10); | ||
| 17117 | ir_add_error(ira, &instruction->base, | ||
| 17118 | buf_sprintf("@popCount on negative %s value %s", | ||
| 17119 | buf_ptr(&value->value.type->name), buf_ptr(val_buf))); | ||
| 17120 | return ira->codegen->invalid_instruction; | ||
| 17121 | } | ||
| 17122 | size_t result = bigint_popcount_signed(&val->data.x_bigint, value->value.type->data.integral.bit_count); | ||
| 17123 | return ir_const_unsigned(ira, &instruction->base, result); | 17140 | return ir_const_unsigned(ira, &instruction->base, result); |
| 17124 | } | 17141 | } |
| 17125 | 17142 | ||
| 17126 | IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope, | 17143 | IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope, |
| 17127 | instruction->base.source_node, value); | 17144 | instruction->base.source_node, nullptr, casted_op); |
| 17128 | result->value.type = get_smallest_unsigned_int_type(ira->codegen, value->value.type->data.integral.bit_count); | 17145 | result->value.type = return_type; |
| 17129 | return result; | 17146 | return result; |
| 17130 | } | 17147 | } |
| 17131 | 17148 | ||
| ... | @@ -22990,8 +23007,6 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction | ... | @@ -22990,8 +23007,6 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction |
| 22990 | return ira->codegen->invalid_instruction; | 23007 | return ira->codegen->invalid_instruction; |
| 22991 | 23008 | ||
| 22992 | IrInstruction *op = instruction->op->child; | 23009 | IrInstruction *op = instruction->op->child; |
| 22993 | if (type_is_invalid(op->value.type)) | ||
| 22994 | return ira->codegen->invalid_instruction; | ||
| 22995 | 23010 | ||
| 22996 | if (int_type->id != ZigTypeIdInt) { | 23011 | if (int_type->id != ZigTypeIdInt) { |
| 22997 | ir_add_error(ira, instruction->type, | 23012 | ir_add_error(ira, instruction->type, |
| ... | @@ -22999,17 +23014,17 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction | ... | @@ -22999,17 +23014,17 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction |
| 22999 | return ira->codegen->invalid_instruction; | 23014 | return ira->codegen->invalid_instruction; |
| 23000 | } | 23015 | } |
| 23001 | 23016 | ||
| 23017 | IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type); | ||
| 23018 | if (type_is_invalid(casted_op->value.type)) | ||
| 23019 | return ira->codegen->invalid_instruction; | ||
| 23020 | |||
| 23002 | if (int_type->data.integral.bit_count % 8 != 0) { | 23021 | if (int_type->data.integral.bit_count % 8 != 0) { |
| 23003 | ir_add_error(ira, instruction->type, | 23022 | ir_add_error(ira, instruction->op, |
| 23004 | buf_sprintf("@bswap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8", | 23023 | buf_sprintf("@byteSwap integer type '%s' has %" PRIu32 " bits which is not evenly divisible by 8", |
| 23005 | buf_ptr(&int_type->name), int_type->data.integral.bit_count)); | 23024 | buf_ptr(&int_type->name), int_type->data.integral.bit_count)); |
| 23006 | return ira->codegen->invalid_instruction; | 23025 | return ira->codegen->invalid_instruction; |
| 23007 | } | 23026 | } |
| 23008 | 23027 | ||
| 23009 | IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type); | ||
| 23010 | if (type_is_invalid(casted_op->value.type)) | ||
| 23011 | return ira->codegen->invalid_instruction; | ||
| 23012 | |||
| 23013 | if (int_type->data.integral.bit_count == 0) { | 23028 | if (int_type->data.integral.bit_count == 0) { |
| 23014 | IrInstruction *result = ir_const(ira, &instruction->base, int_type); | 23029 | IrInstruction *result = ir_const(ira, &instruction->base, int_type); |
| 23015 | bigint_init_unsigned(&result->value.data.x_bigint, 0); | 23030 | bigint_init_unsigned(&result->value.data.x_bigint, 0); |
| ... | @@ -23017,7 +23032,7 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction | ... | @@ -23017,7 +23032,7 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction |
| 23017 | } | 23032 | } |
| 23018 | 23033 | ||
| 23019 | if (int_type->data.integral.bit_count == 8) { | 23034 | if (int_type->data.integral.bit_count == 8) { |
| 23020 | return casted_op; | 23035 | return op; |
| 23021 | } | 23036 | } |
| 23022 | 23037 | ||
| 23023 | if (instr_is_comptime(casted_op)) { | 23038 | if (instr_is_comptime(casted_op)) { |
| ... | @@ -23046,8 +23061,6 @@ static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstr | ... | @@ -23046,8 +23061,6 @@ static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstr |
| 23046 | return ira->codegen->invalid_instruction; | 23061 | return ira->codegen->invalid_instruction; |
| 23047 | 23062 | ||
| 23048 | IrInstruction *op = instruction->op->child; | 23063 | IrInstruction *op = instruction->op->child; |
| 23049 | if (type_is_invalid(op->value.type)) | ||
| 23050 | return ira->codegen->invalid_instruction; | ||
| 23051 | 23064 | ||
| 23052 | if (int_type->id != ZigTypeIdInt) { | 23065 | if (int_type->id != ZigTypeIdInt) { |
| 23053 | ir_add_error(ira, instruction->type, | 23066 | ir_add_error(ira, instruction->type, |
| ... | @@ -23251,6 +23264,10 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23251,6 +23264,10 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23251 | return ir_analyze_instruction_ctz(ira, (IrInstructionCtz *)instruction); | 23264 | return ir_analyze_instruction_ctz(ira, (IrInstructionCtz *)instruction); |
| 23252 | case IrInstructionIdPopCount: | 23265 | case IrInstructionIdPopCount: |
| 23253 | return ir_analyze_instruction_pop_count(ira, (IrInstructionPopCount *)instruction); | 23266 | return ir_analyze_instruction_pop_count(ira, (IrInstructionPopCount *)instruction); |
| 23267 | case IrInstructionIdBswap: | ||
| 23268 | return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction); | ||
| 23269 | case IrInstructionIdBitReverse: | ||
| 23270 | return ir_analyze_instruction_bit_reverse(ira, (IrInstructionBitReverse *)instruction); | ||
| 23254 | case IrInstructionIdSwitchBr: | 23271 | case IrInstructionIdSwitchBr: |
| 23255 | return ir_analyze_instruction_switch_br(ira, (IrInstructionSwitchBr *)instruction); | 23272 | return ir_analyze_instruction_switch_br(ira, (IrInstructionSwitchBr *)instruction); |
| 23256 | case IrInstructionIdSwitchTarget: | 23273 | case IrInstructionIdSwitchTarget: |
| ... | @@ -23443,10 +23460,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio | ... | @@ -23443,10 +23460,6 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio |
| 23443 | return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); | 23460 | return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); |
| 23444 | case IrInstructionIdSqrt: | 23461 | case IrInstructionIdSqrt: |
| 23445 | return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction); | 23462 | return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction); |
| 23446 | case IrInstructionIdBswap: | ||
| 23447 | return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction); | ||
| 23448 | case IrInstructionIdBitReverse: | ||
| 23449 | return ir_analyze_instruction_bit_reverse(ira, (IrInstructionBitReverse *)instruction); | ||
| 23450 | case IrInstructionIdIntToErr: | 23463 | case IrInstructionIdIntToErr: |
| 23451 | return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); | 23464 | return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); |
| 23452 | case IrInstructionIdErrToInt: | 23465 | case IrInstructionIdErrToInt: |
| ... | @@ -23621,6 +23634,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -23621,6 +23634,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23621 | case IrInstructionIdClz: | 23634 | case IrInstructionIdClz: |
| 23622 | case IrInstructionIdCtz: | 23635 | case IrInstructionIdCtz: |
| 23623 | case IrInstructionIdPopCount: | 23636 | case IrInstructionIdPopCount: |
| 23637 | case IrInstructionIdBswap: | ||
| 23638 | case IrInstructionIdBitReverse: | ||
| 23624 | case IrInstructionIdSwitchVar: | 23639 | case IrInstructionIdSwitchVar: |
| 23625 | case IrInstructionIdSwitchElseVar: | 23640 | case IrInstructionIdSwitchElseVar: |
| 23626 | case IrInstructionIdSwitchTarget: | 23641 | case IrInstructionIdSwitchTarget: |
| ... | @@ -23679,8 +23694,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { | ... | @@ -23679,8 +23694,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 23679 | case IrInstructionIdCoroPromise: | 23694 | case IrInstructionIdCoroPromise: |
| 23680 | case IrInstructionIdPromiseResultType: | 23695 | case IrInstructionIdPromiseResultType: |
| 23681 | case IrInstructionIdSqrt: | 23696 | case IrInstructionIdSqrt: |
| 23682 | case IrInstructionIdBswap: | ||
| 23683 | case IrInstructionIdBitReverse: | ||
| 23684 | case IrInstructionIdAtomicLoad: | 23697 | case IrInstructionIdAtomicLoad: |
| 23685 | case IrInstructionIdIntCast: | 23698 | case IrInstructionIdIntCast: |
| 23686 | case IrInstructionIdFloatCast: | 23699 | case IrInstructionIdFloatCast: |
src/ir_print.cpp+54-36| ... | @@ -504,19 +504,61 @@ static void ir_print_optional_unwrap_ptr(IrPrint *irp, IrInstructionOptionalUnwr | ... | @@ -504,19 +504,61 @@ static void ir_print_optional_unwrap_ptr(IrPrint *irp, IrInstructionOptionalUnwr |
| 504 | 504 | ||
| 505 | static void ir_print_clz(IrPrint *irp, IrInstructionClz *instruction) { | 505 | static void ir_print_clz(IrPrint *irp, IrInstructionClz *instruction) { |
| 506 | fprintf(irp->f, "@clz("); | 506 | fprintf(irp->f, "@clz("); |
| 507 | ir_print_other_instruction(irp, instruction->value); | 507 | if (instruction->type != nullptr) { |
| 508 | ir_print_other_instruction(irp, instruction->type); | ||
| 509 | } else { | ||
| 510 | fprintf(irp->f, "null"); | ||
| 511 | } | ||
| 512 | fprintf(irp->f, ","); | ||
| 513 | ir_print_other_instruction(irp, instruction->op); | ||
| 508 | fprintf(irp->f, ")"); | 514 | fprintf(irp->f, ")"); |
| 509 | } | 515 | } |
| 510 | 516 | ||
| 511 | static void ir_print_ctz(IrPrint *irp, IrInstructionCtz *instruction) { | 517 | static void ir_print_ctz(IrPrint *irp, IrInstructionCtz *instruction) { |
| 512 | fprintf(irp->f, "@ctz("); | 518 | fprintf(irp->f, "@ctz("); |
| 513 | ir_print_other_instruction(irp, instruction->value); | 519 | if (instruction->type != nullptr) { |
| 520 | ir_print_other_instruction(irp, instruction->type); | ||
| 521 | } else { | ||
| 522 | fprintf(irp->f, "null"); | ||
| 523 | } | ||
| 524 | fprintf(irp->f, ","); | ||
| 525 | ir_print_other_instruction(irp, instruction->op); | ||
| 514 | fprintf(irp->f, ")"); | 526 | fprintf(irp->f, ")"); |
| 515 | } | 527 | } |
| 516 | 528 | ||
| 517 | static void ir_print_pop_count(IrPrint *irp, IrInstructionPopCount *instruction) { | 529 | static void ir_print_pop_count(IrPrint *irp, IrInstructionPopCount *instruction) { |
| 518 | fprintf(irp->f, "@popCount("); | 530 | fprintf(irp->f, "@popCount("); |
| 519 | ir_print_other_instruction(irp, instruction->value); | 531 | if (instruction->type != nullptr) { |
| 532 | ir_print_other_instruction(irp, instruction->type); | ||
| 533 | } else { | ||
| 534 | fprintf(irp->f, "null"); | ||
| 535 | } | ||
| 536 | fprintf(irp->f, ","); | ||
| 537 | ir_print_other_instruction(irp, instruction->op); | ||
| 538 | fprintf(irp->f, ")"); | ||
| 539 | } | ||
| 540 | |||
| 541 | static void ir_print_bswap(IrPrint *irp, IrInstructionBswap *instruction) { | ||
| 542 | fprintf(irp->f, "@byteSwap("); | ||
| 543 | if (instruction->type != nullptr) { | ||
| 544 | ir_print_other_instruction(irp, instruction->type); | ||
| 545 | } else { | ||
| 546 | fprintf(irp->f, "null"); | ||
| 547 | } | ||
| 548 | fprintf(irp->f, ","); | ||
| 549 | ir_print_other_instruction(irp, instruction->op); | ||
| 550 | fprintf(irp->f, ")"); | ||
| 551 | } | ||
| 552 | |||
| 553 | static void ir_print_bit_reverse(IrPrint *irp, IrInstructionBitReverse *instruction) { | ||
| 554 | fprintf(irp->f, "@bitReverse("); | ||
| 555 | if (instruction->type != nullptr) { | ||
| 556 | ir_print_other_instruction(irp, instruction->type); | ||
| 557 | } else { | ||
| 558 | fprintf(irp->f, "null"); | ||
| 559 | } | ||
| 560 | fprintf(irp->f, ","); | ||
| 561 | ir_print_other_instruction(irp, instruction->op); | ||
| 520 | fprintf(irp->f, ")"); | 562 | fprintf(irp->f, ")"); |
| 521 | } | 563 | } |
| 522 | 564 | ||
| ... | @@ -1411,30 +1453,6 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va | ... | @@ -1411,30 +1453,6 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va |
| 1411 | } | 1453 | } |
| 1412 | } | 1454 | } |
| 1413 | 1455 | ||
| 1414 | static void ir_print_bswap(IrPrint *irp, IrInstructionBswap *instruction) { | ||
| 1415 | fprintf(irp->f, "@bswap("); | ||
| 1416 | if (instruction->type != nullptr) { | ||
| 1417 | ir_print_other_instruction(irp, instruction->type); | ||
| 1418 | } else { | ||
| 1419 | fprintf(irp->f, "null"); | ||
| 1420 | } | ||
| 1421 | fprintf(irp->f, ","); | ||
| 1422 | ir_print_other_instruction(irp, instruction->op); | ||
| 1423 | fprintf(irp->f, ")"); | ||
| 1424 | } | ||
| 1425 | |||
| 1426 | static void ir_print_bit_reverse(IrPrint *irp, IrInstructionBitReverse *instruction) { | ||
| 1427 | fprintf(irp->f, "@bitreverse("); | ||
| 1428 | if (instruction->type != nullptr) { | ||
| 1429 | ir_print_other_instruction(irp, instruction->type); | ||
| 1430 | } else { | ||
| 1431 | fprintf(irp->f, "null"); | ||
| 1432 | } | ||
| 1433 | fprintf(irp->f, ","); | ||
| 1434 | ir_print_other_instruction(irp, instruction->op); | ||
| 1435 | fprintf(irp->f, ")"); | ||
| 1436 | } | ||
| 1437 | |||
| 1438 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | 1456 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1439 | ir_print_prefix(irp, instruction); | 1457 | ir_print_prefix(irp, instruction); |
| 1440 | switch (instruction->id) { | 1458 | switch (instruction->id) { |
| ... | @@ -1551,15 +1569,21 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1551,15 +1569,21 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1551 | case IrInstructionIdOptionalUnwrapPtr: | 1569 | case IrInstructionIdOptionalUnwrapPtr: |
| 1552 | ir_print_optional_unwrap_ptr(irp, (IrInstructionOptionalUnwrapPtr *)instruction); | 1570 | ir_print_optional_unwrap_ptr(irp, (IrInstructionOptionalUnwrapPtr *)instruction); |
| 1553 | break; | 1571 | break; |
| 1554 | case IrInstructionIdCtz: | ||
| 1555 | ir_print_ctz(irp, (IrInstructionCtz *)instruction); | ||
| 1556 | break; | ||
| 1557 | case IrInstructionIdPopCount: | 1572 | case IrInstructionIdPopCount: |
| 1558 | ir_print_pop_count(irp, (IrInstructionPopCount *)instruction); | 1573 | ir_print_pop_count(irp, (IrInstructionPopCount *)instruction); |
| 1559 | break; | 1574 | break; |
| 1560 | case IrInstructionIdClz: | 1575 | case IrInstructionIdClz: |
| 1561 | ir_print_clz(irp, (IrInstructionClz *)instruction); | 1576 | ir_print_clz(irp, (IrInstructionClz *)instruction); |
| 1562 | break; | 1577 | break; |
| 1578 | case IrInstructionIdCtz: | ||
| 1579 | ir_print_ctz(irp, (IrInstructionCtz *)instruction); | ||
| 1580 | break; | ||
| 1581 | case IrInstructionIdBswap: | ||
| 1582 | ir_print_bswap(irp, (IrInstructionBswap *)instruction); | ||
| 1583 | break; | ||
| 1584 | case IrInstructionIdBitReverse: | ||
| 1585 | ir_print_bit_reverse(irp, (IrInstructionBitReverse *)instruction); | ||
| 1586 | break; | ||
| 1563 | case IrInstructionIdSwitchBr: | 1587 | case IrInstructionIdSwitchBr: |
| 1564 | ir_print_switch_br(irp, (IrInstructionSwitchBr *)instruction); | 1588 | ir_print_switch_br(irp, (IrInstructionSwitchBr *)instruction); |
| 1565 | break; | 1589 | break; |
| ... | @@ -1869,12 +1893,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { | ... | @@ -1869,12 +1893,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1869 | case IrInstructionIdSqrt: | 1893 | case IrInstructionIdSqrt: |
| 1870 | ir_print_sqrt(irp, (IrInstructionSqrt *)instruction); | 1894 | ir_print_sqrt(irp, (IrInstructionSqrt *)instruction); |
| 1871 | break; | 1895 | break; |
| 1872 | case IrInstructionIdBswap: | ||
| 1873 | ir_print_bswap(irp, (IrInstructionBswap *)instruction); | ||
| 1874 | break; | ||
| 1875 | case IrInstructionIdBitReverse: | ||
| 1876 | ir_print_bit_reverse(irp, (IrInstructionBitReverse *)instruction); | ||
| 1877 | break; | ||
| 1878 | case IrInstructionIdAtomicLoad: | 1896 | case IrInstructionIdAtomicLoad: |
| 1879 | ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction); | 1897 | ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction); |
| 1880 | break; | 1898 | break; |
std/heap.zig+1-1| ... | @@ -894,7 +894,7 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo | ... | @@ -894,7 +894,7 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo |
| 894 | const large_align = u29(os.page_size << 2); | 894 | const large_align = u29(os.page_size << 2); |
| 895 | 895 | ||
| 896 | var align_mask: usize = undefined; | 896 | var align_mask: usize = undefined; |
| 897 | _ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(large_align)), &align_mask); | 897 | _ = @shlWithOverflow(usize, ~usize(0), USizeShift(@ctz(u29, large_align)), &align_mask); |
| 898 | 898 | ||
| 899 | var slice = try allocator.alignedAlloc(u8, large_align, 500); | 899 | var slice = try allocator.alignedAlloc(u8, large_align, 500); |
| 900 | testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr)); | 900 | testing.expect(@ptrToInt(slice.ptr) & align_mask == @ptrToInt(slice.ptr)); |
std/math.zig+1-1| ... | @@ -698,7 +698,7 @@ test "math.floorPowerOfTwo" { | ... | @@ -698,7 +698,7 @@ test "math.floorPowerOfTwo" { |
| 698 | 698 | ||
| 699 | pub fn log2_int(comptime T: type, x: T) Log2Int(T) { | 699 | pub fn log2_int(comptime T: type, x: T) Log2Int(T) { |
| 700 | assert(x != 0); | 700 | assert(x != 0); |
| 701 | return @intCast(Log2Int(T), T.bit_count - 1 - @clz(x)); | 701 | return @intCast(Log2Int(T), T.bit_count - 1 - @clz(T, x)); |
| 702 | } | 702 | } |
| 703 | 703 | ||
| 704 | pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) { | 704 | pub fn log2_int_ceil(comptime T: type, x: T) Log2Int(T) { |
std/math/big/int.zig+4-4| ... | @@ -207,7 +207,7 @@ pub const Int = struct { | ... | @@ -207,7 +207,7 @@ pub const Int = struct { |
| 207 | 207 | ||
| 208 | /// Returns the number of bits required to represent the absolute value an Int. | 208 | /// Returns the number of bits required to represent the absolute value an Int. |
| 209 | fn bitCountAbs(self: Int) usize { | 209 | fn bitCountAbs(self: Int) usize { |
| 210 | return (self.len() - 1) * Limb.bit_count + (Limb.bit_count - @clz(self.limbs[self.len() - 1])); | 210 | return (self.len() - 1) * Limb.bit_count + (Limb.bit_count - @clz(Limb, self.limbs[self.len() - 1])); |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | /// Returns the number of bits required to represent the integer in twos-complement form. | 213 | /// Returns the number of bits required to represent the integer in twos-complement form. |
| ... | @@ -226,9 +226,9 @@ pub const Int = struct { | ... | @@ -226,9 +226,9 @@ pub const Int = struct { |
| 226 | if (!self.isPositive()) block: { | 226 | if (!self.isPositive()) block: { |
| 227 | bits += 1; | 227 | bits += 1; |
| 228 | 228 | ||
| 229 | if (@popCount(self.limbs[self.len() - 1]) == 1) { | 229 | if (@popCount(Limb, self.limbs[self.len() - 1]) == 1) { |
| 230 | for (self.limbs[0 .. self.len() - 1]) |limb| { | 230 | for (self.limbs[0 .. self.len() - 1]) |limb| { |
| 231 | if (@popCount(limb) != 0) { | 231 | if (@popCount(Limb, limb) != 0) { |
| 232 | break :block; | 232 | break :block; |
| 233 | } | 233 | } |
| 234 | } | 234 | } |
| ... | @@ -962,7 +962,7 @@ pub const Int = struct { | ... | @@ -962,7 +962,7 @@ pub const Int = struct { |
| 962 | defer tmp.deinit(); | 962 | defer tmp.deinit(); |
| 963 | 963 | ||
| 964 | // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) and even | 964 | // Normalize so y > Limb.bit_count / 2 (i.e. leading bit is set) and even |
| 965 | var norm_shift = @clz(y.limbs[y.len() - 1]); | 965 | var norm_shift = @clz(Limb, y.limbs[y.len() - 1]); |
| 966 | if (norm_shift == 0 and y.isOdd()) { | 966 | if (norm_shift == 0 and y.isOdd()) { |
| 967 | norm_shift = Limb.bit_count; | 967 | norm_shift = Limb.bit_count; |
| 968 | } | 968 | } |
std/mem.zig+8-8| ... | @@ -513,7 +513,7 @@ pub fn readIntNative(comptime T: type, bytes: *const [@divExact(T.bit_count, 8)] | ... | @@ -513,7 +513,7 @@ pub fn readIntNative(comptime T: type, bytes: *const [@divExact(T.bit_count, 8)] |
| 513 | /// This function cannot fail and cannot cause undefined behavior. | 513 | /// This function cannot fail and cannot cause undefined behavior. |
| 514 | /// Assumes the endianness of memory is foreign, so it must byte-swap. | 514 | /// Assumes the endianness of memory is foreign, so it must byte-swap. |
| 515 | pub fn readIntForeign(comptime T: type, bytes: *const [@divExact(T.bit_count, 8)]u8) T { | 515 | pub fn readIntForeign(comptime T: type, bytes: *const [@divExact(T.bit_count, 8)]u8) T { |
| 516 | return @bswap(T, readIntNative(T, bytes)); | 516 | return @byteSwap(T, readIntNative(T, bytes)); |
| 517 | } | 517 | } |
| 518 | 518 | ||
| 519 | pub const readIntLittle = switch (builtin.endian) { | 519 | pub const readIntLittle = switch (builtin.endian) { |
| ... | @@ -543,7 +543,7 @@ pub fn readIntSliceNative(comptime T: type, bytes: []const u8) T { | ... | @@ -543,7 +543,7 @@ pub fn readIntSliceNative(comptime T: type, bytes: []const u8) T { |
| 543 | /// The bit count of T must be evenly divisible by 8. | 543 | /// The bit count of T must be evenly divisible by 8. |
| 544 | /// Assumes the endianness of memory is foreign, so it must byte-swap. | 544 | /// Assumes the endianness of memory is foreign, so it must byte-swap. |
| 545 | pub fn readIntSliceForeign(comptime T: type, bytes: []const u8) T { | 545 | pub fn readIntSliceForeign(comptime T: type, bytes: []const u8) T { |
| 546 | return @bswap(T, readIntSliceNative(T, bytes)); | 546 | return @byteSwap(T, readIntSliceNative(T, bytes)); |
| 547 | } | 547 | } |
| 548 | 548 | ||
| 549 | pub const readIntSliceLittle = switch (builtin.endian) { | 549 | pub const readIntSliceLittle = switch (builtin.endian) { |
| ... | @@ -624,9 +624,9 @@ pub fn writeIntNative(comptime T: type, buf: *[(T.bit_count + 7) / 8]u8, value: | ... | @@ -624,9 +624,9 @@ pub fn writeIntNative(comptime T: type, buf: *[(T.bit_count + 7) / 8]u8, value: |
| 624 | /// Writes an integer to memory, storing it in twos-complement. | 624 | /// Writes an integer to memory, storing it in twos-complement. |
| 625 | /// This function always succeeds, has defined behavior for all inputs, but | 625 | /// This function always succeeds, has defined behavior for all inputs, but |
| 626 | /// the integer bit width must be divisible by 8. | 626 | /// the integer bit width must be divisible by 8. |
| 627 | /// This function stores in foreign endian, which means it does a @bswap first. | 627 | /// This function stores in foreign endian, which means it does a @byteSwap first. |
| 628 | pub fn writeIntForeign(comptime T: type, buf: *[@divExact(T.bit_count, 8)]u8, value: T) void { | 628 | pub fn writeIntForeign(comptime T: type, buf: *[@divExact(T.bit_count, 8)]u8, value: T) void { |
| 629 | writeIntNative(T, buf, @bswap(T, value)); | 629 | writeIntNative(T, buf, @byteSwap(T, value)); |
| 630 | } | 630 | } |
| 631 | 631 | ||
| 632 | pub const writeIntLittle = switch (builtin.endian) { | 632 | pub const writeIntLittle = switch (builtin.endian) { |
| ... | @@ -1229,14 +1229,14 @@ test "std.mem.rotate" { | ... | @@ -1229,14 +1229,14 @@ test "std.mem.rotate" { |
| 1229 | pub fn littleToNative(comptime T: type, x: T) T { | 1229 | pub fn littleToNative(comptime T: type, x: T) T { |
| 1230 | return switch (builtin.endian) { | 1230 | return switch (builtin.endian) { |
| 1231 | builtin.Endian.Little => x, | 1231 | builtin.Endian.Little => x, |
| 1232 | builtin.Endian.Big => @bswap(T, x), | 1232 | builtin.Endian.Big => @byteSwap(T, x), |
| 1233 | }; | 1233 | }; |
| 1234 | } | 1234 | } |
| 1235 | 1235 | ||
| 1236 | /// Converts a big-endian integer to host endianness. | 1236 | /// Converts a big-endian integer to host endianness. |
| 1237 | pub fn bigToNative(comptime T: type, x: T) T { | 1237 | pub fn bigToNative(comptime T: type, x: T) T { |
| 1238 | return switch (builtin.endian) { | 1238 | return switch (builtin.endian) { |
| 1239 | builtin.Endian.Little => @bswap(T, x), | 1239 | builtin.Endian.Little => @byteSwap(T, x), |
| 1240 | builtin.Endian.Big => x, | 1240 | builtin.Endian.Big => x, |
| 1241 | }; | 1241 | }; |
| 1242 | } | 1242 | } |
| ... | @@ -1261,14 +1261,14 @@ pub fn nativeTo(comptime T: type, x: T, desired_endianness: builtin.Endian) T { | ... | @@ -1261,14 +1261,14 @@ pub fn nativeTo(comptime T: type, x: T, desired_endianness: builtin.Endian) T { |
| 1261 | pub fn nativeToLittle(comptime T: type, x: T) T { | 1261 | pub fn nativeToLittle(comptime T: type, x: T) T { |
| 1262 | return switch (builtin.endian) { | 1262 | return switch (builtin.endian) { |
| 1263 | builtin.Endian.Little => x, | 1263 | builtin.Endian.Little => x, |
| 1264 | builtin.Endian.Big => @bswap(T, x), | 1264 | builtin.Endian.Big => @byteSwap(T, x), |
| 1265 | }; | 1265 | }; |
| 1266 | } | 1266 | } |
| 1267 | 1267 | ||
| 1268 | /// Converts an integer which has host endianness to big endian. | 1268 | /// Converts an integer which has host endianness to big endian. |
| 1269 | pub fn nativeToBig(comptime T: type, x: T) T { | 1269 | pub fn nativeToBig(comptime T: type, x: T) T { |
| 1270 | return switch (builtin.endian) { | 1270 | return switch (builtin.endian) { |
| 1271 | builtin.Endian.Little => @bswap(T, x), | 1271 | builtin.Endian.Little => @byteSwap(T, x), |
| 1272 | builtin.Endian.Big => x, | 1272 | builtin.Endian.Big => x, |
| 1273 | }; | 1273 | }; |
| 1274 | } | 1274 | } |
std/os.zig+1-1| ... | @@ -3377,7 +3377,7 @@ pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize { | ... | @@ -3377,7 +3377,7 @@ pub fn cpuCount(fallback_allocator: *mem.Allocator) CpuCountError!usize { |
| 3377 | const result = set[0 .. rc / @sizeOf(usize)]; | 3377 | const result = set[0 .. rc / @sizeOf(usize)]; |
| 3378 | var sum: usize = 0; | 3378 | var sum: usize = 0; |
| 3379 | for (result) |x| { | 3379 | for (result) |x| { |
| 3380 | sum += @popCount(x); | 3380 | sum += @popCount(usize, x); |
| 3381 | } | 3381 | } |
| 3382 | return sum; | 3382 | return sum; |
| 3383 | } else { | 3383 | } else { |
std/packed_int_array.zig+3-3| ... | @@ -66,7 +66,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { | ... | @@ -66,7 +66,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { |
| 66 | const value_ptr = @ptrCast(*align(1) const Container, &bytes[start_byte]); | 66 | const value_ptr = @ptrCast(*align(1) const Container, &bytes[start_byte]); |
| 67 | var value = value_ptr.*; | 67 | var value = value_ptr.*; |
| 68 | 68 | ||
| 69 | if (endian != builtin.endian) value = @bswap(Container, value); | 69 | if (endian != builtin.endian) value = @byteSwap(Container, value); |
| 70 | 70 | ||
| 71 | switch (endian) { | 71 | switch (endian) { |
| 72 | .Big => { | 72 | .Big => { |
| ... | @@ -114,7 +114,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { | ... | @@ -114,7 +114,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { |
| 114 | const target_ptr = @ptrCast(*align(1) Container, &bytes[start_byte]); | 114 | const target_ptr = @ptrCast(*align(1) Container, &bytes[start_byte]); |
| 115 | var target = target_ptr.*; | 115 | var target = target_ptr.*; |
| 116 | 116 | ||
| 117 | if (endian != builtin.endian) target = @bswap(Container, target); | 117 | if (endian != builtin.endian) target = @byteSwap(Container, target); |
| 118 | 118 | ||
| 119 | //zero the bits we want to replace in the existing bytes | 119 | //zero the bits we want to replace in the existing bytes |
| 120 | const inv_mask = @intCast(Container, std.math.maxInt(UnInt)) << keep_shift; | 120 | 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 { | ... | @@ -124,7 +124,7 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type { |
| 124 | //merge the new value | 124 | //merge the new value |
| 125 | target |= value; | 125 | target |= value; |
| 126 | 126 | ||
| 127 | if (endian != builtin.endian) target = @bswap(Container, target); | 127 | if (endian != builtin.endian) target = @byteSwap(Container, target); |
| 128 | 128 | ||
| 129 | //save it back | 129 | //save it back |
| 130 | target_ptr.* = target; | 130 | target_ptr.* = target; |
std/special/compiler_rt.zig+1-2| ... | @@ -19,7 +19,6 @@ comptime { | ... | @@ -19,7 +19,6 @@ comptime { |
| 19 | @export("__getf2", @import("compiler_rt/comparetf2.zig").__getf2, linkage); | 19 | @export("__getf2", @import("compiler_rt/comparetf2.zig").__getf2, linkage); |
| 20 | 20 | ||
| 21 | if (!is_test) { | 21 | if (!is_test) { |
| 22 | // only create these aliases when not testing | ||
| 23 | @export("__cmpsf2", @import("compiler_rt/comparesf2.zig").__lesf2, linkage); | 22 | @export("__cmpsf2", @import("compiler_rt/comparesf2.zig").__lesf2, linkage); |
| 24 | @export("__cmpdf2", @import("compiler_rt/comparedf2.zig").__ledf2, linkage); | 23 | @export("__cmpdf2", @import("compiler_rt/comparedf2.zig").__ledf2, linkage); |
| 25 | @export("__cmptf2", @import("compiler_rt/comparetf2.zig").__letf2, linkage); | 24 | @export("__cmptf2", @import("compiler_rt/comparetf2.zig").__letf2, linkage); |
| ... | @@ -599,7 +598,7 @@ extern fn __udivsi3(n: u32, d: u32) u32 { | ... | @@ -599,7 +598,7 @@ extern fn __udivsi3(n: u32, d: u32) u32 { |
| 599 | // special cases | 598 | // special cases |
| 600 | if (d == 0) return 0; // ?! | 599 | if (d == 0) return 0; // ?! |
| 601 | if (n == 0) return 0; | 600 | if (n == 0) return 0; |
| 602 | var sr = @bitCast(c_uint, c_int(@clz(d)) - c_int(@clz(n))); | 601 | var sr = @bitCast(c_uint, c_int(@clz(u32, d)) - c_int(@clz(u32, n))); |
| 603 | // 0 <= sr <= n_uword_bits - 1 or sr large | 602 | // 0 <= sr <= n_uword_bits - 1 or sr large |
| 604 | if (sr > n_uword_bits - 1) { | 603 | if (sr > n_uword_bits - 1) { |
| 605 | // d > r | 604 | // d > r |
std/special/compiler_rt/addXf3.zig+4-4| ... | @@ -36,11 +36,11 @@ pub extern fn __subtf3(a: f128, b: f128) f128 { | ... | @@ -36,11 +36,11 @@ pub extern fn __subtf3(a: f128, b: f128) f128 { |
| 36 | // TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154 | 36 | // TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154 |
| 37 | fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { | 37 | fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { |
| 38 | const Z = @IntType(false, T.bit_count); | 38 | const Z = @IntType(false, T.bit_count); |
| 39 | const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1)); | 39 | const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1)); |
| 40 | const significandBits = std.math.floatMantissaBits(T); | 40 | const significandBits = std.math.floatMantissaBits(T); |
| 41 | const implicitBit = Z(1) << significandBits; | 41 | const implicitBit = Z(1) << significandBits; |
| 42 | 42 | ||
| 43 | const shift = @clz(significand.*) - @clz(implicitBit); | 43 | const shift = @clz(@IntType(false, T.bit_count), significand.*) - @clz(Z, implicitBit); |
| 44 | significand.* <<= @intCast(S, shift); | 44 | significand.* <<= @intCast(S, shift); |
| 45 | return 1 - shift; | 45 | return 1 - shift; |
| 46 | } | 46 | } |
| ... | @@ -48,7 +48,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { | ... | @@ -48,7 +48,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { |
| 48 | // TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154 | 48 | // TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154 |
| 49 | fn addXf3(comptime T: type, a: T, b: T) T { | 49 | fn addXf3(comptime T: type, a: T, b: T) T { |
| 50 | const Z = @IntType(false, T.bit_count); | 50 | const Z = @IntType(false, T.bit_count); |
| 51 | const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1)); | 51 | const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1)); |
| 52 | 52 | ||
| 53 | const typeWidth = T.bit_count; | 53 | const typeWidth = T.bit_count; |
| 54 | const significandBits = std.math.floatMantissaBits(T); | 54 | const significandBits = std.math.floatMantissaBits(T); |
| ... | @@ -162,7 +162,7 @@ fn addXf3(comptime T: type, a: T, b: T) T { | ... | @@ -162,7 +162,7 @@ fn addXf3(comptime T: type, a: T, b: T) T { |
| 162 | // If partial cancellation occured, we need to left-shift the result | 162 | // If partial cancellation occured, we need to left-shift the result |
| 163 | // and adjust the exponent: | 163 | // and adjust the exponent: |
| 164 | if (aSignificand < implicitBit << 3) { | 164 | if (aSignificand < implicitBit << 3) { |
| 165 | const shift = @intCast(i32, @clz(aSignificand)) - @intCast(i32, @clz(implicitBit << 3)); | 165 | const shift = @intCast(i32, @clz(Z, aSignificand)) - @intCast(i32, @clz(@IntType(false, T.bit_count), implicitBit << 3)); |
| 166 | aSignificand <<= @intCast(S, shift); | 166 | aSignificand <<= @intCast(S, shift); |
| 167 | aExponent -= shift; | 167 | aExponent -= shift; |
| 168 | } | 168 | } |
std/special/compiler_rt/divdf3.zig+1-1| ... | @@ -318,7 +318,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { | ... | @@ -318,7 +318,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { |
| 318 | const significandBits = std.math.floatMantissaBits(T); | 318 | const significandBits = std.math.floatMantissaBits(T); |
| 319 | const implicitBit = Z(1) << significandBits; | 319 | const implicitBit = Z(1) << significandBits; |
| 320 | 320 | ||
| 321 | const shift = @clz(significand.*) - @clz(implicitBit); | 321 | const shift = @clz(Z, significand.*) - @clz(Z, implicitBit); |
| 322 | significand.* <<= @intCast(std.math.Log2Int(Z), shift); | 322 | significand.* <<= @intCast(std.math.Log2Int(Z), shift); |
| 323 | return 1 - shift; | 323 | return 1 - shift; |
| 324 | } | 324 | } |
std/special/compiler_rt/divsf3.zig+1-1| ... | @@ -191,7 +191,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { | ... | @@ -191,7 +191,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { |
| 191 | const significandBits = std.math.floatMantissaBits(T); | 191 | const significandBits = std.math.floatMantissaBits(T); |
| 192 | const implicitBit = Z(1) << significandBits; | 192 | const implicitBit = Z(1) << significandBits; |
| 193 | 193 | ||
| 194 | const shift = @clz(significand.*) - @clz(implicitBit); | 194 | const shift = @clz(Z, significand.*) - @clz(Z, implicitBit); |
| 195 | significand.* <<= @intCast(std.math.Log2Int(Z), shift); | 195 | significand.* <<= @intCast(std.math.Log2Int(Z), shift); |
| 196 | return 1 - shift; | 196 | return 1 - shift; |
| 197 | } | 197 | } |
std/special/compiler_rt/extendXfYf2.zig+2-1| ... | @@ -75,7 +75,8 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t | ... | @@ -75,7 +75,8 @@ fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @t |
| 75 | // a is denormal. | 75 | // a is denormal. |
| 76 | // renormalize the significand and clear the leading bit, then insert | 76 | // renormalize the significand and clear the leading bit, then insert |
| 77 | // the correct adjusted exponent in the destination type. | 77 | // the correct adjusted exponent in the destination type. |
| 78 | const scale: u32 = @clz(aAbs) - @clz(src_rep_t(srcMinNormal)); | 78 | const scale: u32 = @clz(src_rep_t, aAbs) - |
| 79 | @clz(src_rep_t, src_rep_t(srcMinNormal)); | ||
| 79 | absResult = dst_rep_t(aAbs) << @intCast(DstShift, dstSigBits - srcSigBits + scale); | 80 | absResult = dst_rep_t(aAbs) << @intCast(DstShift, dstSigBits - srcSigBits + scale); |
| 80 | absResult ^= dstMinNormal; | 81 | absResult ^= dstMinNormal; |
| 81 | const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1; | 82 | const resultExponent: u32 = dstExpBias - srcExpBias - scale + 1; |
std/special/compiler_rt/floatsiXf.zig+2-2| ... | @@ -6,7 +6,7 @@ fn floatsiXf(comptime T: type, a: i32) T { | ... | @@ -6,7 +6,7 @@ fn floatsiXf(comptime T: type, a: i32) T { |
| 6 | @setRuntimeSafety(builtin.is_test); | 6 | @setRuntimeSafety(builtin.is_test); |
| 7 | 7 | ||
| 8 | const Z = @IntType(false, T.bit_count); | 8 | const Z = @IntType(false, T.bit_count); |
| 9 | const S = @IntType(false, T.bit_count - @clz(Z(T.bit_count) - 1)); | 9 | const S = @IntType(false, T.bit_count - @clz(Z, Z(T.bit_count) - 1)); |
| 10 | 10 | ||
| 11 | if (a == 0) { | 11 | if (a == 0) { |
| 12 | return T(0.0); | 12 | return T(0.0); |
| ... | @@ -23,7 +23,7 @@ fn floatsiXf(comptime T: type, a: i32) T { | ... | @@ -23,7 +23,7 @@ fn floatsiXf(comptime T: type, a: i32) T { |
| 23 | // Take absolute value of a via abs(x) = (x^(x >> 31)) - (x >> 31). | 23 | // Take absolute value of a via abs(x) = (x^(x >> 31)) - (x >> 31). |
| 24 | const abs_a = (a ^ sign) -% sign; | 24 | const abs_a = (a ^ sign) -% sign; |
| 25 | // The exponent is the width of abs(a) | 25 | // The exponent is the width of abs(a) |
| 26 | const exp = Z(31 - @clz(abs_a)); | 26 | const exp = Z(31 - @clz(i32, abs_a)); |
| 27 | 27 | ||
| 28 | const sign_bit = if (sign < 0) signBit else 0; | 28 | const sign_bit = if (sign < 0) signBit else 0; |
| 29 | 29 |
std/special/compiler_rt/floattidf.zig+1-1| ... | @@ -17,7 +17,7 @@ pub extern fn __floattidf(arg: i128) f64 { | ... | @@ -17,7 +17,7 @@ pub extern fn __floattidf(arg: i128) f64 { |
| 17 | ai = ((ai ^ si) -% si); | 17 | ai = ((ai ^ si) -% si); |
| 18 | var a = @bitCast(u128, ai); | 18 | var a = @bitCast(u128, ai); |
| 19 | 19 | ||
| 20 | const sd = @bitCast(i32, N - @clz(a)); // number of significant digits | 20 | const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits |
| 21 | var e: i32 = sd - 1; // exponent | 21 | var e: i32 = sd - 1; // exponent |
| 22 | if (sd > DBL_MANT_DIG) { | 22 | if (sd > DBL_MANT_DIG) { |
| 23 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx | 23 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx |
std/special/compiler_rt/floattisf.zig+1-1| ... | @@ -17,7 +17,7 @@ pub extern fn __floattisf(arg: i128) f32 { | ... | @@ -17,7 +17,7 @@ pub extern fn __floattisf(arg: i128) f32 { |
| 17 | ai = ((ai ^ si) -% si); | 17 | ai = ((ai ^ si) -% si); |
| 18 | var a = @bitCast(u128, ai); | 18 | var a = @bitCast(u128, ai); |
| 19 | 19 | ||
| 20 | const sd = @bitCast(i32, N - @clz(a)); // number of significant digits | 20 | const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits |
| 21 | var e: i32 = sd - 1; // exponent | 21 | var e: i32 = sd - 1; // exponent |
| 22 | 22 | ||
| 23 | if (sd > FLT_MANT_DIG) { | 23 | if (sd > FLT_MANT_DIG) { |
std/special/compiler_rt/floattitf.zig+1-1| ... | @@ -17,7 +17,7 @@ pub extern fn __floattitf(arg: i128) f128 { | ... | @@ -17,7 +17,7 @@ pub extern fn __floattitf(arg: i128) f128 { |
| 17 | ai = ((ai ^ si) -% si); | 17 | ai = ((ai ^ si) -% si); |
| 18 | var a = @bitCast(u128, ai); | 18 | var a = @bitCast(u128, ai); |
| 19 | 19 | ||
| 20 | const sd = @bitCast(i32, N - @clz(a)); // number of significant digits | 20 | const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits |
| 21 | var e: i32 = sd - 1; // exponent | 21 | var e: i32 = sd - 1; // exponent |
| 22 | if (sd > LDBL_MANT_DIG) { | 22 | if (sd > LDBL_MANT_DIG) { |
| 23 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx | 23 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx |
std/special/compiler_rt/floatunditf.zig+1-1| ... | @@ -14,7 +14,7 @@ pub extern fn __floatunditf(a: u128) f128 { | ... | @@ -14,7 +14,7 @@ pub extern fn __floatunditf(a: u128) f128 { |
| 14 | const exponent_bias = (1 << (exponent_bits - 1)) - 1; | 14 | const exponent_bias = (1 << (exponent_bits - 1)) - 1; |
| 15 | const implicit_bit = 1 << mantissa_bits; | 15 | const implicit_bit = 1 << mantissa_bits; |
| 16 | 16 | ||
| 17 | const exp = (u128.bit_count - 1) - @clz(a); | 17 | const exp = (u128.bit_count - 1) - @clz(u128, a); |
| 18 | const shift = mantissa_bits - @intCast(u7, exp); | 18 | const shift = mantissa_bits - @intCast(u7, exp); |
| 19 | 19 | ||
| 20 | var result: u128 align(16) = (a << shift) ^ implicit_bit; | 20 | var result: u128 align(16) = (a << shift) ^ implicit_bit; |
std/special/compiler_rt/floatunsidf.zig+1-1| ... | @@ -10,7 +10,7 @@ pub extern fn __floatunsidf(arg: u32) f64 { | ... | @@ -10,7 +10,7 @@ pub extern fn __floatunsidf(arg: u32) f64 { |
| 10 | if (arg == 0) return 0.0; | 10 | if (arg == 0) return 0.0; |
| 11 | 11 | ||
| 12 | // The exponent is the width of abs(a) | 12 | // The exponent is the width of abs(a) |
| 13 | const exp = u64(31) - @clz(arg); | 13 | const exp = u64(31) - @clz(u32, arg); |
| 14 | // Shift a into the significand field and clear the implicit bit | 14 | // Shift a into the significand field and clear the implicit bit |
| 15 | const shift = @intCast(u6, 52 - exp); | 15 | const shift = @intCast(u6, 52 - exp); |
| 16 | const mant = u64(arg) << shift ^ implicitBit; | 16 | const mant = u64(arg) << shift ^ implicitBit; |
std/special/compiler_rt/floatunsitf.zig+1-1| ... | @@ -14,7 +14,7 @@ pub extern fn __floatunsitf(a: u64) f128 { | ... | @@ -14,7 +14,7 @@ pub extern fn __floatunsitf(a: u64) f128 { |
| 14 | const exponent_bias = (1 << (exponent_bits - 1)) - 1; | 14 | const exponent_bias = (1 << (exponent_bits - 1)) - 1; |
| 15 | const implicit_bit = 1 << mantissa_bits; | 15 | const implicit_bit = 1 << mantissa_bits; |
| 16 | 16 | ||
| 17 | const exp = (u64.bit_count - 1) - @clz(a); | 17 | const exp = (u64.bit_count - 1) - @clz(u64, a); |
| 18 | const shift = mantissa_bits - @intCast(u7, exp); | 18 | const shift = mantissa_bits - @intCast(u7, exp); |
| 19 | 19 | ||
| 20 | // TODO(#1148): @bitCast alignment error | 20 | // TODO(#1148): @bitCast alignment error |
std/special/compiler_rt/floatuntidf.zig+1-1| ... | @@ -13,7 +13,7 @@ pub extern fn __floatuntidf(arg: u128) f64 { | ... | @@ -13,7 +13,7 @@ pub extern fn __floatuntidf(arg: u128) f64 { |
| 13 | 13 | ||
| 14 | var a = arg; | 14 | var a = arg; |
| 15 | const N: u32 = @sizeOf(u128) * 8; | 15 | const N: u32 = @sizeOf(u128) * 8; |
| 16 | const sd = @bitCast(i32, N - @clz(a)); // number of significant digits | 16 | const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits |
| 17 | var e: i32 = sd - 1; // exponent | 17 | var e: i32 = sd - 1; // exponent |
| 18 | if (sd > DBL_MANT_DIG) { | 18 | if (sd > DBL_MANT_DIG) { |
| 19 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx | 19 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx |
std/special/compiler_rt/floatuntisf.zig+1-1| ... | @@ -13,7 +13,7 @@ pub extern fn __floatuntisf(arg: u128) f32 { | ... | @@ -13,7 +13,7 @@ pub extern fn __floatuntisf(arg: u128) f32 { |
| 13 | 13 | ||
| 14 | var a = arg; | 14 | var a = arg; |
| 15 | const N: u32 = @sizeOf(u128) * 8; | 15 | const N: u32 = @sizeOf(u128) * 8; |
| 16 | const sd = @bitCast(i32, N - @clz(a)); // number of significant digits | 16 | const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits |
| 17 | var e: i32 = sd - 1; // exponent | 17 | var e: i32 = sd - 1; // exponent |
| 18 | if (sd > FLT_MANT_DIG) { | 18 | if (sd > FLT_MANT_DIG) { |
| 19 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx | 19 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx |
std/special/compiler_rt/floatuntitf.zig+1-1| ... | @@ -13,7 +13,7 @@ pub extern fn __floatuntitf(arg: u128) f128 { | ... | @@ -13,7 +13,7 @@ pub extern fn __floatuntitf(arg: u128) f128 { |
| 13 | 13 | ||
| 14 | var a = arg; | 14 | var a = arg; |
| 15 | const N: u32 = @sizeOf(u128) * 8; | 15 | const N: u32 = @sizeOf(u128) * 8; |
| 16 | const sd = @bitCast(i32, N - @clz(a)); // number of significant digits | 16 | const sd = @bitCast(i32, N - @clz(u128, a)); // number of significant digits |
| 17 | var e: i32 = sd - 1; // exponent | 17 | var e: i32 = sd - 1; // exponent |
| 18 | if (sd > LDBL_MANT_DIG) { | 18 | if (sd > LDBL_MANT_DIG) { |
| 19 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx | 19 | // start: 0000000000000000000001xxxxxxxxxxxxxxxxxxxxxxPQxxxxxxxxxxxxxxxxxx |
std/special/compiler_rt/mulXf3.zig+1-1| ... | @@ -260,7 +260,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { | ... | @@ -260,7 +260,7 @@ fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 { |
| 260 | const significandBits = std.math.floatMantissaBits(T); | 260 | const significandBits = std.math.floatMantissaBits(T); |
| 261 | const implicitBit = Z(1) << significandBits; | 261 | const implicitBit = Z(1) << significandBits; |
| 262 | 262 | ||
| 263 | const shift = @clz(significand.*) - @clz(implicitBit); | 263 | const shift = @clz(Z, significand.*) - @clz(Z, implicitBit); |
| 264 | significand.* <<= @intCast(std.math.Log2Int(Z), shift); | 264 | significand.* <<= @intCast(std.math.Log2Int(Z), shift); |
| 265 | return 1 - shift; | 265 | return 1 - shift; |
| 266 | } | 266 | } |
std/special/compiler_rt/udivmod.zig+5-5| ... | @@ -71,12 +71,12 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: | ... | @@ -71,12 +71,12 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 71 | r[high] = n[high] & (d[high] - 1); | 71 | r[high] = n[high] & (d[high] - 1); |
| 72 | rem.* = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421 | 72 | rem.* = @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &r[0]).*; // TODO issue #421 |
| 73 | } | 73 | } |
| 74 | return n[high] >> @intCast(Log2SingleInt, @ctz(d[high])); | 74 | return n[high] >> @intCast(Log2SingleInt, @ctz(SingleInt, d[high])); |
| 75 | } | 75 | } |
| 76 | // K K | 76 | // K K |
| 77 | // --- | 77 | // --- |
| 78 | // K 0 | 78 | // K 0 |
| 79 | sr = @bitCast(c_uint, c_int(@clz(d[high])) - c_int(@clz(n[high]))); | 79 | sr = @bitCast(c_uint, c_int(@clz(SingleInt, d[high])) - c_int(@clz(SingleInt, n[high]))); |
| 80 | // 0 <= sr <= SingleInt.bit_count - 2 or sr large | 80 | // 0 <= sr <= SingleInt.bit_count - 2 or sr large |
| 81 | if (sr > SingleInt.bit_count - 2) { | 81 | if (sr > SingleInt.bit_count - 2) { |
| 82 | if (maybe_rem) |rem| { | 82 | if (maybe_rem) |rem| { |
| ... | @@ -106,7 +106,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: | ... | @@ -106,7 +106,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 106 | if (d[low] == 1) { | 106 | if (d[low] == 1) { |
| 107 | return a; | 107 | return a; |
| 108 | } | 108 | } |
| 109 | sr = @ctz(d[low]); | 109 | sr = @ctz(SingleInt, d[low]); |
| 110 | q[high] = n[high] >> @intCast(Log2SingleInt, sr); | 110 | q[high] = n[high] >> @intCast(Log2SingleInt, sr); |
| 111 | q[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr)); | 111 | q[low] = (n[high] << @intCast(Log2SingleInt, SingleInt.bit_count - sr)) | (n[low] >> @intCast(Log2SingleInt, sr)); |
| 112 | return @ptrCast(*align(@alignOf(SingleInt)) DoubleInt, &q[0]).*; // TODO issue #421 | 112 | 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: | ... | @@ -114,7 +114,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 114 | // K X | 114 | // K X |
| 115 | // --- | 115 | // --- |
| 116 | // 0 K | 116 | // 0 K |
| 117 | sr = 1 + SingleInt.bit_count + c_uint(@clz(d[low])) - c_uint(@clz(n[high])); | 117 | sr = 1 + SingleInt.bit_count + c_uint(@clz(SingleInt, d[low])) - c_uint(@clz(SingleInt, n[high])); |
| 118 | // 2 <= sr <= DoubleInt.bit_count - 1 | 118 | // 2 <= sr <= DoubleInt.bit_count - 1 |
| 119 | // q.all = a << (DoubleInt.bit_count - sr); | 119 | // q.all = a << (DoubleInt.bit_count - sr); |
| 120 | // r.all = a >> sr; | 120 | // r.all = a >> sr; |
| ... | @@ -140,7 +140,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: | ... | @@ -140,7 +140,7 @@ pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: |
| 140 | // K X | 140 | // K X |
| 141 | // --- | 141 | // --- |
| 142 | // K K | 142 | // K K |
| 143 | sr = @bitCast(c_uint, c_int(@clz(d[high])) - c_int(@clz(n[high]))); | 143 | sr = @bitCast(c_uint, c_int(@clz(SingleInt, d[high])) - c_int(@clz(SingleInt, n[high]))); |
| 144 | // 0 <= sr <= SingleInt.bit_count - 1 or sr large | 144 | // 0 <= sr <= SingleInt.bit_count - 1 or sr large |
| 145 | if (sr > SingleInt.bit_count - 1) { | 145 | if (sr > SingleInt.bit_count - 1) { |
| 146 | if (maybe_rem) |rem| { | 146 | if (maybe_rem) |rem| { |
test/compile_errors.zig+1-10| ... | @@ -1363,21 +1363,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { | ... | @@ -1363,21 +1363,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 1363 | cases.add( | 1363 | cases.add( |
| 1364 | "@popCount - non-integer", | 1364 | "@popCount - non-integer", |
| 1365 | \\export fn entry(x: f32) u32 { | 1365 | \\export fn entry(x: f32) u32 { |
| 1366 | \\ return @popCount(x); | 1366 | \\ return @popCount(f32, x); |
| 1367 | \\} | 1367 | \\} |
| 1368 | , | 1368 | , |
| 1369 | "tmp.zig:2:22: error: expected integer type, found 'f32'", | 1369 | "tmp.zig:2:22: error: expected integer type, found 'f32'", |
| 1370 | ); | 1370 | ); |
| 1371 | 1371 | ||
| 1372 | cases.add( | ||
| 1373 | "@popCount - negative comptime_int", | ||
| 1374 | \\comptime { | ||
| 1375 | \\ _ = @popCount(-1); | ||
| 1376 | \\} | ||
| 1377 | , | ||
| 1378 | "tmp.zig:2:9: error: @popCount on negative comptime_int value -1", | ||
| 1379 | ); | ||
| 1380 | |||
| 1381 | cases.addCase(x: { | 1372 | cases.addCase(x: { |
| 1382 | const tc = cases.create( | 1373 | const tc = cases.create( |
| 1383 | "wrong same named struct", | 1374 | "wrong same named struct", |
test/stage1/behavior.zig+1-1| ... | @@ -8,7 +8,7 @@ comptime { | ... | @@ -8,7 +8,7 @@ comptime { |
| 8 | _ = @import("behavior/bitcast.zig"); | 8 | _ = @import("behavior/bitcast.zig"); |
| 9 | _ = @import("behavior/bitreverse.zig"); | 9 | _ = @import("behavior/bitreverse.zig"); |
| 10 | _ = @import("behavior/bool.zig"); | 10 | _ = @import("behavior/bool.zig"); |
| 11 | _ = @import("behavior/bswap.zig"); | 11 | _ = @import("behavior/byteswap.zig"); |
| 12 | _ = @import("behavior/bugs/1025.zig"); | 12 | _ = @import("behavior/bugs/1025.zig"); |
| 13 | _ = @import("behavior/bugs/1076.zig"); | 13 | _ = @import("behavior/bugs/1076.zig"); |
| 14 | _ = @import("behavior/bugs/1111.zig"); | 14 | _ = @import("behavior/bugs/1111.zig"); |
test/stage1/behavior/bitreverse.zig+38-50| ... | @@ -2,80 +2,68 @@ const std = @import("std"); | ... | @@ -2,80 +2,68 @@ const std = @import("std"); |
| 2 | const expect = std.testing.expect; | 2 | const expect = std.testing.expect; |
| 3 | const minInt = std.math.minInt; | 3 | const minInt = std.math.minInt; |
| 4 | 4 | ||
| 5 | test "@bitreverse" { | 5 | test "@bitReverse" { |
| 6 | comptime testBitReverse(); | 6 | comptime testBitReverse(); |
| 7 | testBitReverse(); | 7 | testBitReverse(); |
| 8 | } | 8 | } |
| 9 | 9 | ||
| 10 | fn testBitReverse() void { | 10 | fn testBitReverse() void { |
| 11 | // using comptime_ints, unsigned | 11 | // using comptime_ints, unsigned |
| 12 | expect(@bitreverse(u0, 0) == 0); | 12 | expect(@bitReverse(u0, u0(0)) == 0); |
| 13 | expect(@bitreverse(u5, 0x12) == 0x9); | 13 | expect(@bitReverse(u5, u5(0x12)) == 0x9); |
| 14 | expect(@bitreverse(u8, 0x12) == 0x48); | 14 | expect(@bitReverse(u8, u8(0x12)) == 0x48); |
| 15 | expect(@bitreverse(u16, 0x1234) == 0x2c48); | 15 | expect(@bitReverse(u16, u16(0x1234)) == 0x2c48); |
| 16 | expect(@bitreverse(u24, 0x123456) == 0x6a2c48); | 16 | expect(@bitReverse(u24, u24(0x123456)) == 0x6a2c48); |
| 17 | expect(@bitreverse(u32, 0x12345678) == 0x1e6a2c48); | 17 | expect(@bitReverse(u32, u32(0x12345678)) == 0x1e6a2c48); |
| 18 | expect(@bitreverse(u40, 0x123456789a) == 0x591e6a2c48); | 18 | expect(@bitReverse(u40, u40(0x123456789a)) == 0x591e6a2c48); |
| 19 | expect(@bitreverse(u48, 0x123456789abc) == 0x3d591e6a2c48); | 19 | expect(@bitReverse(u48, u48(0x123456789abc)) == 0x3d591e6a2c48); |
| 20 | expect(@bitreverse(u56, 0x123456789abcde) == 0x7b3d591e6a2c48); | 20 | expect(@bitReverse(u56, u56(0x123456789abcde)) == 0x7b3d591e6a2c48); |
| 21 | expect(@bitreverse(u64, 0x123456789abcdef1) == 0x8f7b3d591e6a2c48); | 21 | expect(@bitReverse(u64, u64(0x123456789abcdef1)) == 0x8f7b3d591e6a2c48); |
| 22 | expect(@bitreverse(u128, 0x123456789abcdef11121314151617181) == 0x818e868a828c84888f7b3d591e6a2c48); | 22 | expect(@bitReverse(u128, u128(0x123456789abcdef11121314151617181)) == 0x818e868a828c84888f7b3d591e6a2c48); |
| 23 | 23 | ||
| 24 | // using runtime uints, unsigned | 24 | // using runtime uints, unsigned |
| 25 | var num0: u0 = 0; | 25 | var num0: u0 = 0; |
| 26 | expect(@bitreverse(u0, num0) == 0); | 26 | expect(@bitReverse(u0, num0) == 0); |
| 27 | var num5: u5 = 0x12; | 27 | var num5: u5 = 0x12; |
| 28 | expect(@bitreverse(u5, num5) == 0x9); | 28 | expect(@bitReverse(u5, num5) == 0x9); |
| 29 | var num8: u8 = 0x12; | 29 | var num8: u8 = 0x12; |
| 30 | expect(@bitreverse(u8, num8) == 0x48); | 30 | expect(@bitReverse(u8, num8) == 0x48); |
| 31 | var num16: u16 = 0x1234; | 31 | var num16: u16 = 0x1234; |
| 32 | expect(@bitreverse(u16, num16) == 0x2c48); | 32 | expect(@bitReverse(u16, num16) == 0x2c48); |
| 33 | var num24: u24 = 0x123456; | 33 | var num24: u24 = 0x123456; |
| 34 | expect(@bitreverse(u24, num24) == 0x6a2c48); | 34 | expect(@bitReverse(u24, num24) == 0x6a2c48); |
| 35 | var num32: u32 = 0x12345678; | 35 | var num32: u32 = 0x12345678; |
| 36 | expect(@bitreverse(u32, num32) == 0x1e6a2c48); | 36 | expect(@bitReverse(u32, num32) == 0x1e6a2c48); |
| 37 | var num40: u40 = 0x123456789a; | 37 | var num40: u40 = 0x123456789a; |
| 38 | expect(@bitreverse(u40, num40) == 0x591e6a2c48); | 38 | expect(@bitReverse(u40, num40) == 0x591e6a2c48); |
| 39 | var num48: u48 = 0x123456789abc; | 39 | var num48: u48 = 0x123456789abc; |
| 40 | expect(@bitreverse(u48, num48) == 0x3d591e6a2c48); | 40 | expect(@bitReverse(u48, num48) == 0x3d591e6a2c48); |
| 41 | var num56: u56 = 0x123456789abcde; | 41 | var num56: u56 = 0x123456789abcde; |
| 42 | expect(@bitreverse(u56, num56) == 0x7b3d591e6a2c48); | 42 | expect(@bitReverse(u56, num56) == 0x7b3d591e6a2c48); |
| 43 | var num64: u64 = 0x123456789abcdef1; | 43 | var num64: u64 = 0x123456789abcdef1; |
| 44 | expect(@bitreverse(u64, num64) == 0x8f7b3d591e6a2c48); | 44 | expect(@bitReverse(u64, num64) == 0x8f7b3d591e6a2c48); |
| 45 | var num128: u128 = 0x123456789abcdef11121314151617181; | 45 | var num128: u128 = 0x123456789abcdef11121314151617181; |
| 46 | expect(@bitreverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48); | 46 | expect(@bitReverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48); |
| 47 | 47 | ||
| 48 | // using comptime_ints, signed, positive | 48 | // using comptime_ints, signed, positive |
| 49 | expect(@bitreverse(i0, 0) == 0); | 49 | expect(@bitReverse(u8, u8(0)) == 0); |
| 50 | expect(@bitreverse(i8, @bitCast(i8, u8(0x92))) == @bitCast(i8, u8(0x49))); | 50 | expect(@bitReverse(i8, @bitCast(i8, u8(0x92))) == @bitCast(i8, u8(0x49))); |
| 51 | expect(@bitreverse(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x2c48))); | 51 | expect(@bitReverse(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x2c48))); |
| 52 | expect(@bitreverse(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x6a2c48))); | 52 | expect(@bitReverse(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x6a2c48))); |
| 53 | expect(@bitreverse(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x1e6a2c48))); | 53 | expect(@bitReverse(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x1e6a2c48))); |
| 54 | expect(@bitreverse(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x591e6a2c48))); | 54 | expect(@bitReverse(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x591e6a2c48))); |
| 55 | expect(@bitreverse(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0x3d591e6a2c48))); | 55 | expect(@bitReverse(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0x3d591e6a2c48))); |
| 56 | expect(@bitreverse(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0x7b3d591e6a2c48))); | 56 | expect(@bitReverse(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0x7b3d591e6a2c48))); |
| 57 | expect(@bitreverse(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0x8f7b3d591e6a2c48))); | 57 | expect(@bitReverse(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0x8f7b3d591e6a2c48))); |
| 58 | expect(@bitreverse(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == @bitCast(i128, u128(0x818e868a828c84888f7b3d591e6a2c48))); | 58 | expect(@bitReverse(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == @bitCast(i128, u128(0x818e868a828c84888f7b3d591e6a2c48))); |
| 59 | 59 | ||
| 60 | // using comptime_ints, signed, negative. Compare to runtime ints returned from llvm. | 60 | // using signed, negative. Compare to runtime ints returned from llvm. |
| 61 | var neg5: i5 = minInt(i5) + 1; | ||
| 62 | expect(@bitreverse(i5, minInt(i5) + 1) == @bitreverse(i5, neg5)); | ||
| 63 | var neg8: i8 = -18; | 61 | var neg8: i8 = -18; |
| 64 | expect(@bitreverse(i8, -18) == @bitreverse(i8, neg8)); | 62 | expect(@bitReverse(i8, i8(-18)) == @bitReverse(i8, neg8)); |
| 65 | var neg16: i16 = -32694; | 63 | var neg16: i16 = -32694; |
| 66 | expect(@bitreverse(i16, -32694) == @bitreverse(i16, neg16)); | 64 | expect(@bitReverse(i16, i16(-32694)) == @bitReverse(i16, neg16)); |
| 67 | var neg24: i24 = -6773785; | 65 | var neg24: i24 = -6773785; |
| 68 | expect(@bitreverse(i24, -6773785) == @bitreverse(i24, neg24)); | 66 | expect(@bitReverse(i24, i24(-6773785)) == @bitReverse(i24, neg24)); |
| 69 | var neg32: i32 = -16773785; | 67 | var neg32: i32 = -16773785; |
| 70 | expect(@bitreverse(i32, -16773785) == @bitreverse(i32, neg32)); | 68 | expect(@bitReverse(i32, i32(-16773785)) == @bitReverse(i32, neg32)); |
| 71 | var neg40: i40 = minInt(i40) + 12345; | ||
| 72 | expect(@bitreverse(i40, minInt(i40) + 12345) == @bitreverse(i40, neg40)); | ||
| 73 | var neg48: i48 = minInt(i48) + 12345; | ||
| 74 | expect(@bitreverse(i48, minInt(i48) + 12345) == @bitreverse(i48, neg48)); | ||
| 75 | var neg56: i56 = minInt(i56) + 12345; | ||
| 76 | expect(@bitreverse(i56, minInt(i56) + 12345) == @bitreverse(i56, neg56)); | ||
| 77 | var neg64: i64 = minInt(i64) + 12345; | ||
| 78 | expect(@bitreverse(i64, minInt(i64) + 12345) == @bitreverse(i64, neg64)); | ||
| 79 | var neg128: i128 = minInt(i128) + 12345; | ||
| 80 | expect(@bitreverse(i128, minInt(i128) + 12345) == @bitreverse(i128, neg128)); | ||
| 81 | } | 69 | } |
test/stage1/behavior/bswap.zig deleted-32| ... | @@ -1,32 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const expect = std.testing.expect; | ||
| 3 | |||
| 4 | test "@bswap" { | ||
| 5 | comptime testByteSwap(); | ||
| 6 | testByteSwap(); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn testByteSwap() void { | ||
| 10 | expect(@bswap(u0, 0) == 0); | ||
| 11 | expect(@bswap(u8, 0x12) == 0x12); | ||
| 12 | expect(@bswap(u16, 0x1234) == 0x3412); | ||
| 13 | expect(@bswap(u24, 0x123456) == 0x563412); | ||
| 14 | expect(@bswap(u32, 0x12345678) == 0x78563412); | ||
| 15 | expect(@bswap(u40, 0x123456789a) == 0x9a78563412); | ||
| 16 | expect(@bswap(u48, 0x123456789abc) == 0xbc9a78563412); | ||
| 17 | expect(@bswap(u56, 0x123456789abcde) == 0xdebc9a78563412); | ||
| 18 | expect(@bswap(u64, 0x123456789abcdef1) == 0xf1debc9a78563412); | ||
| 19 | expect(@bswap(u128, 0x123456789abcdef11121314151617181) == 0x8171615141312111f1debc9a78563412); | ||
| 20 | |||
| 21 | expect(@bswap(i0, 0) == 0); | ||
| 22 | expect(@bswap(i8, -50) == -50); | ||
| 23 | expect(@bswap(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x3412))); | ||
| 24 | expect(@bswap(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x563412))); | ||
| 25 | expect(@bswap(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x78563412))); | ||
| 26 | expect(@bswap(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40(0x9a78563412))); | ||
| 27 | expect(@bswap(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0xbc9a78563412))); | ||
| 28 | expect(@bswap(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0xdebc9a78563412))); | ||
| 29 | expect(@bswap(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0xf1debc9a78563412))); | ||
| 30 | expect(@bswap(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == | ||
| 31 | @bitCast(i128, u128(0x8171615141312111f1debc9a78563412))); | ||
| 32 | } | ||
test/stage1/behavior/bugs/2114.zig+1-1| ... | @@ -3,7 +3,7 @@ const expect = std.testing.expect; | ... | @@ -3,7 +3,7 @@ const expect = std.testing.expect; |
| 3 | const math = std.math; | 3 | const math = std.math; |
| 4 | 4 | ||
| 5 | fn ctz(x: var) usize { | 5 | fn ctz(x: var) usize { |
| 6 | return @ctz(x); | 6 | return @ctz(u128, x); |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | test "fixed" { | 9 | test "fixed" { |
test/stage1/behavior/byteswap.zig created+32| ... | @@ -0,0 +1,32 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const expect = std.testing.expect; | ||
| 3 | |||
| 4 | test "@byteSwap" { | ||
| 5 | comptime testByteSwap(); | ||
| 6 | testByteSwap(); | ||
| 7 | } | ||
| 8 | |||
| 9 | fn testByteSwap() void { | ||
| 10 | expect(@byteSwap(u0, u0(0)) == 0); | ||
| 11 | expect(@byteSwap(u8, u8(0x12)) == 0x12); | ||
| 12 | expect(@byteSwap(u16, u16(0x1234)) == 0x3412); | ||
| 13 | expect(@byteSwap(u24, u24(0x123456)) == 0x563412); | ||
| 14 | expect(@byteSwap(u32, u32(0x12345678)) == 0x78563412); | ||
| 15 | expect(@byteSwap(u40, u40(0x123456789a)) == 0x9a78563412); | ||
| 16 | expect(@byteSwap(i48, u48(0x123456789abc)) == @bitCast(i48, u48(0xbc9a78563412))); | ||
| 17 | expect(@byteSwap(u56, u56(0x123456789abcde)) == 0xdebc9a78563412); | ||
| 18 | expect(@byteSwap(u64, u64(0x123456789abcdef1)) == 0xf1debc9a78563412); | ||
| 19 | expect(@byteSwap(u128, u128(0x123456789abcdef11121314151617181)) == 0x8171615141312111f1debc9a78563412); | ||
| 20 | |||
| 21 | expect(@byteSwap(u0, u0(0)) == 0); | ||
| 22 | expect(@byteSwap(i8, i8(-50)) == -50); | ||
| 23 | expect(@byteSwap(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16(0x3412))); | ||
| 24 | expect(@byteSwap(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24(0x563412))); | ||
| 25 | expect(@byteSwap(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32(0x78563412))); | ||
| 26 | expect(@byteSwap(u40, @bitCast(i40, u40(0x123456789a))) == u40(0x9a78563412)); | ||
| 27 | expect(@byteSwap(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48(0xbc9a78563412))); | ||
| 28 | expect(@byteSwap(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56(0xdebc9a78563412))); | ||
| 29 | expect(@byteSwap(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64, u64(0xf1debc9a78563412))); | ||
| 30 | expect(@byteSwap(i128, @bitCast(i128, u128(0x123456789abcdef11121314151617181))) == | ||
| 31 | @bitCast(i128, u128(0x8171615141312111f1debc9a78563412))); | ||
| 32 | } | ||
test/stage1/behavior/math.zig+25-12| ... | @@ -114,15 +114,16 @@ test "@clz" { | ... | @@ -114,15 +114,16 @@ test "@clz" { |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | fn testClz() void { | 116 | fn testClz() void { |
| 117 | expect(clz(u8(0b00001010)) == 4); | 117 | expect(clz(u8, u8(0b10001010)) == 0); |
| 118 | expect(clz(u8(0b10001010)) == 0); | 118 | expect(clz(u8, u8(0b00001010)) == 4); |
| 119 | expect(clz(u8(0b00000000)) == 8); | 119 | expect(clz(u8, u8(0b00011010)) == 3); |
| 120 | expect(clz(u128(0xffffffffffffffff)) == 64); | 120 | expect(clz(u8, u8(0b00000000)) == 8); |
| 121 | expect(clz(u128(0x10000000000000000)) == 63); | 121 | expect(clz(u128, u128(0xffffffffffffffff)) == 64); |
| 122 | expect(clz(u128, u128(0x10000000000000000)) == 63); | ||
| 122 | } | 123 | } |
| 123 | 124 | ||
| 124 | fn clz(x: var) usize { | 125 | fn clz(comptime T: type, x: T) usize { |
| 125 | return @clz(x); | 126 | return @clz(T, x); |
| 126 | } | 127 | } |
| 127 | 128 | ||
| 128 | test "@ctz" { | 129 | test "@ctz" { |
| ... | @@ -131,13 +132,25 @@ test "@ctz" { | ... | @@ -131,13 +132,25 @@ test "@ctz" { |
| 131 | } | 132 | } |
| 132 | 133 | ||
| 133 | fn testCtz() void { | 134 | fn testCtz() void { |
| 134 | expect(ctz(u8(0b10100000)) == 5); | 135 | expect(ctz(u8, u8(0b10100000)) == 5); |
| 135 | expect(ctz(u8(0b10001010)) == 1); | 136 | expect(ctz(u8, u8(0b10001010)) == 1); |
| 136 | expect(ctz(u8(0b00000000)) == 8); | 137 | expect(ctz(u8, u8(0b00000000)) == 8); |
| 138 | expect(ctz(u16, u16(0b00000000)) == 16); | ||
| 137 | } | 139 | } |
| 138 | 140 | ||
| 139 | fn ctz(x: var) usize { | 141 | fn ctz(comptime T: type, x: T) usize { |
| 140 | return @ctz(x); | 142 | return @ctz(T, x); |
| 143 | } | ||
| 144 | |||
| 145 | pub fn Log2Int(comptime T: type) type { | ||
| 146 | // comptime ceil log2 | ||
| 147 | comptime var count = 0; | ||
| 148 | comptime var s = T.bit_count - 1; | ||
| 149 | inline while (s != 0) : (s >>= 1) { | ||
| 150 | count += 1; | ||
| 151 | } | ||
| 152 | |||
| 153 | return @IntType(false, count); | ||
| 141 | } | 154 | } |
| 142 | 155 | ||
| 143 | test "assignment operators" { | 156 | test "assignment operators" { |
test/stage1/behavior/popcount.zig+23-4| ... | @@ -6,20 +6,39 @@ test "@popCount" { | ... | @@ -6,20 +6,39 @@ test "@popCount" { |
| 6 | } | 6 | } |
| 7 | 7 | ||
| 8 | fn testPopCount() void { | 8 | fn testPopCount() void { |
| 9 | { | ||
| 10 | var x: u32 = 0xffffffff; | ||
| 11 | expect(@popCount(u32, x) == 32); | ||
| 12 | } | ||
| 13 | { | ||
| 14 | var x: u5 = 0x1f; | ||
| 15 | expect(@popCount(u5, x) == 5); | ||
| 16 | } | ||
| 9 | { | 17 | { |
| 10 | var x: u32 = 0xaa; | 18 | var x: u32 = 0xaa; |
| 11 | expect(@popCount(x) == 4); | 19 | expect(@popCount(u32, x) == 4); |
| 12 | } | 20 | } |
| 13 | { | 21 | { |
| 14 | var x: u32 = 0xaaaaaaaa; | 22 | var x: u32 = 0xaaaaaaaa; |
| 15 | expect(@popCount(x) == 16); | 23 | expect(@popCount(u32, x) == 16); |
| 24 | } | ||
| 25 | { | ||
| 26 | var x: u32 = 0xaaaaaaaa; | ||
| 27 | expect(@popCount(u32, x) == 16); | ||
| 16 | } | 28 | } |
| 17 | { | 29 | { |
| 18 | var x: i16 = -1; | 30 | var x: i16 = -1; |
| 19 | expect(@popCount(x) == 16); | 31 | expect(@popCount(i16, x) == 16); |
| 32 | } | ||
| 33 | { | ||
| 34 | var x: i8 = -120; | ||
| 35 | expect(@popCount(i8, x) == 2); | ||
| 36 | } | ||
| 37 | comptime { | ||
| 38 | expect(@popCount(u8, @bitCast(u8, i8(-120))) == 2); | ||
| 20 | } | 39 | } |
| 21 | comptime { | 40 | comptime { |
| 22 | expect(@popCount(0b11111111000110001100010000100001000011000011100101010001) == 24); | 41 | expect(@popCount(i128, u128(0b11111111000110001100010000100001000011000011100101010001)) == 24); |
| 23 | } | 42 | } |
| 24 | } | 43 | } |
| 25 | 44 |