| author | |
| committer | |
| log | 76ad9cb10eeae5257eb51838953d0e3bcb993fa3 |
| tree | b656838f6b4d0a431989bccf76d36196e4e5a8a8 |
| parent | fb9a7dad178398326033dfcddedf41b59227bc70 |
| signature |
7 files changed, 115 insertions(+), 2 deletions(-)
src/Sema.zig-1| ... | @@ -18181,7 +18181,6 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst | ... | @@ -18181,7 +18181,6 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst |
| 18181 | const ptr = try sema.resolveInst(extra.rhs); | 18181 | const ptr = try sema.resolveInst(extra.rhs); |
| 18182 | const ptr_ty = sema.typeOf(ptr); | 18182 | const ptr_ty = sema.typeOf(ptr); |
| 18183 | 18183 | ||
| 18184 | |||
| 18185 | // TODO in addition to pointers, this instruction is supposed to work for | 18184 | // TODO in addition to pointers, this instruction is supposed to work for |
| 18186 | // pointer-like optionals and slices. | 18185 | // pointer-like optionals and slices. |
| 18187 | try sema.checkPtrOperand(block, ptr_src, ptr_ty); | 18186 | try sema.checkPtrOperand(block, ptr_src, ptr_ty); |
src/stage1/all_types.hpp+14| ... | @@ -95,6 +95,11 @@ enum AddressSpace { | ... | @@ -95,6 +95,11 @@ enum AddressSpace { |
| 95 | AddressSpaceGS, | 95 | AddressSpaceGS, |
| 96 | AddressSpaceFS, | 96 | AddressSpaceFS, |
| 97 | AddressSpaceSS, | 97 | AddressSpaceSS, |
| 98 | AddressSpaceGlobal, | ||
| 99 | AddressSpaceConstant, | ||
| 100 | AddressSpaceParam, | ||
| 101 | AddressSpaceShared, | ||
| 102 | AddressSpaceLocal | ||
| 98 | }; | 103 | }; |
| 99 | 104 | ||
| 100 | // This one corresponds to the builtin.zig enum. | 105 | // This one corresponds to the builtin.zig enum. |
| ... | @@ -1842,6 +1847,7 @@ enum BuiltinFnId { | ... | @@ -1842,6 +1847,7 @@ enum BuiltinFnId { |
| 1842 | BuiltinFnIdMaximum, | 1847 | BuiltinFnIdMaximum, |
| 1843 | BuiltinFnIdMinimum, | 1848 | BuiltinFnIdMinimum, |
| 1844 | BuiltinFnIdPrefetch, | 1849 | BuiltinFnIdPrefetch, |
| 1850 | BuiltinFnIdAddrSpaceCast, | ||
| 1845 | }; | 1851 | }; |
| 1846 | 1852 | ||
| 1847 | struct BuiltinFnEntry { | 1853 | struct BuiltinFnEntry { |
| ... | @@ -2673,6 +2679,7 @@ enum Stage1ZirInstId : uint8_t { | ... | @@ -2673,6 +2679,7 @@ enum Stage1ZirInstId : uint8_t { |
| 2673 | Stage1ZirInstIdWasmMemoryGrow, | 2679 | Stage1ZirInstIdWasmMemoryGrow, |
| 2674 | Stage1ZirInstIdSrc, | 2680 | Stage1ZirInstIdSrc, |
| 2675 | Stage1ZirInstIdPrefetch, | 2681 | Stage1ZirInstIdPrefetch, |
| 2682 | Stage1ZirInstIdAddrSpaceCast, | ||
| 2676 | }; | 2683 | }; |
| 2677 | 2684 | ||
| 2678 | // ir_render_* functions in codegen.cpp consume Gen instructions and produce LLVM IR. | 2685 | // ir_render_* functions in codegen.cpp consume Gen instructions and produce LLVM IR. |
| ... | @@ -4169,6 +4176,13 @@ struct Stage1AirInstAlignCast { | ... | @@ -4169,6 +4176,13 @@ struct Stage1AirInstAlignCast { |
| 4169 | Stage1AirInst *target; | 4176 | Stage1AirInst *target; |
| 4170 | }; | 4177 | }; |
| 4171 | 4178 | ||
| 4179 | struct Stage1ZirInstAddrSpaceCast { | ||
| 4180 | Stage1ZirInst base; | ||
| 4181 | |||
| 4182 | Stage1ZirInst *addrspace; | ||
| 4183 | Stage1ZirInst *ptr; | ||
| 4184 | }; | ||
| 4185 | |||
| 4172 | struct Stage1ZirInstSetAlignStack { | 4186 | struct Stage1ZirInstSetAlignStack { |
| 4173 | Stage1ZirInst base; | 4187 | Stage1ZirInst base; |
| 4174 | 4188 |
src/stage1/analyze.cpp+5| ... | @@ -1030,6 +1030,11 @@ const char *address_space_name(AddressSpace as) { | ... | @@ -1030,6 +1030,11 @@ const char *address_space_name(AddressSpace as) { |
| 1030 | case AddressSpaceGS: return "gs"; | 1030 | case AddressSpaceGS: return "gs"; |
| 1031 | case AddressSpaceFS: return "fs"; | 1031 | case AddressSpaceFS: return "fs"; |
| 1032 | case AddressSpaceSS: return "ss"; | 1032 | case AddressSpaceSS: return "ss"; |
| 1033 | case AddressSpaceGlobal: return "global"; | ||
| 1034 | case AddressSpaceConstant: return "constant"; | ||
| 1035 | case AddressSpaceParam: return "param"; | ||
| 1036 | case AddressSpaceShared: return "shared"; | ||
| 1037 | case AddressSpaceLocal: return "local"; | ||
| 1033 | } | 1038 | } |
| 1034 | zig_unreachable(); | 1039 | zig_unreachable(); |
| 1035 | } | 1040 | } |
src/stage1/astgen.cpp+34| ... | @@ -351,6 +351,8 @@ void destroy_instruction_src(Stage1ZirInst *inst) { | ... | @@ -351,6 +351,8 @@ void destroy_instruction_src(Stage1ZirInst *inst) { |
| 351 | return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSrc *>(inst)); | 351 | return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSrc *>(inst)); |
| 352 | case Stage1ZirInstIdPrefetch: | 352 | case Stage1ZirInstIdPrefetch: |
| 353 | return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstPrefetch *>(inst)); | 353 | return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstPrefetch *>(inst)); |
| 354 | case Stage1ZirInstIdAddrSpaceCast: | ||
| 355 | return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstAddrSpaceCast *>(inst)); | ||
| 354 | } | 356 | } |
| 355 | zig_unreachable(); | 357 | zig_unreachable(); |
| 356 | } | 358 | } |
| ... | @@ -947,6 +949,10 @@ static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstPrefetch *) { | ... | @@ -947,6 +949,10 @@ static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstPrefetch *) { |
| 947 | return Stage1ZirInstIdPrefetch; | 949 | return Stage1ZirInstIdPrefetch; |
| 948 | } | 950 | } |
| 949 | 951 | ||
| 952 | static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAddrSpaceCast *) { | ||
| 953 | return Stage1ZirInstIdAddrSpaceCast; | ||
| 954 | } | ||
| 955 | |||
| 950 | template<typename T> | 956 | template<typename T> |
| 951 | static T *ir_create_instruction(Stage1AstGen *ag, Scope *scope, AstNode *source_node) { | 957 | static T *ir_create_instruction(Stage1AstGen *ag, Scope *scope, AstNode *source_node) { |
| 952 | T *special_instruction = heap::c_allocator.create<T>(); | 958 | T *special_instruction = heap::c_allocator.create<T>(); |
| ... | @@ -2572,6 +2578,19 @@ static Stage1ZirInst *ir_build_align_cast_src(Stage1AstGen *ag, Scope *scope, As | ... | @@ -2572,6 +2578,19 @@ static Stage1ZirInst *ir_build_align_cast_src(Stage1AstGen *ag, Scope *scope, As |
| 2572 | return &instruction->base; | 2578 | return &instruction->base; |
| 2573 | } | 2579 | } |
| 2574 | 2580 | ||
| 2581 | static Stage1ZirInst *ir_build_addrspace_cast(Stage1AstGen *ag, Scope *scope, AstNode *source_node, | ||
| 2582 | Stage1ZirInst *addrspace, Stage1ZirInst *ptr) | ||
| 2583 | { | ||
| 2584 | Stage1ZirInstAddrSpaceCast *instruction = ir_build_instruction<Stage1ZirInstAddrSpaceCast>(ag, scope, source_node); | ||
| 2585 | instruction->addrspace = addrspace; | ||
| 2586 | instruction->ptr = ptr; | ||
| 2587 | |||
| 2588 | ir_ref_instruction(addrspace, ag->current_basic_block); | ||
| 2589 | ir_ref_instruction(ptr, ag->current_basic_block); | ||
| 2590 | |||
| 2591 | return &instruction->base; | ||
| 2592 | } | ||
| 2593 | |||
| 2575 | static Stage1ZirInst *ir_build_resolve_result(Stage1AstGen *ag, Scope *scope, AstNode *source_node, | 2594 | static Stage1ZirInst *ir_build_resolve_result(Stage1AstGen *ag, Scope *scope, AstNode *source_node, |
| 2576 | ResultLoc *result_loc, Stage1ZirInst *ty) | 2595 | ResultLoc *result_loc, Stage1ZirInst *ty) |
| 2577 | { | 2596 | { |
| ... | @@ -5459,6 +5478,21 @@ static Stage1ZirInst *astgen_builtin_fn_call(Stage1AstGen *ag, Scope *scope, Ast | ... | @@ -5459,6 +5478,21 @@ static Stage1ZirInst *astgen_builtin_fn_call(Stage1AstGen *ag, Scope *scope, Ast |
| 5459 | Stage1ZirInst *ir_extern = ir_build_prefetch(ag, scope, node, ptr_value, casted_options_value); | 5478 | Stage1ZirInst *ir_extern = ir_build_prefetch(ag, scope, node, ptr_value, casted_options_value); |
| 5460 | return ir_lval_wrap(ag, scope, ir_extern, lval, result_loc); | 5479 | return ir_lval_wrap(ag, scope, ir_extern, lval, result_loc); |
| 5461 | } | 5480 | } |
| 5481 | case BuiltinFnIdAddrSpaceCast: | ||
| 5482 | { | ||
| 5483 | AstNode *arg0_node = node->data.fn_call_expr.params.at(0); | ||
| 5484 | Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope); | ||
| 5485 | if (arg0_value == ag->codegen->invalid_inst_src) | ||
| 5486 | return arg0_value; | ||
| 5487 | |||
| 5488 | AstNode* arg1_node = node->data.fn_call_expr.params.at(1); | ||
| 5489 | Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope); | ||
| 5490 | if (arg1_value == ag->codegen->invalid_inst_src) | ||
| 5491 | return arg1_value; | ||
| 5492 | |||
| 5493 | Stage1ZirInst *addrspace_cast = ir_build_addrspace_cast(ag, scope, node, arg0_value, arg1_value); | ||
| 5494 | return ir_lval_wrap(ag, scope, addrspace_cast, lval, result_loc); | ||
| 5495 | } | ||
| 5462 | } | 5496 | } |
| 5463 | zig_unreachable(); | 5497 | zig_unreachable(); |
| 5464 | } | 5498 | } |
src/stage1/codegen.cpp+2-1| ... | @@ -4371,7 +4371,7 @@ static LLVMValueRef ir_render_binary_not(CodeGen *g, Stage1Air *executable, | ... | @@ -4371,7 +4371,7 @@ static LLVMValueRef ir_render_binary_not(CodeGen *g, Stage1Air *executable, |
| 4371 | 4371 | ||
| 4372 | static LLVMValueRef gen_soft_float_neg(CodeGen *g, ZigType *operand_type, LLVMValueRef operand) { | 4372 | static LLVMValueRef gen_soft_float_neg(CodeGen *g, ZigType *operand_type, LLVMValueRef operand) { |
| 4373 | uint32_t vector_len = operand_type->id == ZigTypeIdVector ? operand_type->data.vector.len : 0; | 4373 | uint32_t vector_len = operand_type->id == ZigTypeIdVector ? operand_type->data.vector.len : 0; |
| 4374 | uint16_t num_bits = operand_type->id == ZigTypeIdVector ? | 4374 | uint16_t num_bits = operand_type->id == ZigTypeIdVector ? |
| 4375 | operand_type->data.vector.elem_type->data.floating.bit_count : | 4375 | operand_type->data.vector.elem_type->data.floating.bit_count : |
| 4376 | operand_type->data.floating.bit_count; | 4376 | operand_type->data.floating.bit_count; |
| 4377 | 4377 | ||
| ... | @@ -10085,6 +10085,7 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -10085,6 +10085,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 10085 | create_builtin_fn(g, BuiltinFnIdMaximum, "maximum", 2); | 10085 | create_builtin_fn(g, BuiltinFnIdMaximum, "maximum", 2); |
| 10086 | create_builtin_fn(g, BuiltinFnIdMinimum, "minimum", 2); | 10086 | create_builtin_fn(g, BuiltinFnIdMinimum, "minimum", 2); |
| 10087 | create_builtin_fn(g, BuiltinFnIdPrefetch, "prefetch", 2); | 10087 | create_builtin_fn(g, BuiltinFnIdPrefetch, "prefetch", 2); |
| 10088 | create_builtin_fn(g, BuiltinFnIdAddrSpaceCast, "addrSpaceCast", 2); | ||
| 10088 | } | 10089 | } |
| 10089 | 10090 | ||
| 10090 | static const char *bool_to_str(bool b) { | 10091 | static const char *bool_to_str(bool b) { |
src/stage1/ir.cpp+47| ... | @@ -23746,6 +23746,50 @@ static Stage1AirInst *ir_analyze_instruction_align_cast(IrAnalyze *ira, Stage1Zi | ... | @@ -23746,6 +23746,50 @@ static Stage1AirInst *ir_analyze_instruction_align_cast(IrAnalyze *ira, Stage1Zi |
| 23746 | return result; | 23746 | return result; |
| 23747 | } | 23747 | } |
| 23748 | 23748 | ||
| 23749 | static bool ir_resolve_addrspace(IrAnalyze *ira, Stage1AirInst *value, AddressSpace *out) { | ||
| 23750 | if (type_is_invalid(value->value->type)) | ||
| 23751 | return false; | ||
| 23752 | |||
| 23753 | ZigType *addrspace_type = get_builtin_type(ira->codegen, "AddressSpace"); | ||
| 23754 | |||
| 23755 | Stage1AirInst *casted_value = ir_implicit_cast(ira, value, addrspace_type); | ||
| 23756 | if (type_is_invalid(casted_value->value->type)) | ||
| 23757 | return false; | ||
| 23758 | |||
| 23759 | ZigValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); | ||
| 23760 | if (!const_val) | ||
| 23761 | return false; | ||
| 23762 | |||
| 23763 | *out = (AddressSpace)bigint_as_u32(&const_val->data.x_enum_tag); | ||
| 23764 | return true; | ||
| 23765 | } | ||
| 23766 | |||
| 23767 | static Stage1AirInst *ir_analyze_instruction_addrspace_cast(IrAnalyze *ira, Stage1ZirInstAddrSpaceCast *instruction) { | ||
| 23768 | Stage1AirInst *ptr_inst = instruction->ptr->child; | ||
| 23769 | ZigType *ptr_type = ptr_inst->value->type; | ||
| 23770 | if (type_is_invalid(ptr_type)) | ||
| 23771 | return ira->codegen->invalid_inst_gen; | ||
| 23772 | |||
| 23773 | AddressSpace addrspace; | ||
| 23774 | if (!ir_resolve_addrspace(ira, instruction->addrspace->child, &addrspace)) | ||
| 23775 | return ira->codegen->invalid_inst_gen; | ||
| 23776 | |||
| 23777 | if (addrspace != AddressSpaceGeneric) { | ||
| 23778 | ir_add_error_node(ira, instruction->addrspace->source_node, buf_sprintf( | ||
| 23779 | "address space '%s' not available in stage 1 compiler, must be .generic", | ||
| 23780 | address_space_name(addrspace))); | ||
| 23781 | return ira->codegen->invalid_inst_gen; | ||
| 23782 | } | ||
| 23783 | |||
| 23784 | if (is_slice(ptr_type) || get_src_ptr_type(ptr_type) != nullptr) { | ||
| 23785 | ir_add_error_node(ira, instruction->ptr->source_node, | ||
| 23786 | buf_sprintf("expected pointer or slice, found '%s'", buf_ptr(&ptr_type->name))); | ||
| 23787 | return ira->codegen->invalid_inst_gen; | ||
| 23788 | } | ||
| 23789 | |||
| 23790 | return ptr_inst; | ||
| 23791 | } | ||
| 23792 | |||
| 23749 | static Stage1AirInst *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, Stage1ZirInstSetAlignStack *instruction) { | 23793 | static Stage1AirInst *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, Stage1ZirInstSetAlignStack *instruction) { |
| 23750 | uint32_t align_bytes; | 23794 | uint32_t align_bytes; |
| 23751 | Stage1AirInst *align_bytes_inst = instruction->align_bytes->child; | 23795 | Stage1AirInst *align_bytes_inst = instruction->align_bytes->child; |
| ... | @@ -25451,6 +25495,8 @@ static Stage1AirInst *ir_analyze_instruction_base(IrAnalyze *ira, Stage1ZirInst | ... | @@ -25451,6 +25495,8 @@ static Stage1AirInst *ir_analyze_instruction_base(IrAnalyze *ira, Stage1ZirInst |
| 25451 | return ir_analyze_instruction_src(ira, (Stage1ZirInstSrc *)instruction); | 25495 | return ir_analyze_instruction_src(ira, (Stage1ZirInstSrc *)instruction); |
| 25452 | case Stage1ZirInstIdPrefetch: | 25496 | case Stage1ZirInstIdPrefetch: |
| 25453 | return ir_analyze_instruction_prefetch(ira, (Stage1ZirInstPrefetch *)instruction); | 25497 | return ir_analyze_instruction_prefetch(ira, (Stage1ZirInstPrefetch *)instruction); |
| 25498 | case Stage1ZirInstIdAddrSpaceCast: | ||
| 25499 | return ir_analyze_instruction_addrspace_cast(ira, (Stage1ZirInstAddrSpaceCast *)instruction); | ||
| 25454 | } | 25500 | } |
| 25455 | zig_unreachable(); | 25501 | zig_unreachable(); |
| 25456 | } | 25502 | } |
| ... | @@ -25832,6 +25878,7 @@ bool ir_inst_src_has_side_effects(Stage1ZirInst *instruction) { | ... | @@ -25832,6 +25878,7 @@ bool ir_inst_src_has_side_effects(Stage1ZirInst *instruction) { |
| 25832 | case Stage1ZirInstIdWasmMemorySize: | 25878 | case Stage1ZirInstIdWasmMemorySize: |
| 25833 | case Stage1ZirInstIdSrc: | 25879 | case Stage1ZirInstIdSrc: |
| 25834 | case Stage1ZirInstIdReduce: | 25880 | case Stage1ZirInstIdReduce: |
| 25881 | case Stage1ZirInstIdAddrSpaceCast: | ||
| 25835 | return false; | 25882 | return false; |
| 25836 | 25883 | ||
| 25837 | case Stage1ZirInstIdAsm: | 25884 | case Stage1ZirInstIdAsm: |
src/stage1/ir_print.cpp+13| ... | @@ -373,6 +373,8 @@ const char* ir_inst_src_type_str(Stage1ZirInstId id) { | ... | @@ -373,6 +373,8 @@ const char* ir_inst_src_type_str(Stage1ZirInstId id) { |
| 373 | return "SrcSrc"; | 373 | return "SrcSrc"; |
| 374 | case Stage1ZirInstIdPrefetch: | 374 | case Stage1ZirInstIdPrefetch: |
| 375 | return "SrcPrefetch"; | 375 | return "SrcPrefetch"; |
| 376 | case Stage1ZirInstIdAddrSpaceCast: | ||
| 377 | return "SrcAddrSpaceCast"; | ||
| 376 | } | 378 | } |
| 377 | zig_unreachable(); | 379 | zig_unreachable(); |
| 378 | } | 380 | } |
| ... | @@ -2382,6 +2384,14 @@ static void ir_print_align_cast(IrPrintSrc *irp, Stage1ZirInstAlignCast *instruc | ... | @@ -2382,6 +2384,14 @@ static void ir_print_align_cast(IrPrintSrc *irp, Stage1ZirInstAlignCast *instruc |
| 2382 | fprintf(irp->f, ")"); | 2384 | fprintf(irp->f, ")"); |
| 2383 | } | 2385 | } |
| 2384 | 2386 | ||
| 2387 | static void ir_print_addrspace_cast(IrPrintSrc *irp, Stage1ZirInstAddrSpaceCast *instruction) { | ||
| 2388 | fprintf(irp->f, "@addrSpaceCast("); | ||
| 2389 | ir_print_other_inst_src(irp, instruction->addrspace); | ||
| 2390 | fprintf(irp->f, ","); | ||
| 2391 | ir_print_other_inst_src(irp, instruction->ptr); | ||
| 2392 | fprintf(irp->f, ")"); | ||
| 2393 | } | ||
| 2394 | |||
| 2385 | static void ir_print_align_cast(IrPrintGen *irp, Stage1AirInstAlignCast *instruction) { | 2395 | static void ir_print_align_cast(IrPrintGen *irp, Stage1AirInstAlignCast *instruction) { |
| 2386 | fprintf(irp->f, "@alignCast("); | 2396 | fprintf(irp->f, "@alignCast("); |
| 2387 | ir_print_other_inst_gen(irp, instruction->target); | 2397 | ir_print_other_inst_gen(irp, instruction->target); |
| ... | @@ -3127,6 +3137,9 @@ static void ir_print_inst_src(IrPrintSrc *irp, Stage1ZirInst *instruction, bool | ... | @@ -3127,6 +3137,9 @@ static void ir_print_inst_src(IrPrintSrc *irp, Stage1ZirInst *instruction, bool |
| 3127 | case Stage1ZirInstIdPrefetch: | 3137 | case Stage1ZirInstIdPrefetch: |
| 3128 | ir_print_prefetch(irp, (Stage1ZirInstPrefetch *)instruction); | 3138 | ir_print_prefetch(irp, (Stage1ZirInstPrefetch *)instruction); |
| 3129 | break; | 3139 | break; |
| 3140 | case Stage1ZirInstIdAddrSpaceCast: | ||
| 3141 | ir_print_addrspace_cast(irp, (Stage1ZirInstAddrSpaceCast *)instruction); | ||
| 3142 | break; | ||
| 3130 | } | 3143 | } |
| 3131 | fprintf(irp->f, "\n"); | 3144 | fprintf(irp->f, "\n"); |
| 3132 | } | 3145 | } |