riscv: mutable globals

This commit is contained in:
David Rubin 2024-04-14 15:07:02 -07:00
parent d9e0cafe64
commit a615fbc1f8
4 changed files with 44 additions and 14 deletions

View File

@ -1452,7 +1452,7 @@ fn computeFrameLayout(self: *Self) !FrameLayout {
const spill_frame_size = frame_size[@intFromEnum(FrameIndex.spill_frame)];
const call_frame_size = frame_size[@intFromEnum(FrameIndex.call_frame)];
// TODO: this 24 should be a 16, but we were clobbering the top and bottom of the frame.
// TODO: this 64 should be a 16, but we were clobbering the top and bottom of the frame.
// maybe everything can go from the bottom?
const acc_frame_size: i32 = std.mem.alignForward(
i32,
@ -1497,7 +1497,7 @@ fn memSize(self: *Self, ty: Type) Memory.Size {
const mod = self.bin_file.comp.module.?;
return switch (ty.zigTypeTag(mod)) {
.Float => Memory.Size.fromBitSize(ty.floatBits(self.target.*)),
else => Memory.Size.fromSize(@intCast(ty.abiSize(mod))),
else => Memory.Size.fromByteSize(ty.abiSize(mod)),
};
}
@ -4318,6 +4318,21 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {
.off = -dst_reg_off.off,
} },
}),
.indirect => |ro| {
const src_reg = try self.copyToTmpRegister(ty, src_mcv);
_ = try self.addInst(.{
.tag = .pseudo,
.ops = .pseudo_store_rm,
.data = .{ .rm = .{
.r = src_reg,
.m = .{
.base = .{ .reg = ro.reg },
.mod = .{ .rm = .{ .disp = ro.off, .size = self.memSize(ty) } },
},
} },
});
},
.load_frame => |frame| return self.genSetStack(ty, frame, src_mcv),
.memory => return self.fail("TODO: genCopy memory", .{}),
.register_pair => |dst_regs| {

View File

@ -4,6 +4,7 @@ const Register = bits.Register;
const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
const Type = @import("../../type.zig").Type;
const Module = @import("../../Module.zig");
const assert = std.debug.assert;
pub const Class = enum { memory, byval, integer, double_integer, fields, none };
@ -93,14 +94,16 @@ pub fn classifyType(ty: Type, mod: *Module) Class {
/// There are a maximum of 8 possible return slots. Returned values are in
/// the beginning of the array; unused slots are filled with .none.
pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
pub fn classifySystem(ty: Type, zcu: *Module) [8]Class {
const ip = zcu.intern_pool;
var result = [1]Class{.none} ** 8;
switch (ty.zigTypeTag(mod)) {
switch (ty.zigTypeTag(zcu)) {
.Bool, .Void, .NoReturn => {
result[0] = .integer;
return result;
},
.Pointer => switch (ty.ptrSize(mod)) {
.Pointer => switch (ty.ptrSize(zcu)) {
.Slice => {
result[0] = .integer;
result[1] = .integer;
@ -112,7 +115,7 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
},
},
.Optional => {
if (ty.isPtrLikeOptional(mod)) {
if (ty.isPtrLikeOptional(zcu)) {
result[0] = .integer;
return result;
}
@ -121,7 +124,7 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
return result;
},
.Int, .Enum, .ErrorSet => {
const int_bits = ty.intInfo(mod).bits;
const int_bits = ty.intInfo(zcu).bits;
if (int_bits <= 64) {
result[0] = .integer;
return result;
@ -134,8 +137,8 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
unreachable; // support > 128 bit int arguments
},
.ErrorUnion => {
const payload_ty = ty.errorUnionPayload(mod);
const payload_bits = payload_ty.bitSize(mod);
const payload_ty = ty.errorUnionPayload(zcu);
const payload_bits = payload_ty.bitSize(zcu);
// the error union itself
result[0] = .integer;
@ -143,7 +146,20 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
// anyerror!void can fit into one register
if (payload_bits == 0) return result;
std.debug.panic("support ErrorUnion payload {}", .{payload_ty.fmt(mod)});
std.debug.panic("support ErrorUnion payload {}", .{payload_ty.fmt(zcu)});
},
.Struct => {
const loaded_struct = ip.loadStructType(ty.toIntern());
const ty_size = ty.abiSize(zcu);
if (loaded_struct.layout == .@"packed") {
assert(ty_size <= 16);
result[0] = .integer;
if (ty_size > 8) result[1] = .integer;
return result;
}
std.debug.panic("support Struct in classifySystem", .{});
},
else => |bad_ty| std.debug.panic("classifySystem {s}", .{@tagName(bad_ty)}),
}

View File

@ -20,7 +20,7 @@ pub const Memory = struct {
size: Size,
disp: i32 = 0,
},
off: u64,
off: i32,
};
pub const Size = enum(u4) {
@ -33,7 +33,7 @@ pub const Memory = struct {
/// Double word, 8 Bytes
dword,
pub fn fromSize(size: u32) Size {
pub fn fromByteSize(size: u64) Size {
return switch (size) {
1 => .byte,
2 => .hword,
@ -66,7 +66,7 @@ pub const Memory = struct {
/// Asserts `mem` can be represented as a `FrameLoc`.
pub fn toFrameLoc(mem: Memory, mir: Mir) Mir.FrameLoc {
const offset: i32 = switch (mem.mod) {
.off => |off| @intCast(off),
.off => |off| off,
.rm => |rm| rm.disp,
};

View File

@ -67,7 +67,6 @@ var g2: i32 = 0;
test "global variables" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
try expect(g2 == 0);
g2 = g1;