mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
x86_64: implement global payload pointers
This commit is contained in:
parent
2cbd442a9d
commit
57c38f6433
3 changed files with 35 additions and 8 deletions
|
|
@ -3467,14 +3467,17 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
|
||||||
try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
|
try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
|
||||||
}
|
}
|
||||||
|
|
||||||
const dst_mcv = if (src_mcv.isRegister() and self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
|
const dst_mcv: MCValue = if (src_mcv.isRegister() and
|
||||||
|
self.reuseOperand(inst, ty_op.operand, 0, src_mcv))
|
||||||
src_mcv
|
src_mcv
|
||||||
|
else if (self.liveness.isUnused(inst))
|
||||||
|
.{ .register = try self.copyToTmpRegister(dst_ty, src_mcv) }
|
||||||
else
|
else
|
||||||
try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
|
try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv);
|
||||||
|
|
||||||
const pl_ty = dst_ty.childType();
|
const pl_ty = dst_ty.childType();
|
||||||
const pl_abi_size = @intCast(i32, pl_ty.abiSize(self.target.*));
|
const pl_abi_size = @intCast(i32, pl_ty.abiSize(self.target.*));
|
||||||
try self.genSetMem(.{ .reg = dst_mcv.register }, pl_abi_size, Type.bool, .{ .immediate = 1 });
|
try self.genSetMem(.{ .reg = dst_mcv.getReg().? }, pl_abi_size, Type.bool, .{ .immediate = 1 });
|
||||||
break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv;
|
break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv;
|
||||||
};
|
};
|
||||||
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
|
return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
|
||||||
|
|
|
||||||
|
|
@ -380,7 +380,7 @@ pub fn generateSymbol(
|
||||||
|
|
||||||
return Result.ok;
|
return Result.ok;
|
||||||
},
|
},
|
||||||
.field_ptr, .elem_ptr => return lowerParentPtr(
|
.field_ptr, .elem_ptr, .opt_payload_ptr => return lowerParentPtr(
|
||||||
bin_file,
|
bin_file,
|
||||||
src_loc,
|
src_loc,
|
||||||
typed_value,
|
typed_value,
|
||||||
|
|
@ -812,7 +812,6 @@ fn lowerParentPtr(
|
||||||
reloc_info: RelocInfo,
|
reloc_info: RelocInfo,
|
||||||
) CodeGenError!Result {
|
) CodeGenError!Result {
|
||||||
const target = bin_file.options.target;
|
const target = bin_file.options.target;
|
||||||
|
|
||||||
switch (parent_ptr.tag()) {
|
switch (parent_ptr.tag()) {
|
||||||
.field_ptr => {
|
.field_ptr => {
|
||||||
const field_ptr = parent_ptr.castTag(.field_ptr).?.data;
|
const field_ptr = parent_ptr.castTag(.field_ptr).?.data;
|
||||||
|
|
@ -858,6 +857,31 @@ fn lowerParentPtr(
|
||||||
reloc_info.offset(@intCast(u32, elem_ptr.index * elem_ptr.elem_ty.abiSize(target))),
|
reloc_info.offset(@intCast(u32, elem_ptr.index * elem_ptr.elem_ty.abiSize(target))),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
.opt_payload_ptr => {
|
||||||
|
const opt_payload_ptr = parent_ptr.castTag(.opt_payload_ptr).?.data;
|
||||||
|
return lowerParentPtr(
|
||||||
|
bin_file,
|
||||||
|
src_loc,
|
||||||
|
typed_value,
|
||||||
|
opt_payload_ptr.container_ptr,
|
||||||
|
code,
|
||||||
|
debug_output,
|
||||||
|
reloc_info,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
.eu_payload_ptr => {
|
||||||
|
const eu_payload_ptr = parent_ptr.castTag(.eu_payload_ptr).?.data;
|
||||||
|
const pl_ty = eu_payload_ptr.container_ty.errorUnionPayload();
|
||||||
|
return lowerParentPtr(
|
||||||
|
bin_file,
|
||||||
|
src_loc,
|
||||||
|
typed_value,
|
||||||
|
eu_payload_ptr.container_ptr,
|
||||||
|
code,
|
||||||
|
debug_output,
|
||||||
|
reloc_info.offset(@intCast(u32, errUnionPayloadOffset(pl_ty, target))),
|
||||||
|
);
|
||||||
|
},
|
||||||
.variable, .decl_ref, .decl_ref_mut => |tag| return lowerDeclRef(
|
.variable, .decl_ref, .decl_ref_mut => |tag| return lowerDeclRef(
|
||||||
bin_file,
|
bin_file,
|
||||||
src_loc,
|
src_loc,
|
||||||
|
|
@ -1262,9 +1286,10 @@ pub fn genTypedValue(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn errUnionPayloadOffset(payload_ty: Type, target: std.Target) u64 {
|
pub fn errUnionPayloadOffset(payload_ty: Type, target: std.Target) u64 {
|
||||||
|
if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return 0;
|
||||||
const payload_align = payload_ty.abiAlignment(target);
|
const payload_align = payload_ty.abiAlignment(target);
|
||||||
const error_align = Type.anyerror.abiAlignment(target);
|
const error_align = Type.anyerror.abiAlignment(target);
|
||||||
if (payload_align >= error_align) {
|
if (payload_align >= error_align or !payload_ty.hasRuntimeBitsIgnoreComptime()) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return mem.alignForwardGeneric(u64, Type.anyerror.abiSize(target), payload_align);
|
return mem.alignForwardGeneric(u64, Type.anyerror.abiSize(target), payload_align);
|
||||||
|
|
@ -1272,9 +1297,10 @@ pub fn errUnionPayloadOffset(payload_ty: Type, target: std.Target) u64 {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn errUnionErrorOffset(payload_ty: Type, target: std.Target) u64 {
|
pub fn errUnionErrorOffset(payload_ty: Type, target: std.Target) u64 {
|
||||||
|
if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return 0;
|
||||||
const payload_align = payload_ty.abiAlignment(target);
|
const payload_align = payload_ty.abiAlignment(target);
|
||||||
const error_align = Type.anyerror.abiAlignment(target);
|
const error_align = Type.anyerror.abiAlignment(target);
|
||||||
if (payload_align >= error_align) {
|
if (payload_align >= error_align and payload_ty.hasRuntimeBitsIgnoreComptime()) {
|
||||||
return mem.alignForwardGeneric(u64, payload_ty.abiSize(target), error_align);
|
return mem.alignForwardGeneric(u64, payload_ty.abiSize(target), error_align);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,6 @@ test "optional with void type" {
|
||||||
test "address of unwrap optional" {
|
test "address of unwrap optional" {
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
|
||||||
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
|
||||||
|
|
||||||
|
|
@ -365,7 +364,6 @@ test "optional pointer to zero bit optional payload" {
|
||||||
}
|
}
|
||||||
|
|
||||||
test "optional pointer to zero bit error union payload" {
|
test "optional pointer to zero bit error union payload" {
|
||||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
|
||||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue