authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-09-17 01:24:13+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-10-12 20:36:14+02:00
log76ad9cb10eeae5257eb51838953d0e3bcb993fa3
treeb656838f6b4d0a431989bccf76d36196e4e5a8a8
parentfb9a7dad178398326033dfcddedf41b59227bc70
signaturelock-open Commit is signed but in an unrecognized format.

backport @addrSpaceCast to stage 1


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);
1818318183
18184
18185 // TODO in addition to pointers, this instruction is supposed to work for18184 // 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};
99104
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};
18461852
1847struct BuiltinFnEntry {1853struct 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};
26772684
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};
41714178
4179struct Stage1ZirInstAddrSpaceCast {
4180 Stage1ZirInst base;
4181
4182 Stage1ZirInst *addrspace;
4183 Stage1ZirInst *ptr;
4184};
4185
4172struct Stage1ZirInstSetAlignStack {4186struct Stage1ZirInstSetAlignStack {
4173 Stage1ZirInst base;4187 Stage1ZirInst base;
41744188
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}
949951
952static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAddrSpaceCast *) {
953 return Stage1ZirInstIdAddrSpaceCast;
954}
955
950template<typename T>956template<typename T>
951static T *ir_create_instruction(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {957static 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}
25742580
2581static 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
2575static Stage1ZirInst *ir_build_resolve_result(Stage1AstGen *ag, Scope *scope, AstNode *source_node,2594static 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,
43714371
4372static LLVMValueRef gen_soft_float_neg(CodeGen *g, ZigType *operand_type, LLVMValueRef operand) {4372static 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;
43774377
...@@ -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}
1008910090
10090static const char *bool_to_str(bool b) {10091static 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}
2374823748
23749static 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
23767static 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
23749static Stage1AirInst *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, Stage1ZirInstSetAlignStack *instruction) {23793static 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;
2583625883
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}
23842386
2387static 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
2385static void ir_print_align_cast(IrPrintGen *irp, Stage1AirInstAlignCast *instruction) {2395static 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}