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
1818118181 const ptr = try sema.resolveInst(extra.rhs);
1818218182 const ptr_ty = sema.typeOf(ptr);
1818318183
18184
1818518184 // TODO in addition to pointers, this instruction is supposed to work for
1818618185 // pointer-like optionals and slices.
1818718186 try sema.checkPtrOperand(block, ptr_src, ptr_ty);
src/stage1/all_types.hpp+14
......@@ -95,6 +95,11 @@ enum AddressSpace {
9595 AddressSpaceGS,
9696 AddressSpaceFS,
9797 AddressSpaceSS,
98 AddressSpaceGlobal,
99 AddressSpaceConstant,
100 AddressSpaceParam,
101 AddressSpaceShared,
102 AddressSpaceLocal
98103};
99104
100105// This one corresponds to the builtin.zig enum.
......@@ -1842,6 +1847,7 @@ enum BuiltinFnId {
18421847 BuiltinFnIdMaximum,
18431848 BuiltinFnIdMinimum,
18441849 BuiltinFnIdPrefetch,
1850 BuiltinFnIdAddrSpaceCast,
18451851};
18461852
18471853struct BuiltinFnEntry {
......@@ -2673,6 +2679,7 @@ enum Stage1ZirInstId : uint8_t {
26732679 Stage1ZirInstIdWasmMemoryGrow,
26742680 Stage1ZirInstIdSrc,
26752681 Stage1ZirInstIdPrefetch,
2682 Stage1ZirInstIdAddrSpaceCast,
26762683};
26772684
26782685// ir_render_* functions in codegen.cpp consume Gen instructions and produce LLVM IR.
......@@ -4169,6 +4176,13 @@ struct Stage1AirInstAlignCast {
41694176 Stage1AirInst *target;
41704177};
41714178
4179struct Stage1ZirInstAddrSpaceCast {
4180 Stage1ZirInst base;
4181
4182 Stage1ZirInst *addrspace;
4183 Stage1ZirInst *ptr;
4184};
4185
41724186struct Stage1ZirInstSetAlignStack {
41734187 Stage1ZirInst base;
41744188
src/stage1/analyze.cpp+5
......@@ -1030,6 +1030,11 @@ const char *address_space_name(AddressSpace as) {
10301030 case AddressSpaceGS: return "gs";
10311031 case AddressSpaceFS: return "fs";
10321032 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";
10331038 }
10341039 zig_unreachable();
10351040}
src/stage1/astgen.cpp+34
......@@ -351,6 +351,8 @@ void destroy_instruction_src(Stage1ZirInst *inst) {
351351 return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSrc *>(inst));
352352 case Stage1ZirInstIdPrefetch:
353353 return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstPrefetch *>(inst));
354 case Stage1ZirInstIdAddrSpaceCast:
355 return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstAddrSpaceCast *>(inst));
354356 }
355357 zig_unreachable();
356358}
......@@ -947,6 +949,10 @@ static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstPrefetch *) {
947949 return Stage1ZirInstIdPrefetch;
948950}
949951
952static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAddrSpaceCast *) {
953 return Stage1ZirInstIdAddrSpaceCast;
954}
955
950956template<typename T>
951957static T *ir_create_instruction(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
952958 T *special_instruction = heap::c_allocator.create<T>();
......@@ -2572,6 +2578,19 @@ static Stage1ZirInst *ir_build_align_cast_src(Stage1AstGen *ag, Scope *scope, As
25722578 return &instruction->base;
25732579}
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
25752594static Stage1ZirInst *ir_build_resolve_result(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
25762595 ResultLoc *result_loc, Stage1ZirInst *ty)
25772596{
......@@ -5459,6 +5478,21 @@ static Stage1ZirInst *astgen_builtin_fn_call(Stage1AstGen *ag, Scope *scope, Ast
54595478 Stage1ZirInst *ir_extern = ir_build_prefetch(ag, scope, node, ptr_value, casted_options_value);
54605479 return ir_lval_wrap(ag, scope, ir_extern, lval, result_loc);
54615480 }
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 }
54625496 }
54635497 zig_unreachable();
54645498}
src/stage1/codegen.cpp+2-1
......@@ -4371,7 +4371,7 @@ static LLVMValueRef ir_render_binary_not(CodeGen *g, Stage1Air *executable,
43714371
43724372static LLVMValueRef gen_soft_float_neg(CodeGen *g, ZigType *operand_type, LLVMValueRef operand) {
43734373 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 ?
43754375 operand_type->data.vector.elem_type->data.floating.bit_count :
43764376 operand_type->data.floating.bit_count;
43774377
......@@ -10085,6 +10085,7 @@ static void define_builtin_fns(CodeGen *g) {
1008510085 create_builtin_fn(g, BuiltinFnIdMaximum, "maximum", 2);
1008610086 create_builtin_fn(g, BuiltinFnIdMinimum, "minimum", 2);
1008710087 create_builtin_fn(g, BuiltinFnIdPrefetch, "prefetch", 2);
10088 create_builtin_fn(g, BuiltinFnIdAddrSpaceCast, "addrSpaceCast", 2);
1008810089}
1008910090
1009010091static 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
2374623746 return result;
2374723747}
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
2374923793static Stage1AirInst *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, Stage1ZirInstSetAlignStack *instruction) {
2375023794 uint32_t align_bytes;
2375123795 Stage1AirInst *align_bytes_inst = instruction->align_bytes->child;
......@@ -25451,6 +25495,8 @@ static Stage1AirInst *ir_analyze_instruction_base(IrAnalyze *ira, Stage1ZirInst
2545125495 return ir_analyze_instruction_src(ira, (Stage1ZirInstSrc *)instruction);
2545225496 case Stage1ZirInstIdPrefetch:
2545325497 return ir_analyze_instruction_prefetch(ira, (Stage1ZirInstPrefetch *)instruction);
25498 case Stage1ZirInstIdAddrSpaceCast:
25499 return ir_analyze_instruction_addrspace_cast(ira, (Stage1ZirInstAddrSpaceCast *)instruction);
2545425500 }
2545525501 zig_unreachable();
2545625502}
......@@ -25832,6 +25878,7 @@ bool ir_inst_src_has_side_effects(Stage1ZirInst *instruction) {
2583225878 case Stage1ZirInstIdWasmMemorySize:
2583325879 case Stage1ZirInstIdSrc:
2583425880 case Stage1ZirInstIdReduce:
25881 case Stage1ZirInstIdAddrSpaceCast:
2583525882 return false;
2583625883
2583725884 case Stage1ZirInstIdAsm:
src/stage1/ir_print.cpp+13
......@@ -373,6 +373,8 @@ const char* ir_inst_src_type_str(Stage1ZirInstId id) {
373373 return "SrcSrc";
374374 case Stage1ZirInstIdPrefetch:
375375 return "SrcPrefetch";
376 case Stage1ZirInstIdAddrSpaceCast:
377 return "SrcAddrSpaceCast";
376378 }
377379 zig_unreachable();
378380}
......@@ -2382,6 +2384,14 @@ static void ir_print_align_cast(IrPrintSrc *irp, Stage1ZirInstAlignCast *instruc
23822384 fprintf(irp->f, ")");
23832385}
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
23852395static void ir_print_align_cast(IrPrintGen *irp, Stage1AirInstAlignCast *instruction) {
23862396 fprintf(irp->f, "@alignCast(");
23872397 ir_print_other_inst_gen(irp, instruction->target);
......@@ -3127,6 +3137,9 @@ static void ir_print_inst_src(IrPrintSrc *irp, Stage1ZirInst *instruction, bool
31273137 case Stage1ZirInstIdPrefetch:
31283138 ir_print_prefetch(irp, (Stage1ZirInstPrefetch *)instruction);
31293139 break;
3140 case Stage1ZirInstIdAddrSpaceCast:
3141 ir_print_addrspace_cast(irp, (Stage1ZirInstAddrSpaceCast *)instruction);
3142 break;
31303143 }
31313144 fprintf(irp->f, "\n");
31323145}