| 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 | 18181 | const ptr = try sema.resolveInst(extra.rhs); |
| 18182 | 18182 | const ptr_ty = sema.typeOf(ptr); |
| 18183 | 18183 | |
| 18184 | ||
| 18185 | 18184 | // TODO in addition to pointers, this instruction is supposed to work for |
| 18186 | 18185 | // pointer-like optionals and slices. |
| 18187 | 18186 | try sema.checkPtrOperand(block, ptr_src, ptr_ty); |
src/stage1/all_types.hpp+14| ... | ... | @@ -95,6 +95,11 @@ enum AddressSpace { |
| 95 | 95 | AddressSpaceGS, |
| 96 | 96 | AddressSpaceFS, |
| 97 | 97 | AddressSpaceSS, |
| 98 | AddressSpaceGlobal, | |
| 99 | AddressSpaceConstant, | |
| 100 | AddressSpaceParam, | |
| 101 | AddressSpaceShared, | |
| 102 | AddressSpaceLocal | |
| 98 | 103 | }; |
| 99 | 104 | |
| 100 | 105 | // This one corresponds to the builtin.zig enum. |
| ... | ... | @@ -1842,6 +1847,7 @@ enum BuiltinFnId { |
| 1842 | 1847 | BuiltinFnIdMaximum, |
| 1843 | 1848 | BuiltinFnIdMinimum, |
| 1844 | 1849 | BuiltinFnIdPrefetch, |
| 1850 | BuiltinFnIdAddrSpaceCast, | |
| 1845 | 1851 | }; |
| 1846 | 1852 | |
| 1847 | 1853 | struct BuiltinFnEntry { |
| ... | ... | @@ -2673,6 +2679,7 @@ enum Stage1ZirInstId : uint8_t { |
| 2673 | 2679 | Stage1ZirInstIdWasmMemoryGrow, |
| 2674 | 2680 | Stage1ZirInstIdSrc, |
| 2675 | 2681 | Stage1ZirInstIdPrefetch, |
| 2682 | Stage1ZirInstIdAddrSpaceCast, | |
| 2676 | 2683 | }; |
| 2677 | 2684 | |
| 2678 | 2685 | // ir_render_* functions in codegen.cpp consume Gen instructions and produce LLVM IR. |
| ... | ... | @@ -4169,6 +4176,13 @@ struct Stage1AirInstAlignCast { |
| 4169 | 4176 | Stage1AirInst *target; |
| 4170 | 4177 | }; |
| 4171 | 4178 | |
| 4179 | struct Stage1ZirInstAddrSpaceCast { | |
| 4180 | Stage1ZirInst base; | |
| 4181 | ||
| 4182 | Stage1ZirInst *addrspace; | |
| 4183 | Stage1ZirInst *ptr; | |
| 4184 | }; | |
| 4185 | ||
| 4172 | 4186 | struct Stage1ZirInstSetAlignStack { |
| 4173 | 4187 | Stage1ZirInst base; |
| 4174 | 4188 |
src/stage1/analyze.cpp+5| ... | ... | @@ -1030,6 +1030,11 @@ const char *address_space_name(AddressSpace as) { |
| 1030 | 1030 | case AddressSpaceGS: return "gs"; |
| 1031 | 1031 | case AddressSpaceFS: return "fs"; |
| 1032 | 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 | 1039 | zig_unreachable(); |
| 1035 | 1040 | } |
src/stage1/astgen.cpp+34| ... | ... | @@ -351,6 +351,8 @@ void destroy_instruction_src(Stage1ZirInst *inst) { |
| 351 | 351 | return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSrc *>(inst)); |
| 352 | 352 | case Stage1ZirInstIdPrefetch: |
| 353 | 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 | 357 | zig_unreachable(); |
| 356 | 358 | } |
| ... | ... | @@ -947,6 +949,10 @@ static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstPrefetch *) { |
| 947 | 949 | return Stage1ZirInstIdPrefetch; |
| 948 | 950 | } |
| 949 | 951 | |
| 952 | static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAddrSpaceCast *) { | |
| 953 | return Stage1ZirInstIdAddrSpaceCast; | |
| 954 | } | |
| 955 | ||
| 950 | 956 | template<typename T> |
| 951 | 957 | static T *ir_create_instruction(Stage1AstGen *ag, Scope *scope, AstNode *source_node) { |
| 952 | 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 | 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 | 2594 | static Stage1ZirInst *ir_build_resolve_result(Stage1AstGen *ag, Scope *scope, AstNode *source_node, |
| 2576 | 2595 | ResultLoc *result_loc, Stage1ZirInst *ty) |
| 2577 | 2596 | { |
| ... | ... | @@ -5459,6 +5478,21 @@ static Stage1ZirInst *astgen_builtin_fn_call(Stage1AstGen *ag, Scope *scope, Ast |
| 5459 | 5478 | Stage1ZirInst *ir_extern = ir_build_prefetch(ag, scope, node, ptr_value, casted_options_value); |
| 5460 | 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 | 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 | 4371 | |
| 4372 | 4372 | static LLVMValueRef gen_soft_float_neg(CodeGen *g, ZigType *operand_type, LLVMValueRef operand) { |
| 4373 | 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 | 4375 | operand_type->data.vector.elem_type->data.floating.bit_count : |
| 4376 | 4376 | operand_type->data.floating.bit_count; |
| 4377 | 4377 | |
| ... | ... | @@ -10085,6 +10085,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 10085 | 10085 | create_builtin_fn(g, BuiltinFnIdMaximum, "maximum", 2); |
| 10086 | 10086 | create_builtin_fn(g, BuiltinFnIdMinimum, "minimum", 2); |
| 10087 | 10087 | create_builtin_fn(g, BuiltinFnIdPrefetch, "prefetch", 2); |
| 10088 | create_builtin_fn(g, BuiltinFnIdAddrSpaceCast, "addrSpaceCast", 2); | |
| 10088 | 10089 | } |
| 10089 | 10090 | |
| 10090 | 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 | 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 | 23793 | static Stage1AirInst *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, Stage1ZirInstSetAlignStack *instruction) { |
| 23750 | 23794 | uint32_t align_bytes; |
| 23751 | 23795 | Stage1AirInst *align_bytes_inst = instruction->align_bytes->child; |
| ... | ... | @@ -25451,6 +25495,8 @@ static Stage1AirInst *ir_analyze_instruction_base(IrAnalyze *ira, Stage1ZirInst |
| 25451 | 25495 | return ir_analyze_instruction_src(ira, (Stage1ZirInstSrc *)instruction); |
| 25452 | 25496 | case Stage1ZirInstIdPrefetch: |
| 25453 | 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 | 25501 | zig_unreachable(); |
| 25456 | 25502 | } |
| ... | ... | @@ -25832,6 +25878,7 @@ bool ir_inst_src_has_side_effects(Stage1ZirInst *instruction) { |
| 25832 | 25878 | case Stage1ZirInstIdWasmMemorySize: |
| 25833 | 25879 | case Stage1ZirInstIdSrc: |
| 25834 | 25880 | case Stage1ZirInstIdReduce: |
| 25881 | case Stage1ZirInstIdAddrSpaceCast: | |
| 25835 | 25882 | return false; |
| 25836 | 25883 | |
| 25837 | 25884 | case Stage1ZirInstIdAsm: |
src/stage1/ir_print.cpp+13| ... | ... | @@ -373,6 +373,8 @@ const char* ir_inst_src_type_str(Stage1ZirInstId id) { |
| 373 | 373 | return "SrcSrc"; |
| 374 | 374 | case Stage1ZirInstIdPrefetch: |
| 375 | 375 | return "SrcPrefetch"; |
| 376 | case Stage1ZirInstIdAddrSpaceCast: | |
| 377 | return "SrcAddrSpaceCast"; | |
| 376 | 378 | } |
| 377 | 379 | zig_unreachable(); |
| 378 | 380 | } |
| ... | ... | @@ -2382,6 +2384,14 @@ static void ir_print_align_cast(IrPrintSrc *irp, Stage1ZirInstAlignCast *instruc |
| 2382 | 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 | 2395 | static void ir_print_align_cast(IrPrintGen *irp, Stage1AirInstAlignCast *instruction) { |
| 2386 | 2396 | fprintf(irp->f, "@alignCast("); |
| 2387 | 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 | 3137 | case Stage1ZirInstIdPrefetch: |
| 3128 | 3138 | ir_print_prefetch(irp, (Stage1ZirInstPrefetch *)instruction); |
| 3129 | 3139 | break; |
| 3140 | case Stage1ZirInstIdAddrSpaceCast: | |
| 3141 | ir_print_addrspace_cast(irp, (Stage1ZirInstAddrSpaceCast *)instruction); | |
| 3142 | break; | |
| 3130 | 3143 | } |
| 3131 | 3144 | fprintf(irp->f, "\n"); |
| 3132 | 3145 | } |