authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-04-14 15:07:02-07:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-05-11 02:17:24-07:00
loga615fbc1f8330e455d02fdda5c6de257b0cde7f4
treed18e559387fc70023dfe72607bea9a4866708add
parentd9e0cafe64dd7dc56fc2d46bc29c18630a108356

riscv: mutable globals


4 files changed, 44 insertions(+), 14 deletions(-)

src/arch/riscv64/CodeGen.zig+17-2
......@@ -1452,7 +1452,7 @@ fn computeFrameLayout(self: *Self) !FrameLayout {
14521452 const spill_frame_size = frame_size[@intFromEnum(FrameIndex.spill_frame)];
14531453 const call_frame_size = frame_size[@intFromEnum(FrameIndex.call_frame)];
14541454
1455 // TODO: this 24 should be a 16, but we were clobbering the top and bottom of the frame.
1455 // TODO: this 64 should be a 16, but we were clobbering the top and bottom of the frame.
14561456 // maybe everything can go from the bottom?
14571457 const acc_frame_size: i32 = std.mem.alignForward(
14581458 i32,
......@@ -1497,7 +1497,7 @@ fn memSize(self: *Self, ty: Type) Memory.Size {
14971497 const mod = self.bin_file.comp.module.?;
14981498 return switch (ty.zigTypeTag(mod)) {
14991499 .Float => Memory.Size.fromBitSize(ty.floatBits(self.target.*)),
1500 else => Memory.Size.fromSize(@intCast(ty.abiSize(mod))),
1500 else => Memory.Size.fromByteSize(ty.abiSize(mod)),
15011501 };
15021502}
15031503
......@@ -4318,6 +4318,21 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {
43184318 .off = -dst_reg_off.off,
43194319 } },
43204320 }),
4321 .indirect => |ro| {
4322 const src_reg = try self.copyToTmpRegister(ty, src_mcv);
4323
4324 _ = try self.addInst(.{
4325 .tag = .pseudo,
4326 .ops = .pseudo_store_rm,
4327 .data = .{ .rm = .{
4328 .r = src_reg,
4329 .m = .{
4330 .base = .{ .reg = ro.reg },
4331 .mod = .{ .rm = .{ .disp = ro.off, .size = self.memSize(ty) } },
4332 },
4333 } },
4334 });
4335 },
43214336 .load_frame => |frame| return self.genSetStack(ty, frame, src_mcv),
43224337 .memory => return self.fail("TODO: genCopy memory", .{}),
43234338 .register_pair => |dst_regs| {
src/arch/riscv64/abi.zig+24-8
......@@ -4,6 +4,7 @@ const Register = bits.Register;
44const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
55const Type = @import("../../type.zig").Type;
66const Module = @import("../../Module.zig");
7const assert = std.debug.assert;
78
89pub const Class = enum { memory, byval, integer, double_integer, fields, none };
910
......@@ -93,14 +94,16 @@ pub fn classifyType(ty: Type, mod: *Module) Class {
9394
9495/// There are a maximum of 8 possible return slots. Returned values are in
9596/// the beginning of the array; unused slots are filled with .none.
96pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
97pub fn classifySystem(ty: Type, zcu: *Module) [8]Class {
98 const ip = zcu.intern_pool;
9799 var result = [1]Class{.none} ** 8;
98 switch (ty.zigTypeTag(mod)) {
100
101 switch (ty.zigTypeTag(zcu)) {
99102 .Bool, .Void, .NoReturn => {
100103 result[0] = .integer;
101104 return result;
102105 },
103 .Pointer => switch (ty.ptrSize(mod)) {
106 .Pointer => switch (ty.ptrSize(zcu)) {
104107 .Slice => {
105108 result[0] = .integer;
106109 result[1] = .integer;
......@@ -112,7 +115,7 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
112115 },
113116 },
114117 .Optional => {
115 if (ty.isPtrLikeOptional(mod)) {
118 if (ty.isPtrLikeOptional(zcu)) {
116119 result[0] = .integer;
117120 return result;
118121 }
......@@ -121,7 +124,7 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
121124 return result;
122125 },
123126 .Int, .Enum, .ErrorSet => {
124 const int_bits = ty.intInfo(mod).bits;
127 const int_bits = ty.intInfo(zcu).bits;
125128 if (int_bits <= 64) {
126129 result[0] = .integer;
127130 return result;
......@@ -134,8 +137,8 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
134137 unreachable; // support > 128 bit int arguments
135138 },
136139 .ErrorUnion => {
137 const payload_ty = ty.errorUnionPayload(mod);
138 const payload_bits = payload_ty.bitSize(mod);
140 const payload_ty = ty.errorUnionPayload(zcu);
141 const payload_bits = payload_ty.bitSize(zcu);
139142
140143 // the error union itself
141144 result[0] = .integer;
......@@ -143,7 +146,20 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
143146 // anyerror!void can fit into one register
144147 if (payload_bits == 0) return result;
145148
146 std.debug.panic("support ErrorUnion payload {}", .{payload_ty.fmt(mod)});
149 std.debug.panic("support ErrorUnion payload {}", .{payload_ty.fmt(zcu)});
150 },
151 .Struct => {
152 const loaded_struct = ip.loadStructType(ty.toIntern());
153 const ty_size = ty.abiSize(zcu);
154
155 if (loaded_struct.layout == .@"packed") {
156 assert(ty_size <= 16);
157 result[0] = .integer;
158 if (ty_size > 8) result[1] = .integer;
159 return result;
160 }
161
162 std.debug.panic("support Struct in classifySystem", .{});
147163 },
148164 else => |bad_ty| std.debug.panic("classifySystem {s}", .{@tagName(bad_ty)}),
149165 }
src/arch/riscv64/bits.zig+3-3
......@@ -20,7 +20,7 @@ pub const Memory = struct {
2020 size: Size,
2121 disp: i32 = 0,
2222 },
23 off: u64,
23 off: i32,
2424 };
2525
2626 pub const Size = enum(u4) {
......@@ -33,7 +33,7 @@ pub const Memory = struct {
3333 /// Double word, 8 Bytes
3434 dword,
3535
36 pub fn fromSize(size: u32) Size {
36 pub fn fromByteSize(size: u64) Size {
3737 return switch (size) {
3838 1 => .byte,
3939 2 => .hword,
......@@ -66,7 +66,7 @@ pub const Memory = struct {
6666 /// Asserts `mem` can be represented as a `FrameLoc`.
6767 pub fn toFrameLoc(mem: Memory, mir: Mir) Mir.FrameLoc {
6868 const offset: i32 = switch (mem.mod) {
69 .off => |off| @intCast(off),
69 .off => |off| off,
7070 .rm => |rm| rm.disp,
7171 };
7272
test/behavior/basic.zig-1
......@@ -67,7 +67,6 @@ var g2: i32 = 0;
6767
6868test "global variables" {
6969 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
70 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7170
7271 try expect(g2 == 0);
7372 g2 = g1;