authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-08-22 00:21:31+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2022-10-12 20:36:12+02:00
log5d429b03e3d43e937e2b517d594275034a873959
tree2071dddfb806b692bf51864dd413c60c90d42bdd
parent5f3b91437f5cd23bcae66227932555b7abe32669
signaturelock-open Commit is signed but in an unrecognized format.

stage2: add @addrSpaceCast builtin


17 files changed, 99 insertions(+), 4 deletions(-)

src/Air.zig+5
...@@ -729,6 +729,10 @@ pub const Inst = struct {...@@ -729,6 +729,10 @@ pub const Inst = struct {
729 /// Sets the operand as the current error return trace,729 /// Sets the operand as the current error return trace,
730 set_err_return_trace,730 set_err_return_trace,
731731
732 /// Convert the address space of a pointer.
733 /// Uses the `ty_op` field.
734 addrspace_cast,
735
732 pub fn fromCmpOp(op: std.math.CompareOperator, optimized: bool) Tag {736 pub fn fromCmpOp(op: std.math.CompareOperator, optimized: bool) Tag {
733 switch (op) {737 switch (op) {
734 .lt => return if (optimized) .cmp_lt_optimized else .cmp_lt,738 .lt => return if (optimized) .cmp_lt_optimized else .cmp_lt,
...@@ -1138,6 +1142,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {...@@ -1138,6 +1142,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index) Type {
1138 .popcount,1142 .popcount,
1139 .byte_swap,1143 .byte_swap,
1140 .bit_reverse,1144 .bit_reverse,
1145 .addrspace_cast,
1141 => return air.getRefType(datas[inst].ty_op.ty),1146 => return air.getRefType(datas[inst].ty_op.ty),
11421147
1143 .loop,1148 .loop,
src/AstGen.zig+8
...@@ -7789,6 +7789,14 @@ fn builtinCall(...@@ -7789,6 +7789,14 @@ fn builtinCall(
7789 });7789 });
7790 return rvalue(gz, rl, result, node);7790 return rvalue(gz, rl, result, node);
7791 },7791 },
7792 .addrspace_cast => {
7793 const result = try gz.addExtendedPayload(.addrspace_cast, Zir.Inst.BinNode{
7794 .lhs = try comptimeExpr(gz, scope, .{ .ty = .address_space_type }, params[0]),
7795 .rhs = try expr(gz, scope, .none, params[1]),
7796 .node = gz.nodeIndexToRelative(node),
7797 });
7798 return rvalue(gz, rl, result, node);
7799 },
77927800
7793 // zig fmt: off7801 // zig fmt: off
7794 .has_decl => return hasDeclOrField(gz, scope, rl, node, params[0], params[1], .has_decl),7802 .has_decl => return hasDeclOrField(gz, scope, rl, node, params[0], params[1], .has_decl),
src/BuiltinFn.zig+8
...@@ -2,6 +2,7 @@ const std = @import("std");...@@ -2,6 +2,7 @@ const std = @import("std");
22
3pub const Tag = enum {3pub const Tag = enum {
4 add_with_overflow,4 add_with_overflow,
5 addrspace_cast,
5 align_cast,6 align_cast,
6 align_of,7 align_of,
7 as,8 as,
...@@ -152,6 +153,13 @@ pub const list = list: {...@@ -152,6 +153,13 @@ pub const list = list: {
152 .param_count = 4,153 .param_count = 4,
153 },154 },
154 },155 },
156 .{
157 "@addrSpaceCast",
158 .{
159 .tag = .addrspace_cast,
160 .param_count = 2,
161 },
162 },
155 .{163 .{
156 "@alignCast",164 "@alignCast",
157 .{165 .{
src/Liveness.zig+2
...@@ -268,6 +268,7 @@ pub fn categorizeOperand(...@@ -268,6 +268,7 @@ pub fn categorizeOperand(
268 .bit_reverse,268 .bit_reverse,
269 .splat,269 .splat,
270 .error_set_has_value,270 .error_set_has_value,
271 .addrspace_cast,
271 => {272 => {
272 const o = air_datas[inst].ty_op;273 const o = air_datas[inst].ty_op;
273 if (o.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);274 if (o.operand == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none);
...@@ -844,6 +845,7 @@ fn analyzeInst(...@@ -844,6 +845,7 @@ fn analyzeInst(
844 .bit_reverse,845 .bit_reverse,
845 .splat,846 .splat,
846 .error_set_has_value,847 .error_set_has_value,
848 .addrspace_cast,
847 => {849 => {
848 const o = inst_datas[inst].ty_op;850 const o = inst_datas[inst].ty_op;
849 return trackOperands(a, new_set, inst, main_tomb, .{ o.operand, .none, .none });851 return trackOperands(a, new_set, inst, main_tomb, .{ o.operand, .none, .none });
src/Module.zig+1-1
...@@ -4617,7 +4617,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -4617,7 +4617,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
4617 .constant => target_util.defaultAddressSpace(target, .global_constant),4617 .constant => target_util.defaultAddressSpace(target, .global_constant),
4618 else => unreachable,4618 else => unreachable,
4619 },4619 },
4620 else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx),4620 else => |addrspace_ref| try sema.analyzeAddressSpace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx),
4621 };4621 };
4622 };4622 };
46234623
src/Sema.zig+51-3
...@@ -975,8 +975,9 @@ fn analyzeBodyInner(...@@ -975,8 +975,9 @@ fn analyzeBodyInner(
975 .reify => try sema.zirReify( block, extended, inst),975 .reify => try sema.zirReify( block, extended, inst),
976 .builtin_async_call => try sema.zirBuiltinAsyncCall( block, extended),976 .builtin_async_call => try sema.zirBuiltinAsyncCall( block, extended),
977 .cmpxchg => try sema.zirCmpxchg( block, extended),977 .cmpxchg => try sema.zirCmpxchg( block, extended),
978978 .addrspace_cast => try sema.zirAddrSpaceCast( block, extended),
979 // zig fmt: on979 // zig fmt: on
980
980 .fence => {981 .fence => {
981 try sema.zirFence(block, extended);982 try sema.zirFence(block, extended);
982 i += 1;983 i += 1;
...@@ -16250,7 +16251,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -16250,7 +16251,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
16250 const address_space = if (inst_data.flags.has_addrspace) blk: {16251 const address_space = if (inst_data.flags.has_addrspace) blk: {
16251 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);16252 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
16252 extra_i += 1;16253 extra_i += 1;
16253 break :blk try sema.analyzeAddrspace(block, addrspace_src, ref, .pointer);16254 break :blk try sema.analyzeAddressSpace(block, addrspace_src, ref, .pointer);
16254 } else .generic;16255 } else .generic;
1625516256
16256 const bit_offset = if (inst_data.flags.has_bit_range) blk: {16257 const bit_offset = if (inst_data.flags.has_bit_range) blk: {
...@@ -18170,6 +18171,53 @@ fn reifyStruct(...@@ -18170,6 +18171,53 @@ fn reifyStruct(
18170 return sema.analyzeDeclVal(block, src, new_decl_index);18171 return sema.analyzeDeclVal(block, src, new_decl_index);
18171}18172}
1817218173
18174fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
18175 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
18176 const src = LazySrcLoc.nodeOffset(extra.node);
18177 const addrspace_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node };
18178 const ptr_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = extra.node };
18179
18180 const dest_addrspace = try sema.analyzeAddressSpace(block, addrspace_src, extra.lhs, .pointer);
18181 const ptr = try sema.resolveInst(extra.rhs);
18182 const ptr_ty = sema.typeOf(ptr);
18183
18184 // TODO in addition to pointers, this instruction is supposed to work for
18185 // pointer-like optionals and slices.
18186 try sema.checkPtrOperand(block, ptr_src, ptr_ty);
18187
18188 // TODO check address space cast validity.
18189 const src_addrspace = ptr_ty.ptrAddressSpace();
18190 _ = src_addrspace;
18191
18192 const ptr_info = ptr_ty.ptrInfo().data;
18193 const dest_ty = try Type.ptr(sema.arena, sema.mod, .{
18194 .pointee_type = ptr_info.pointee_type,
18195 .@"align" = ptr_info.@"align",
18196 .@"addrspace" = dest_addrspace,
18197 .mutable = ptr_info.mutable,
18198 .@"allowzero" = ptr_info.@"allowzero",
18199 .@"volatile" = ptr_info.@"volatile",
18200 .size = ptr_info.size,
18201 });
18202
18203 if (try sema.resolveMaybeUndefVal(block, ptr_src, ptr)) |val| {
18204 // Pointer value should compatible with both address spaces.
18205 // TODO: Figure out why this generates an invalid bitcast.
18206 return sema.addConstant(dest_ty, val);
18207 }
18208
18209 try sema.requireRuntimeBlock(block, src, ptr_src);
18210 // TODO: Address space cast safety?
18211
18212 return block.addInst(.{
18213 .tag = .addrspace_cast,
18214 .data = .{ .ty_op = .{
18215 .ty = try sema.addType(dest_ty),
18216 .operand = ptr,
18217 } },
18218 });
18219}
18220
18173fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {18221fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
18174 const inst_data = sema.code.instructions.items(.data)[inst].un_node;18222 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
18175 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };18223 const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
...@@ -30292,7 +30340,7 @@ pub const AddressSpaceContext = enum {...@@ -30292,7 +30340,7 @@ pub const AddressSpaceContext = enum {
30292 pointer,30340 pointer,
30293};30341};
3029430342
30295pub fn analyzeAddrspace(30343pub fn analyzeAddressSpace(
30296 sema: *Sema,30344 sema: *Sema,
30297 block: *Block,30345 block: *Block,
30298 src: LazySrcLoc,30346 src: LazySrcLoc,
src/Zir.zig+3
...@@ -1969,6 +1969,9 @@ pub const Inst = struct {...@@ -1969,6 +1969,9 @@ pub const Inst = struct {
1969 /// `small` 0=>weak 1=>strong1969 /// `small` 0=>weak 1=>strong
1970 /// `operand` is payload index to `Cmpxchg`.1970 /// `operand` is payload index to `Cmpxchg`.
1971 cmpxchg,1971 cmpxchg,
1972 /// Implement the builtin `@addrSpaceCast`
1973 /// `Operand` is payload index to `BinNode`. `lhs` is dest type, `rhs` is operand.
1974 addrspace_cast,
19721975
1973 pub const InstData = struct {1976 pub const InstData = struct {
1974 opcode: Extended,1977 opcode: Extended,
src/arch/aarch64/CodeGen.zig+1
...@@ -677,6 +677,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -677,6 +677,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
677 .union_init => try self.airUnionInit(inst),677 .union_init => try self.airUnionInit(inst),
678 .prefetch => try self.airPrefetch(inst),678 .prefetch => try self.airPrefetch(inst),
679 .mul_add => try self.airMulAdd(inst),679 .mul_add => try self.airMulAdd(inst),
680 .addrspace_cast => return self.fail("TODO implement addrspace_cast", .{}),
680681
681 .@"try" => try self.airTry(inst),682 .@"try" => try self.airTry(inst),
682 .try_ptr => try self.airTryPtr(inst),683 .try_ptr => try self.airTryPtr(inst),
src/arch/arm/CodeGen.zig+1
...@@ -690,6 +690,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -690,6 +690,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
690 .union_init => try self.airUnionInit(inst),690 .union_init => try self.airUnionInit(inst),
691 .prefetch => try self.airPrefetch(inst),691 .prefetch => try self.airPrefetch(inst),
692 .mul_add => try self.airMulAdd(inst),692 .mul_add => try self.airMulAdd(inst),
693 .addrspace_cast => return self.fail("TODO implement addrspace_cast", .{}),
693694
694 .@"try" => try self.airTry(inst),695 .@"try" => try self.airTry(inst),
695 .try_ptr => try self.airTryPtr(inst),696 .try_ptr => try self.airTryPtr(inst),
src/arch/riscv64/CodeGen.zig+1
...@@ -604,6 +604,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -604,6 +604,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
604 .union_init => try self.airUnionInit(inst),604 .union_init => try self.airUnionInit(inst),
605 .prefetch => try self.airPrefetch(inst),605 .prefetch => try self.airPrefetch(inst),
606 .mul_add => try self.airMulAdd(inst),606 .mul_add => try self.airMulAdd(inst),
607 .addrspace_cast => @panic("TODO"),
607608
608 .@"try" => @panic("TODO"),609 .@"try" => @panic("TODO"),
609 .try_ptr => @panic("TODO"),610 .try_ptr => @panic("TODO"),
src/arch/sparc64/CodeGen.zig+1
...@@ -618,6 +618,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -618,6 +618,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
618 .union_init => @panic("TODO try self.airUnionInit(inst)"),618 .union_init => @panic("TODO try self.airUnionInit(inst)"),
619 .prefetch => try self.airPrefetch(inst),619 .prefetch => try self.airPrefetch(inst),
620 .mul_add => @panic("TODO try self.airMulAdd(inst)"),620 .mul_add => @panic("TODO try self.airMulAdd(inst)"),
621 .addrspace_cast => @panic("TODO try self.airAddrSpaceCast(int)"),
621622
622 .@"try" => try self.airTry(inst),623 .@"try" => try self.airTry(inst),
623 .try_ptr => @panic("TODO try self.airTryPtr(inst)"),624 .try_ptr => @panic("TODO try self.airTryPtr(inst)"),
src/arch/wasm/CodeGen.zig+1
...@@ -1699,6 +1699,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {...@@ -1699,6 +1699,7 @@ fn genInst(self: *Self, inst: Air.Inst.Index) !WValue {
1699 .set_err_return_trace,1699 .set_err_return_trace,
1700 .is_named_enum_value,1700 .is_named_enum_value,
1701 .error_set_has_value,1701 .error_set_has_value,
1702 .addrspace_cast,
1702 => |tag| return self.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),1703 => |tag| return self.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}),
17031704
1704 .add_optimized,1705 .add_optimized,
src/arch/x86_64/CodeGen.zig+1
...@@ -695,6 +695,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {...@@ -695,6 +695,7 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void {
695 .union_init => try self.airUnionInit(inst),695 .union_init => try self.airUnionInit(inst),
696 .prefetch => try self.airPrefetch(inst),696 .prefetch => try self.airPrefetch(inst),
697 .mul_add => try self.airMulAdd(inst),697 .mul_add => try self.airMulAdd(inst),
698 .addrspace_cast => return self.fail("TODO implement addrspace_cast", .{}),
698699
699 .@"try" => try self.airTry(inst),700 .@"try" => try self.airTry(inst),
700 .try_ptr => try self.airTryPtr(inst),701 .try_ptr => try self.airTryPtr(inst),
src/codegen/c.zig+1
...@@ -1871,6 +1871,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO...@@ -1871,6 +1871,7 @@ fn genBody(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, OutO
1871 .aggregate_init => try airAggregateInit(f, inst),1871 .aggregate_init => try airAggregateInit(f, inst),
1872 .union_init => try airUnionInit(f, inst),1872 .union_init => try airUnionInit(f, inst),
1873 .prefetch => try airPrefetch(f, inst),1873 .prefetch => try airPrefetch(f, inst),
1874 .addrspace_cast => return f.fail("TODO: C backend: implement addrspace_cast", .{}),
18741875
1875 .@"try" => try airTry(f, inst),1876 .@"try" => try airTry(f, inst),
1876 .try_ptr => try airTryPtr(f, inst),1877 .try_ptr => try airTryPtr(f, inst),
src/codegen/llvm.zig+12
...@@ -4512,6 +4512,7 @@ pub const FuncGen = struct {...@@ -4512,6 +4512,7 @@ pub const FuncGen = struct {
4512 .aggregate_init => try self.airAggregateInit(inst),4512 .aggregate_init => try self.airAggregateInit(inst),
4513 .union_init => try self.airUnionInit(inst),4513 .union_init => try self.airUnionInit(inst),
4514 .prefetch => try self.airPrefetch(inst),4514 .prefetch => try self.airPrefetch(inst),
4515 .addrspace_cast => try self.airAddrSpaceCast(inst),
45154516
4516 .is_named_enum_value => try self.airIsNamedEnumValue(inst),4517 .is_named_enum_value => try self.airIsNamedEnumValue(inst),
4517 .error_set_has_value => try self.airErrorSetHasValue(inst),4518 .error_set_has_value => try self.airErrorSetHasValue(inst),
...@@ -9045,6 +9046,17 @@ pub const FuncGen = struct {...@@ -9045,6 +9046,17 @@ pub const FuncGen = struct {
9045 return null;9046 return null;
9046 }9047 }
90479048
9049 fn airAddrSpaceCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value {
9050 if (self.liveness.isUnused(inst)) return null;
9051
9052 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
9053 const inst_ty = self.air.typeOfIndex(inst);
9054 const operand = try self.resolveInst(ty_op.operand);
9055
9056 const llvm_dest_ty = try self.dg.lowerType(inst_ty);
9057 return self.builder.buildAddrSpaceCast(operand, llvm_dest_ty, "");
9058 }
9059
9048 fn softF80TruncOrExt(9060 fn softF80TruncOrExt(
9049 self: *FuncGen,9061 self: *FuncGen,
9050 operand: *llvm.Value,9062 operand: *llvm.Value,
src/print_air.zig+1
...@@ -244,6 +244,7 @@ const Writer = struct {...@@ -244,6 +244,7 @@ const Writer = struct {
244 .byte_swap,244 .byte_swap,
245 .bit_reverse,245 .bit_reverse,
246 .error_set_has_value,246 .error_set_has_value,
247 .addrspace_cast,
247 => try w.writeTyOp(s, inst),248 => try w.writeTyOp(s, inst),
248249
249 .block,250 .block,
src/print_zir.zig+1
...@@ -512,6 +512,7 @@ const Writer = struct {...@@ -512,6 +512,7 @@ const Writer = struct {
512 .err_set_cast,512 .err_set_cast,
513 .wasm_memory_grow,513 .wasm_memory_grow,
514 .prefetch,514 .prefetch,
515 .addrspace_cast,
515 => {516 => {
516 const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;517 const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
517 const src = LazySrcLoc.nodeOffset(inst_data.node);518 const src = LazySrcLoc.nodeOffset(inst_data.node);