authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-01-08 16:50:16-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-01-08 16:50:16-05:00
log027a0c46aef9828ab07d6342030c1ba5b5e4f769
treee796bb65af29fa7ce53a0076e4c0b3e6932385fd
parent1ca983dbd7af661d3f1f840138ecba9dc0a6e372
parent4d5d0d3adad09e9ce34d281327c424de6402fcdb

Merge remote-tracking branch 'origin/master' into llvm8


14 files changed, 365 insertions(+), 26 deletions(-)

doc/langref.html.in+12
...@@ -5316,6 +5316,18 @@ comptime {...@@ -5316,6 +5316,18 @@ comptime {
5316 </p>5316 </p>
5317 {#header_close#}5317 {#header_close#}
53185318
5319 {#header_open|@bitreverse#}
5320 <pre>{#syntax#}@bitreverse(comptime T: type, value: T) T{#endsyntax#}</pre>
5321 <p>{#syntax#}T{#endsyntax#} accepts any integer type.</p>
5322 <p>
5323 Reverses the bitpattern of an integer value, including the sign bit if applicable.
5324 </p>
5325 <p>
5326 For example 0b10110110 ({#syntax#}u8 = 182{#endsyntax#}, {#syntax#}i8 = -74{#endsyntax#})
5327 becomes 0b01101101 ({#syntax#}u8 = 109{#endsyntax#}, {#syntax#}i8 = 109{#endsyntax#}).
5328 </p>
5329 {#header_close#}
5330
5319 {#header_open|@byteOffsetOf#}5331 {#header_open|@byteOffsetOf#}
5320 <pre>{#syntax#}@byteOffsetOf(comptime T: type, comptime field_name: [] const u8) comptime_int{#endsyntax#}</pre>5332 <pre>{#syntax#}@byteOffsetOf(comptime T: type, comptime field_name: [] const u8) comptime_int{#endsyntax#}</pre>
5321 <p>5333 <p>
src/all_types.hpp+14
...@@ -1166,6 +1166,7 @@ struct ZigTypeFn {...@@ -1166,6 +1166,7 @@ struct ZigTypeFn {
1166 FnGenParamInfo *gen_param_info;1166 FnGenParamInfo *gen_param_info;
11671167
1168 LLVMTypeRef raw_type_ref;1168 LLVMTypeRef raw_type_ref;
1169 ZigLLVMDIType *raw_di_type;
11691170
1170 ZigType *bound_fn_parent;1171 ZigType *bound_fn_parent;
1171};1172};
...@@ -1415,6 +1416,7 @@ enum BuiltinFnId {...@@ -1415,6 +1416,7 @@ enum BuiltinFnId {
1415 BuiltinFnIdAtomicRmw,1416 BuiltinFnIdAtomicRmw,
1416 BuiltinFnIdAtomicLoad,1417 BuiltinFnIdAtomicLoad,
1417 BuiltinFnIdBswap,1418 BuiltinFnIdBswap,
1419 BuiltinFnIdBitReverse,
1418};1420};
14191421
1420struct BuiltinFnEntry {1422struct BuiltinFnEntry {
...@@ -1488,6 +1490,7 @@ enum ZigLLVMFnId {...@@ -1488,6 +1490,7 @@ enum ZigLLVMFnId {
1488 ZigLLVMFnIdCeil,1490 ZigLLVMFnIdCeil,
1489 ZigLLVMFnIdSqrt,1491 ZigLLVMFnIdSqrt,
1490 ZigLLVMFnIdBswap,1492 ZigLLVMFnIdBswap,
1493 ZigLLVMFnIdBitReverse,
1491};1494};
14921495
1493enum AddSubMul {1496enum AddSubMul {
...@@ -1520,6 +1523,9 @@ struct ZigLLVMFnKey {...@@ -1520,6 +1523,9 @@ struct ZigLLVMFnKey {
1520 struct {1523 struct {
1521 uint32_t bit_count;1524 uint32_t bit_count;
1522 } bswap;1525 } bswap;
1526 struct {
1527 uint32_t bit_count;
1528 } bit_reverse;
1523 } data;1529 } data;
1524};1530};
15251531
...@@ -2162,6 +2168,7 @@ enum IrInstructionId {...@@ -2162,6 +2168,7 @@ enum IrInstructionId {
2162 IrInstructionIdMarkErrRetTracePtr,2168 IrInstructionIdMarkErrRetTracePtr,
2163 IrInstructionIdSqrt,2169 IrInstructionIdSqrt,
2164 IrInstructionIdBswap,2170 IrInstructionIdBswap,
2171 IrInstructionIdBitReverse,
2165 IrInstructionIdErrSetCast,2172 IrInstructionIdErrSetCast,
2166 IrInstructionIdToBytes,2173 IrInstructionIdToBytes,
2167 IrInstructionIdFromBytes,2174 IrInstructionIdFromBytes,
...@@ -3262,6 +3269,13 @@ struct IrInstructionBswap {...@@ -3262,6 +3269,13 @@ struct IrInstructionBswap {
3262 IrInstruction *op;3269 IrInstruction *op;
3263};3270};
32643271
3272struct IrInstructionBitReverse {
3273 IrInstruction base;
3274
3275 IrInstruction *type;
3276 IrInstruction *op;
3277};
3278
3265static const size_t slice_ptr_index = 0;3279static const size_t slice_ptr_index = 0;
3266static const size_t slice_len_index = 1;3280static const size_t slice_len_index = 1;
32673281
src/analyze.cpp+8-1
...@@ -1220,7 +1220,10 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1220,7 +1220,10 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1220 fn_type->data.fn.raw_type_ref = LLVMFunctionType(gen_return_type->type_ref,1220 fn_type->data.fn.raw_type_ref = LLVMFunctionType(gen_return_type->type_ref,
1221 gen_param_types.items, (unsigned int)gen_param_types.length, fn_type_id->is_var_args);1221 gen_param_types.items, (unsigned int)gen_param_types.length, fn_type_id->is_var_args);
1222 fn_type->type_ref = LLVMPointerType(fn_type->data.fn.raw_type_ref, 0);1222 fn_type->type_ref = LLVMPointerType(fn_type->data.fn.raw_type_ref, 0);
1223 fn_type->di_type = ZigLLVMCreateSubroutineType(g->dbuilder, param_di_types.items, (int)param_di_types.length, 0);1223 fn_type->data.fn.raw_di_type = ZigLLVMCreateSubroutineType(g->dbuilder, param_di_types.items, (int)param_di_types.length, 0);
1224 fn_type->di_type = ZigLLVMCreateDebugPointerType(g->dbuilder, fn_type->data.fn.raw_di_type,
1225 LLVMStoreSizeOfType(g->target_data_ref, fn_type->type_ref),
1226 LLVMABIAlignmentOfType(g->target_data_ref, fn_type->type_ref), "");
1224 }1227 }
12251228
1226 g->fn_type_table.put(&fn_type->data.fn.fn_type_id, fn_type);1229 g->fn_type_table.put(&fn_type->data.fn.fn_type_id, fn_type);
...@@ -6121,6 +6124,8 @@ uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) {...@@ -6121,6 +6124,8 @@ uint32_t zig_llvm_fn_key_hash(ZigLLVMFnKey x) {
6121 return (uint32_t)(x.data.floating.bit_count) * (uint32_t)2225366385;6124 return (uint32_t)(x.data.floating.bit_count) * (uint32_t)2225366385;
6122 case ZigLLVMFnIdBswap:6125 case ZigLLVMFnIdBswap:
6123 return (uint32_t)(x.data.bswap.bit_count) * (uint32_t)3661994335;6126 return (uint32_t)(x.data.bswap.bit_count) * (uint32_t)3661994335;
6127 case ZigLLVMFnIdBitReverse:
6128 return (uint32_t)(x.data.bit_reverse.bit_count) * (uint32_t)2621398431;
6124 case ZigLLVMFnIdOverflowArithmetic:6129 case ZigLLVMFnIdOverflowArithmetic:
6125 return ((uint32_t)(x.data.overflow_arithmetic.bit_count) * 87135777) +6130 return ((uint32_t)(x.data.overflow_arithmetic.bit_count) * 87135777) +
6126 ((uint32_t)(x.data.overflow_arithmetic.add_sub_mul) * 31640542) +6131 ((uint32_t)(x.data.overflow_arithmetic.add_sub_mul) * 31640542) +
...@@ -6141,6 +6146,8 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {...@@ -6141,6 +6146,8 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
6141 return a.data.pop_count.bit_count == b.data.pop_count.bit_count;6146 return a.data.pop_count.bit_count == b.data.pop_count.bit_count;
6142 case ZigLLVMFnIdBswap:6147 case ZigLLVMFnIdBswap:
6143 return a.data.bswap.bit_count == b.data.bswap.bit_count;6148 return a.data.bswap.bit_count == b.data.bswap.bit_count;
6149 case ZigLLVMFnIdBitReverse:
6150 return a.data.bit_reverse.bit_count == b.data.bit_reverse.bit_count;
6144 case ZigLLVMFnIdFloor:6151 case ZigLLVMFnIdFloor:
6145 case ZigLLVMFnIdCeil:6152 case ZigLLVMFnIdCeil:
6146 case ZigLLVMFnIdSqrt:6153 case ZigLLVMFnIdSqrt:
src/bigint.cpp+1
...@@ -1722,3 +1722,4 @@ void bigint_incr(BigInt *x) {...@@ -1722,3 +1722,4 @@ void bigint_incr(BigInt *x) {
17221722
1723 bigint_add(x, &copy, &one);1723 bigint_add(x, &copy, &one);
1724}1724}
1725
src/codegen.cpp+17-1
...@@ -649,7 +649,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {...@@ -649,7 +649,7 @@ static ZigLLVMDIScope *get_di_scope(CodeGen *g, Scope *scope) {
649 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,649 ZigLLVMDISubprogram *subprogram = ZigLLVMCreateFunction(g->dbuilder,
650 fn_di_scope, buf_ptr(&fn_table_entry->symbol_name), "",650 fn_di_scope, buf_ptr(&fn_table_entry->symbol_name), "",
651 import->di_file, line_number,651 import->di_file, line_number,
652 fn_table_entry->type_entry->di_type, is_internal_linkage,652 fn_table_entry->type_entry->data.fn.raw_di_type, is_internal_linkage,
653 is_definition, scope_line, flags, is_optimized, nullptr);653 is_definition, scope_line, flags, is_optimized, nullptr);
654654
655 scope->di_scope = ZigLLVMSubprogramToScope(subprogram);655 scope->di_scope = ZigLLVMSubprogramToScope(subprogram);
...@@ -3789,6 +3789,11 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI...@@ -3789,6 +3789,11 @@ static LLVMValueRef get_int_builtin_fn(CodeGen *g, ZigType *int_type, BuiltinFnI
3789 n_args = 1;3789 n_args = 1;
3790 key.id = ZigLLVMFnIdBswap;3790 key.id = ZigLLVMFnIdBswap;
3791 key.data.bswap.bit_count = (uint32_t)int_type->data.integral.bit_count;3791 key.data.bswap.bit_count = (uint32_t)int_type->data.integral.bit_count;
3792 } else if (fn_id == BuiltinFnIdBitReverse) {
3793 fn_name = "bitreverse";
3794 n_args = 1;
3795 key.id = ZigLLVMFnIdBitReverse;
3796 key.data.bit_reverse.bit_count = (uint32_t)int_type->data.integral.bit_count;
3792 } else {3797 } else {
3793 zig_unreachable();3798 zig_unreachable();
3794 }3799 }
...@@ -5096,6 +5101,14 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutable *executable, IrInst...@@ -5096,6 +5101,14 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, IrExecutable *executable, IrInst
5096 return LLVMBuildTrunc(g->builder, shifted, int_type->type_ref, "");5101 return LLVMBuildTrunc(g->builder, shifted, int_type->type_ref, "");
5097}5102}
50985103
5104static LLVMValueRef ir_render_bit_reverse(CodeGen *g, IrExecutable *executable, IrInstructionBitReverse *instruction) {
5105 LLVMValueRef op = ir_llvm_value(g, instruction->op);
5106 ZigType *int_type = instruction->base.value.type;
5107 assert(int_type->id == ZigTypeIdInt);
5108 LLVMValueRef fn_val = get_int_builtin_fn(g, instruction->base.value.type, BuiltinFnIdBitReverse);
5109 return LLVMBuildCall(g->builder, fn_val, &op, 1, "");
5110}
5111
5099static void set_debug_location(CodeGen *g, IrInstruction *instruction) {5112static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
5100 AstNode *source_node = instruction->source_node;5113 AstNode *source_node = instruction->source_node;
5101 Scope *scope = instruction->scope;5114 Scope *scope = instruction->scope;
...@@ -5335,6 +5348,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -5335,6 +5348,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
5335 return ir_render_sqrt(g, executable, (IrInstructionSqrt *)instruction);5348 return ir_render_sqrt(g, executable, (IrInstructionSqrt *)instruction);
5336 case IrInstructionIdBswap:5349 case IrInstructionIdBswap:
5337 return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction);5350 return ir_render_bswap(g, executable, (IrInstructionBswap *)instruction);
5351 case IrInstructionIdBitReverse:
5352 return ir_render_bit_reverse(g, executable, (IrInstructionBitReverse *)instruction);
5338 }5353 }
5339 zig_unreachable();5354 zig_unreachable();
5340}5355}
...@@ -6758,6 +6773,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -6758,6 +6773,7 @@ static void define_builtin_fns(CodeGen *g) {
6758 create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);6773 create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);
6759 create_builtin_fn(g, BuiltinFnIdThis, "This", 0);6774 create_builtin_fn(g, BuiltinFnIdThis, "This", 0);
6760 create_builtin_fn(g, BuiltinFnIdBswap, "bswap", 2);6775 create_builtin_fn(g, BuiltinFnIdBswap, "bswap", 2);
6776 create_builtin_fn(g, BuiltinFnIdBitReverse, "bitreverse", 2);
6761}6777}
67626778
6763static const char *bool_to_str(bool b) {6779static const char *bool_to_str(bool b) {
src/ir.cpp+128-20
...@@ -861,6 +861,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) {...@@ -861,6 +861,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionBswap *) {
861 return IrInstructionIdBswap;861 return IrInstructionIdBswap;
862}862}
863863
864static constexpr IrInstructionId ir_instruction_id(IrInstructionBitReverse *) {
865 return IrInstructionIdBitReverse;
866}
867
864static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) {868static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) {
865 return IrInstructionIdCheckRuntimeScope;869 return IrInstructionIdCheckRuntimeScope;
866}870}
...@@ -2721,6 +2725,17 @@ static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *sour...@@ -2721,6 +2725,17 @@ static IrInstruction *ir_build_bswap(IrBuilder *irb, Scope *scope, AstNode *sour
2721 return &instruction->base;2725 return &instruction->base;
2722}2726}
27232727
2728static IrInstruction *ir_build_bit_reverse(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) {
2729 IrInstructionBitReverse *instruction = ir_build_instruction<IrInstructionBitReverse>(irb, scope, source_node);
2730 instruction->type = type;
2731 instruction->op = op;
2732
2733 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block);
2734 ir_ref_instruction(op, irb->current_basic_block);
2735
2736 return &instruction->base;
2737}
2738
2724static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) {2739static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) {
2725 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node);2740 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node);
2726 instruction->scope_is_comptime = scope_is_comptime;2741 instruction->scope_is_comptime = scope_is_comptime;
...@@ -3646,7 +3661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -3646,7 +3661,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
3646 Buf *name = fn_ref_expr->data.symbol_expr.symbol;3661 Buf *name = fn_ref_expr->data.symbol_expr.symbol;
3647 auto entry = irb->codegen->builtin_fn_table.maybe_get(name);3662 auto entry = irb->codegen->builtin_fn_table.maybe_get(name);
36483663
3649 if (!entry) {3664 if (!entry) { // new built in not found
3650 add_node_error(irb->codegen, node,3665 add_node_error(irb->codegen, node,
3651 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name)));3666 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name)));
3652 return irb->codegen->invalid_instruction;3667 return irb->codegen->invalid_instruction;
...@@ -4720,6 +4735,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -4720,6 +4735,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
4720 IrInstruction *result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value);4735 IrInstruction *result = ir_build_bswap(irb, scope, node, arg0_value, arg1_value);
4721 return ir_lval_wrap(irb, scope, result, lval);4736 return ir_lval_wrap(irb, scope, result, lval);
4722 }4737 }
4738 case BuiltinFnIdBitReverse:
4739 {
4740 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4741 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
4742 if (arg0_value == irb->codegen->invalid_instruction)
4743 return arg0_value;
4744
4745 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4746 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
4747 if (arg1_value == irb->codegen->invalid_instruction)
4748 return arg1_value;
4749
4750 IrInstruction *result = ir_build_bit_reverse(irb, scope, node, arg0_value, arg1_value);
4751 return ir_lval_wrap(irb, scope, result, lval);
4752 }
4723 }4753 }
4724 zig_unreachable();4754 zig_unreachable();
4725}4755}
...@@ -14547,8 +14577,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_...@@ -14547,8 +14577,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
14547 return ira->codegen->invalid_instruction;14577 return ira->codegen->invalid_instruction;
14548 if (type_is_invalid(struct_val->type))14578 if (type_is_invalid(struct_val->type))
14549 return ira->codegen->invalid_instruction;14579 return ira->codegen->invalid_instruction;
14550 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index];14580 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry,
14551 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type,
14552 is_const, is_volatile, PtrLenSingle, align_bytes,14581 is_const, is_volatile, PtrLenSingle, align_bytes,
14553 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),14582 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host),
14554 (uint32_t)host_int_bytes_for_result_type);14583 (uint32_t)host_int_bytes_for_result_type);
...@@ -16853,16 +16882,12 @@ static void ensure_field_index(ZigType *type, const char *field_name, size_t ind...@@ -16853,16 +16882,12 @@ static void ensure_field_index(ZigType *type, const char *field_name, size_t ind
1685316882
16854static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, ZigType *root) {16883static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, ZigType *root) {
16855 Error err;16884 Error err;
16856 static ConstExprValue *type_info_var = nullptr; // TODO oops this global variable made it past code review16885 ConstExprValue *type_info_var = get_builtin_value(ira->codegen, "TypeInfo");
16857 static ZigType *type_info_type = nullptr; // TODO oops this global variable made it past code review16886 assert(type_info_var->type->id == ZigTypeIdMetaType);
16858 if (type_info_var == nullptr) {16887 assertNoError(ensure_complete_type(ira->codegen, type_info_var->data.x_type));
16859 type_info_var = get_builtin_value(ira->codegen, "TypeInfo");
16860 assert(type_info_var->type->id == ZigTypeIdMetaType);
1686116888
16862 assertNoError(ensure_complete_type(ira->codegen, type_info_var->data.x_type));16889 ZigType *type_info_type = type_info_var->data.x_type;
16863 type_info_type = type_info_var->data.x_type;16890 assert(type_info_type->id == ZigTypeIdUnion);
16864 assert(type_info_type->id == ZigTypeIdUnion);
16865 }
1686616891
16867 if (type_name == nullptr && root == nullptr)16892 if (type_name == nullptr && root == nullptr)
16868 return type_info_type;16893 return type_info_type;
...@@ -17075,12 +17100,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco...@@ -17075,12 +17100,7 @@ static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, Sco
17075 ensure_field_index(fn_def_val->type, "return_type", 7);17100 ensure_field_index(fn_def_val->type, "return_type", 7);
17076 fn_def_fields[7].special = ConstValSpecialStatic;17101 fn_def_fields[7].special = ConstValSpecialStatic;
17077 fn_def_fields[7].type = ira->codegen->builtin_types.entry_type;17102 fn_def_fields[7].type = ira->codegen->builtin_types.entry_type;
17078 if (fn_entry->src_implicit_return_type != nullptr)17103 fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;
17079 fn_def_fields[7].data.x_type = fn_entry->src_implicit_return_type;
17080 else if (fn_entry->type_entry->data.fn.gen_return_type != nullptr)
17081 fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.gen_return_type;
17082 else
17083 fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type;
17084 // arg_names: [][] const u817104 // arg_names: [][] const u8
17085 ensure_field_index(fn_def_val->type, "arg_names", 8);17105 ensure_field_index(fn_def_val->type, "arg_names", 8);
17086 size_t fn_arg_count = fn_entry->variable_list.length;17106 size_t fn_arg_count = fn_entry->variable_list.length;
...@@ -20150,8 +20170,29 @@ static Error buf_read_value_bytes(IrAnalyze *ira, AstNode *source_node, uint8_t...@@ -20150,8 +20170,29 @@ static Error buf_read_value_bytes(IrAnalyze *ira, AstNode *source_node, uint8_t
20150 val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&bn);20170 val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&bn);
20151 return ErrorNone;20171 return ErrorNone;
20152 }20172 }
20153 case ZigTypeIdArray:20173 case ZigTypeIdArray: {
20154 zig_panic("TODO buf_read_value_bytes array type");20174 uint64_t elem_size = type_size(ira->codegen, val->type->data.array.child_type);
20175 size_t len = val->type->data.array.len;
20176
20177 switch (val->data.x_array.special) {
20178 case ConstArraySpecialNone:
20179 val->data.x_array.data.s_none.elements = create_const_vals(len);
20180 for (size_t i = 0; i < len; i++) {
20181 ConstExprValue *elem = &val->data.x_array.data.s_none.elements[i];
20182 elem->special = ConstValSpecialStatic;
20183 elem->type = val->type->data.array.child_type;
20184 if ((err = buf_read_value_bytes(ira, source_node, buf + (elem_size * i), elem)))
20185 return err;
20186 }
20187 break;
20188 case ConstArraySpecialUndef:
20189 zig_panic("TODO buf_read_value_bytes ConstArraySpecialUndef array type");
20190 case ConstArraySpecialBuf:
20191 zig_panic("TODO buf_read_value_bytes ConstArraySpecialBuf array type");
20192 }
20193
20194 return ErrorNone;
20195 }
20155 case ZigTypeIdStruct:20196 case ZigTypeIdStruct:
20156 switch (val->type->data.structure.layout) {20197 switch (val->type->data.structure.layout) {
20157 case ContainerLayoutAuto: {20198 case ContainerLayoutAuto: {
...@@ -20333,6 +20374,7 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru...@@ -20333,6 +20374,7 @@ static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstru
2033320374
20334 IrInstruction *result = ir_const(ira, &instruction->base, dest_type);20375 IrInstruction *result = ir_const(ira, &instruction->base, dest_type);
20335 result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr;20376 result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr;
20377 result->value.data.x_ptr.mut = ConstPtrMutRuntimeVar;
20336 result->value.data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&val->data.x_bigint);20378 result->value.data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&val->data.x_bigint);
20337 return result;20379 return result;
20338 }20380 }
...@@ -21115,6 +21157,69 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction...@@ -21115,6 +21157,69 @@ static IrInstruction *ir_analyze_instruction_bswap(IrAnalyze *ira, IrInstruction
21115 return result;21157 return result;
21116}21158}
2111721159
21160static IrInstruction *ir_analyze_instruction_bit_reverse(IrAnalyze *ira, IrInstructionBitReverse *instruction) {
21161 ZigType *int_type = ir_resolve_type(ira, instruction->type->child);
21162 if (type_is_invalid(int_type))
21163 return ira->codegen->invalid_instruction;
21164
21165 IrInstruction *op = instruction->op->child;
21166 if (type_is_invalid(op->value.type))
21167 return ira->codegen->invalid_instruction;
21168
21169 if (int_type->id != ZigTypeIdInt) {
21170 ir_add_error(ira, instruction->type,
21171 buf_sprintf("expected integer type, found '%s'", buf_ptr(&int_type->name)));
21172 return ira->codegen->invalid_instruction;
21173 }
21174
21175 IrInstruction *casted_op = ir_implicit_cast(ira, op, int_type);
21176 if (type_is_invalid(casted_op->value.type))
21177 return ira->codegen->invalid_instruction;
21178
21179 if (int_type->data.integral.bit_count == 0) {
21180 IrInstruction *result = ir_const(ira, &instruction->base, int_type);
21181 bigint_init_unsigned(&result->value.data.x_bigint, 0);
21182 return result;
21183 }
21184
21185 if (instr_is_comptime(casted_op)) {
21186 ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad);
21187 if (!val)
21188 return ira->codegen->invalid_instruction;
21189
21190 IrInstruction *result = ir_const(ira, &instruction->base, int_type);
21191 size_t num_bits = int_type->data.integral.bit_count;
21192 size_t buf_size = (num_bits + 7) / 8;
21193 uint8_t *comptime_buf = allocate_nonzero<uint8_t>(buf_size);
21194 uint8_t *result_buf = allocate_nonzero<uint8_t>(buf_size);
21195 memset(comptime_buf,0,buf_size);
21196 memset(result_buf,0,buf_size);
21197
21198 bigint_write_twos_complement(&val->data.x_bigint,comptime_buf,num_bits,ira->codegen->is_big_endian);
21199
21200 size_t bit_i = 0;
21201 size_t bit_rev_i = num_bits - 1;
21202 for (; bit_i < num_bits; bit_i++, bit_rev_i--) {
21203 if (comptime_buf[bit_i / 8] & (1 << (bit_i % 8))) {
21204 result_buf[bit_rev_i / 8] |= (1 << (bit_rev_i % 8));
21205 }
21206 }
21207
21208 bigint_read_twos_complement(&result->value.data.x_bigint,
21209 result_buf,
21210 int_type->data.integral.bit_count,
21211 ira->codegen->is_big_endian,
21212 int_type->data.integral.is_signed);
21213
21214 return result;
21215 }
21216
21217 IrInstruction *result = ir_build_bit_reverse(&ira->new_irb, instruction->base.scope,
21218 instruction->base.source_node, nullptr, casted_op);
21219 result->value.type = int_type;
21220 return result;
21221}
21222
2111821223
21119static IrInstruction *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstructionEnumToInt *instruction) {21224static IrInstruction *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstructionEnumToInt *instruction) {
21120 Error err;21225 Error err;
...@@ -21453,6 +21558,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio...@@ -21453,6 +21558,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
21453 return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction);21558 return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction);
21454 case IrInstructionIdBswap:21559 case IrInstructionIdBswap:
21455 return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction);21560 return ir_analyze_instruction_bswap(ira, (IrInstructionBswap *)instruction);
21561 case IrInstructionIdBitReverse:
21562 return ir_analyze_instruction_bit_reverse(ira, (IrInstructionBitReverse *)instruction);
21456 case IrInstructionIdIntToErr:21563 case IrInstructionIdIntToErr:
21457 return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction);21564 return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction);
21458 case IrInstructionIdErrToInt:21565 case IrInstructionIdErrToInt:
...@@ -21675,6 +21782,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -21675,6 +21782,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
21675 case IrInstructionIdPromiseResultType:21782 case IrInstructionIdPromiseResultType:
21676 case IrInstructionIdSqrt:21783 case IrInstructionIdSqrt:
21677 case IrInstructionIdBswap:21784 case IrInstructionIdBswap:
21785 case IrInstructionIdBitReverse:
21678 case IrInstructionIdAtomicLoad:21786 case IrInstructionIdAtomicLoad:
21679 case IrInstructionIdIntCast:21787 case IrInstructionIdIntCast:
21680 case IrInstructionIdFloatCast:21788 case IrInstructionIdFloatCast:
src/ir_print.cpp+15
...@@ -1335,6 +1335,18 @@ static void ir_print_bswap(IrPrint *irp, IrInstructionBswap *instruction) {...@@ -1335,6 +1335,18 @@ static void ir_print_bswap(IrPrint *irp, IrInstructionBswap *instruction) {
1335 fprintf(irp->f, ")");1335 fprintf(irp->f, ")");
1336}1336}
13371337
1338static void ir_print_bit_reverse(IrPrint *irp, IrInstructionBitReverse *instruction) {
1339 fprintf(irp->f, "@bitreverse(");
1340 if (instruction->type != nullptr) {
1341 ir_print_other_instruction(irp, instruction->type);
1342 } else {
1343 fprintf(irp->f, "null");
1344 }
1345 fprintf(irp->f, ",");
1346 ir_print_other_instruction(irp, instruction->op);
1347 fprintf(irp->f, ")");
1348}
1349
1338static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {1350static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1339 ir_print_prefix(irp, instruction);1351 ir_print_prefix(irp, instruction);
1340 switch (instruction->id) {1352 switch (instruction->id) {
...@@ -1751,6 +1763,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1751,6 +1763,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1751 case IrInstructionIdBswap:1763 case IrInstructionIdBswap:
1752 ir_print_bswap(irp, (IrInstructionBswap *)instruction);1764 ir_print_bswap(irp, (IrInstructionBswap *)instruction);
1753 break;1765 break;
1766 case IrInstructionIdBitReverse:
1767 ir_print_bit_reverse(irp, (IrInstructionBitReverse *)instruction);
1768 break;
1754 case IrInstructionIdAtomicLoad:1769 case IrInstructionIdAtomicLoad:
1755 ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction);1770 ir_print_atomic_load(irp, (IrInstructionAtomicLoad *)instruction);
1756 break;1771 break;
std/c/freebsd.zig+27
...@@ -22,6 +22,8 @@ pub extern "c" fn openat(fd: c_int, path: ?[*]const u8, flags: c_int) c_int;...@@ -22,6 +22,8 @@ pub extern "c" fn openat(fd: c_int, path: ?[*]const u8, flags: c_int) c_int;
22pub extern "c" fn setgid(ruid: c_uint, euid: c_uint) c_int;22pub extern "c" fn setgid(ruid: c_uint, euid: c_uint) c_int;
23pub extern "c" fn setuid(uid: c_uint) c_int;23pub extern "c" fn setuid(uid: c_uint) c_int;
24pub extern "c" fn kill(pid: c_int, sig: c_int) c_int;24pub extern "c" fn kill(pid: c_int, sig: c_int) c_int;
25pub extern "c" fn clock_gettime(clk_id: c_int, tp: *timespec) c_int;
26pub extern "c" fn clock_getres(clk_id: c_int, tp: *timespec) c_int;
2527
26/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.28/// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
27pub const Kevent = extern struct {29pub const Kevent = extern struct {
...@@ -91,3 +93,28 @@ pub const dirent = extern struct {...@@ -91,3 +93,28 @@ pub const dirent = extern struct {
91 d_pad1: u16,93 d_pad1: u16,
92 d_name: [256]u8,94 d_name: [256]u8,
93};95};
96
97pub const in_port_t = u16;
98pub const sa_family_t = u16;
99
100pub const sockaddr = extern union {
101 in: sockaddr_in,
102 in6: sockaddr_in6,
103};
104
105pub const sockaddr_in = extern struct {
106 len: u8,
107 family: sa_family_t,
108 port: in_port_t,
109 addr: [16]u8,
110 zero: [8]u8,
111};
112
113pub const sockaddr_in6 = extern struct {
114 len: u8,
115 family: sa_family_t,
116 port: in_port_t,
117 flowinfo: u32,
118 addr: [16]u8,
119 scope_id: u32,
120};
std/os/freebsd/index.zig+27
...@@ -26,6 +26,21 @@ pub const PROT_READ = 1;...@@ -26,6 +26,21 @@ pub const PROT_READ = 1;
26pub const PROT_WRITE = 2;26pub const PROT_WRITE = 2;
27pub const PROT_EXEC = 4;27pub const PROT_EXEC = 4;
2828
29pub const CLOCK_REALTIME = 0;
30pub const CLOCK_VIRTUAL = 1;
31pub const CLOCK_PROF = 2;
32pub const CLOCK_MONOTONIC = 4;
33pub const CLOCK_UPTIME = 5;
34pub const CLOCK_UPTIME_PRECISE = 7;
35pub const CLOCK_UPTIME_FAST = 8;
36pub const CLOCK_REALTIME_PRECISE = 9;
37pub const CLOCK_REALTIME_FAST = 10;
38pub const CLOCK_MONOTONIC_PRECISE = 11;
39pub const CLOCK_MONOTONIC_FAST = 12;
40pub const CLOCK_SECOND = 13;
41pub const CLOCK_THREAD_CPUTIME_ID = 14;
42pub const CLOCK_PROCESS_CPUTIME_ID = 15;
43
29pub const MAP_FAILED = maxInt(usize);44pub const MAP_FAILED = maxInt(usize);
30pub const MAP_SHARED = 0x0001;45pub const MAP_SHARED = 0x0001;
31pub const MAP_PRIVATE = 0x0002;46pub const MAP_PRIVATE = 0x0002;
...@@ -510,6 +525,10 @@ pub const TIOCGPKT = 0x80045438;...@@ -510,6 +525,10 @@ pub const TIOCGPKT = 0x80045438;
510pub const TIOCGPTLCK = 0x80045439;525pub const TIOCGPTLCK = 0x80045439;
511pub const TIOCGEXCL = 0x80045440;526pub const TIOCGEXCL = 0x80045440;
512527
528pub const sockaddr = c.sockaddr;
529pub const sockaddr_in = c.sockaddr_in;
530pub const sockaddr_in6 = c.sockaddr_in6;
531
513fn unsigned(s: i32) u32 {532fn unsigned(s: i32) u32 {
514 return @bitCast(u32, s);533 return @bitCast(u32, s);
515}534}
...@@ -699,6 +718,14 @@ pub fn nanosleep(req: *const timespec, rem: ?*timespec) usize {...@@ -699,6 +718,14 @@ pub fn nanosleep(req: *const timespec, rem: ?*timespec) usize {
699 return errnoWrap(c.nanosleep(req, rem));718 return errnoWrap(c.nanosleep(req, rem));
700}719}
701720
721pub fn clock_gettime(clk_id: i32, tp: *timespec) usize {
722 return errnoWrap(c.clock_gettime(clk_id, tp));
723}
724
725pub fn clock_getres(clk_id: i32, tp: *timespec) usize {
726 return errnoWrap(c.clock_getres(clk_id, tp));
727}
728
702pub fn setuid(uid: u32) usize {729pub fn setuid(uid: u32) usize {
703 return errnoWrap(c.setuid(uid));730 return errnoWrap(c.setuid(uid));
704}731}
std/os/time.zig+4-4
...@@ -61,7 +61,7 @@ pub fn timestamp() u64 {...@@ -61,7 +61,7 @@ pub fn timestamp() u64 {
61/// Get the posix timestamp, UTC, in milliseconds61/// Get the posix timestamp, UTC, in milliseconds
62pub const milliTimestamp = switch (builtin.os) {62pub const milliTimestamp = switch (builtin.os) {
63 Os.windows => milliTimestampWindows,63 Os.windows => milliTimestampWindows,
64 Os.linux => milliTimestampPosix,64 Os.linux, Os.freebsd => milliTimestampPosix,
65 Os.macosx, Os.ios => milliTimestampDarwin,65 Os.macosx, Os.ios => milliTimestampDarwin,
66 else => @compileError("Unsupported OS"),66 else => @compileError("Unsupported OS"),
67};67};
...@@ -179,7 +179,7 @@ pub const Timer = struct {...@@ -179,7 +179,7 @@ pub const Timer = struct {
179 debug.assert(err != windows.FALSE);179 debug.assert(err != windows.FALSE);
180 self.start_time = @intCast(u64, start_time);180 self.start_time = @intCast(u64, start_time);
181 },181 },
182 Os.linux => {182 Os.linux, Os.freebsd => {
183 //On Linux, seccomp can do arbitrary things to our ability to call183 //On Linux, seccomp can do arbitrary things to our ability to call
184 // syscalls, including return any errno value it wants and184 // syscalls, including return any errno value it wants and
185 // inconsistently throwing errors. Since we can't account for185 // inconsistently throwing errors. Since we can't account for
...@@ -215,7 +215,7 @@ pub const Timer = struct {...@@ -215,7 +215,7 @@ pub const Timer = struct {
215 var clock = clockNative() - self.start_time;215 var clock = clockNative() - self.start_time;
216 return switch (builtin.os) {216 return switch (builtin.os) {
217 Os.windows => @divFloor(clock * ns_per_s, self.frequency),217 Os.windows => @divFloor(clock * ns_per_s, self.frequency),
218 Os.linux => clock,218 Os.linux, Os.freebsd => clock,
219 Os.macosx, Os.ios => @divFloor(clock * self.frequency.numer, self.frequency.denom),219 Os.macosx, Os.ios => @divFloor(clock * self.frequency.numer, self.frequency.denom),
220 else => @compileError("Unsupported OS"),220 else => @compileError("Unsupported OS"),
221 };221 };
...@@ -236,7 +236,7 @@ pub const Timer = struct {...@@ -236,7 +236,7 @@ pub const Timer = struct {
236236
237 const clockNative = switch (builtin.os) {237 const clockNative = switch (builtin.os) {
238 Os.windows => clockWindows,238 Os.windows => clockWindows,
239 Os.linux => clockLinux,239 Os.linux, Os.freebsd => clockLinux,
240 Os.macosx, Os.ios => clockDarwin,240 Os.macosx, Os.ios => clockDarwin,
241 else => @compileError("Unsupported OS"),241 else => @compileError("Unsupported OS"),
242 };242 };
test/behavior.zig+1
...@@ -9,6 +9,7 @@ comptime {...@@ -9,6 +9,7 @@ comptime {
9 _ = @import("cases/bitcast.zig");9 _ = @import("cases/bitcast.zig");
10 _ = @import("cases/bool.zig");10 _ = @import("cases/bool.zig");
11 _ = @import("cases/bswap.zig");11 _ = @import("cases/bswap.zig");
12 _ = @import("cases/bitreverse.zig");
12 _ = @import("cases/bugs/1076.zig");13 _ = @import("cases/bugs/1076.zig");
13 _ = @import("cases/bugs/1111.zig");14 _ = @import("cases/bugs/1111.zig");
14 _ = @import("cases/bugs/1277.zig");15 _ = @import("cases/bugs/1277.zig");
test/cases/bitreverse.zig created+81
...@@ -0,0 +1,81 @@
1const std = @import("std");
2const assert = std.debug.assert;
3const minInt = std.math.minInt;
4
5test "@bitreverse" {
6 comptime testBitReverse();
7 testBitReverse();
8}
9
10fn testBitReverse() void {
11 // using comptime_ints, unsigned
12 assert(@bitreverse(u0, 0) == 0);
13 assert(@bitreverse(u5, 0x12) == 0x9);
14 assert(@bitreverse(u8, 0x12) == 0x48);
15 assert(@bitreverse(u16, 0x1234) == 0x2c48);
16 assert(@bitreverse(u24, 0x123456) == 0x6a2c48);
17 assert(@bitreverse(u32, 0x12345678) == 0x1e6a2c48);
18 assert(@bitreverse(u40, 0x123456789a) == 0x591e6a2c48);
19 assert(@bitreverse(u48, 0x123456789abc) == 0x3d591e6a2c48);
20 assert(@bitreverse(u56, 0x123456789abcde) == 0x7b3d591e6a2c48);
21 assert(@bitreverse(u64, 0x123456789abcdef1) == 0x8f7b3d591e6a2c48);
22 assert(@bitreverse(u128, 0x123456789abcdef11121314151617181) == 0x818e868a828c84888f7b3d591e6a2c48);
23
24 // using runtime uints, unsigned
25 var num0: u0 = 0;
26 assert(@bitreverse(u0, num0) == 0);
27 var num5: u5 = 0x12;
28 assert(@bitreverse(u5, num5) == 0x9);
29 var num8: u8 = 0x12;
30 assert(@bitreverse(u8, num8) == 0x48);
31 var num16: u16 = 0x1234;
32 assert(@bitreverse(u16, num16) == 0x2c48);
33 var num24: u24 = 0x123456;
34 assert(@bitreverse(u24, num24) == 0x6a2c48);
35 var num32: u32 = 0x12345678;
36 assert(@bitreverse(u32, num32) == 0x1e6a2c48);
37 var num40: u40 = 0x123456789a;
38 assert(@bitreverse(u40, num40) == 0x591e6a2c48);
39 var num48: u48 = 0x123456789abc;
40 assert(@bitreverse(u48, num48) == 0x3d591e6a2c48);
41 var num56: u56 = 0x123456789abcde;
42 assert(@bitreverse(u56, num56) == 0x7b3d591e6a2c48);
43 var num64: u64 = 0x123456789abcdef1;
44 assert(@bitreverse(u64, num64) == 0x8f7b3d591e6a2c48);
45 var num128: u128 = 0x123456789abcdef11121314151617181;
46 assert(@bitreverse(u128, num128) == 0x818e868a828c84888f7b3d591e6a2c48);
47
48 // using comptime_ints, signed, positive
49 assert(@bitreverse(i0, 0) == 0);
50 assert(@bitreverse(i8, @bitCast(i8, u8(0x92))) == @bitCast(i8, u8( 0x49)));
51 assert(@bitreverse(i16, @bitCast(i16, u16(0x1234))) == @bitCast(i16, u16( 0x2c48)));
52 assert(@bitreverse(i24, @bitCast(i24, u24(0x123456))) == @bitCast(i24, u24( 0x6a2c48)));
53 assert(@bitreverse(i32, @bitCast(i32, u32(0x12345678))) == @bitCast(i32, u32( 0x1e6a2c48)));
54 assert(@bitreverse(i40, @bitCast(i40, u40(0x123456789a))) == @bitCast(i40, u40( 0x591e6a2c48)));
55 assert(@bitreverse(i48, @bitCast(i48, u48(0x123456789abc))) == @bitCast(i48, u48( 0x3d591e6a2c48)));
56 assert(@bitreverse(i56, @bitCast(i56, u56(0x123456789abcde))) == @bitCast(i56, u56( 0x7b3d591e6a2c48)));
57 assert(@bitreverse(i64, @bitCast(i64, u64(0x123456789abcdef1))) == @bitCast(i64,u64(0x8f7b3d591e6a2c48)));
58 assert(@bitreverse(i128, @bitCast(i128,u128(0x123456789abcdef11121314151617181))) == @bitCast(i128,u128(0x818e868a828c84888f7b3d591e6a2c48)));
59
60 // using comptime_ints, signed, negative. Compare to runtime ints returned from llvm.
61 var neg5: i5 = minInt(i5) + 1;
62 assert(@bitreverse(i5, minInt(i5) + 1) == @bitreverse(i5, neg5));
63 var neg8: i8 = -18;
64 assert(@bitreverse(i8, -18) == @bitreverse(i8, neg8));
65 var neg16: i16 = -32694;
66 assert(@bitreverse(i16, -32694) == @bitreverse(i16, neg16));
67 var neg24: i24 = -6773785;
68 assert(@bitreverse(i24, -6773785) == @bitreverse(i24, neg24));
69 var neg32: i32 = -16773785;
70 assert(@bitreverse(i32, -16773785) == @bitreverse(i32, neg32));
71 var neg40: i40 = minInt(i40) + 12345;
72 assert(@bitreverse(i40, minInt(i40) + 12345) == @bitreverse(i40, neg40));
73 var neg48: i48 = minInt(i48) + 12345;
74 assert(@bitreverse(i48, minInt(i48) + 12345) == @bitreverse(i48, neg48));
75 var neg56: i56 = minInt(i56) + 12345;
76 assert(@bitreverse(i56, minInt(i56) + 12345) == @bitreverse(i56, neg56));
77 var neg64: i64 = minInt(i64) + 12345;
78 assert(@bitreverse(i64, minInt(i64) + 12345) == @bitreverse(i64, neg64));
79 var neg128: i128 = minInt(i128) + 12345;
80 assert(@bitreverse(i128, minInt(i128) + 12345) == @bitreverse(i128, neg128));
81}
test/cases/inttoptr.zig+14
...@@ -11,3 +11,17 @@ fn randomAddressToFunction() void {...@@ -11,3 +11,17 @@ fn randomAddressToFunction() void {
11 var addr: usize = 0xdeadbeef;11 var addr: usize = 0xdeadbeef;
12 var ptr = @intToPtr(fn () void, addr);12 var ptr = @intToPtr(fn () void, addr);
13}13}
14
15test "mutate through ptr initialized with constant intToPtr value" {
16 forceCompilerAnalyzeBranchHardCodedPtrDereference(false);
17}
18
19fn forceCompilerAnalyzeBranchHardCodedPtrDereference(x: bool) void {
20 const hardCodedP = @intToPtr(*volatile u8, 0xdeadbeef);
21 if (x) {
22 hardCodedP.* = hardCodedP.* | 10;
23 } else {
24 return;
25 }
26}
27
test/cases/ptrcast.zig+16
...@@ -34,3 +34,19 @@ fn testReinterpretBytesAsExternStruct() void {...@@ -34,3 +34,19 @@ fn testReinterpretBytesAsExternStruct() void {
34 var val = ptr.c;34 var val = ptr.c;
35 assertOrPanic(val == 5);35 assertOrPanic(val == 5);
36}36}
37
38test "reinterpret struct field at comptime" {
39 const numLittle = comptime Bytes.init(0x12345678);
40 assertOrPanic(std.mem.eql(u8, []u8{ 0x78, 0x56, 0x34, 0x12 }, numLittle.bytes));
41}
42
43const Bytes = struct {
44 bytes: [4]u8,
45
46 pub fn init(v: u32) Bytes {
47 var res: Bytes = undefined;
48 @ptrCast(*align(1) u32, &res.bytes).* = v;
49
50 return res;
51 }
52};