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 {...@@ -1452,7 +1452,7 @@ fn computeFrameLayout(self: *Self) !FrameLayout {
1452 const spill_frame_size = frame_size[@intFromEnum(FrameIndex.spill_frame)];1452 const spill_frame_size = frame_size[@intFromEnum(FrameIndex.spill_frame)];
1453 const call_frame_size = frame_size[@intFromEnum(FrameIndex.call_frame)];1453 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.
1456 // maybe everything can go from the bottom?1456 // maybe everything can go from the bottom?
1457 const acc_frame_size: i32 = std.mem.alignForward(1457 const acc_frame_size: i32 = std.mem.alignForward(
1458 i32,1458 i32,
...@@ -1497,7 +1497,7 @@ fn memSize(self: *Self, ty: Type) Memory.Size {...@@ -1497,7 +1497,7 @@ fn memSize(self: *Self, ty: Type) Memory.Size {
1497 const mod = self.bin_file.comp.module.?;1497 const mod = self.bin_file.comp.module.?;
1498 return switch (ty.zigTypeTag(mod)) {1498 return switch (ty.zigTypeTag(mod)) {
1499 .Float => Memory.Size.fromBitSize(ty.floatBits(self.target.*)),1499 .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)),
1501 };1501 };
1502}1502}
15031503
...@@ -4318,6 +4318,21 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {...@@ -4318,6 +4318,21 @@ fn genCopy(self: *Self, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {
4318 .off = -dst_reg_off.off,4318 .off = -dst_reg_off.off,
4319 } },4319 } },
4320 }),4320 }),
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 },
4321 .load_frame => |frame| return self.genSetStack(ty, frame, src_mcv),4336 .load_frame => |frame| return self.genSetStack(ty, frame, src_mcv),
4322 .memory => return self.fail("TODO: genCopy memory", .{}),4337 .memory => return self.fail("TODO: genCopy memory", .{}),
4323 .register_pair => |dst_regs| {4338 .register_pair => |dst_regs| {
src/arch/riscv64/abi.zig+24-8
...@@ -4,6 +4,7 @@ const Register = bits.Register;...@@ -4,6 +4,7 @@ const Register = bits.Register;
4const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;4const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager;
5const Type = @import("../../type.zig").Type;5const Type = @import("../../type.zig").Type;
6const Module = @import("../../Module.zig");6const Module = @import("../../Module.zig");
7const assert = std.debug.assert;
78
8pub const Class = enum { memory, byval, integer, double_integer, fields, none };9pub const Class = enum { memory, byval, integer, double_integer, fields, none };
910
...@@ -93,14 +94,16 @@ pub fn classifyType(ty: Type, mod: *Module) Class {...@@ -93,14 +94,16 @@ pub fn classifyType(ty: Type, mod: *Module) Class {
9394
94/// There are a maximum of 8 possible return slots. Returned values are in95/// There are a maximum of 8 possible return slots. Returned values are in
95/// the beginning of the array; unused slots are filled with .none.96/// 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;
97 var result = [1]Class{.none} ** 8;99 var result = [1]Class{.none} ** 8;
98 switch (ty.zigTypeTag(mod)) {100
101 switch (ty.zigTypeTag(zcu)) {
99 .Bool, .Void, .NoReturn => {102 .Bool, .Void, .NoReturn => {
100 result[0] = .integer;103 result[0] = .integer;
101 return result;104 return result;
102 },105 },
103 .Pointer => switch (ty.ptrSize(mod)) {106 .Pointer => switch (ty.ptrSize(zcu)) {
104 .Slice => {107 .Slice => {
105 result[0] = .integer;108 result[0] = .integer;
106 result[1] = .integer;109 result[1] = .integer;
...@@ -112,7 +115,7 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {...@@ -112,7 +115,7 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
112 },115 },
113 },116 },
114 .Optional => {117 .Optional => {
115 if (ty.isPtrLikeOptional(mod)) {118 if (ty.isPtrLikeOptional(zcu)) {
116 result[0] = .integer;119 result[0] = .integer;
117 return result;120 return result;
118 }121 }
...@@ -121,7 +124,7 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {...@@ -121,7 +124,7 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
121 return result;124 return result;
122 },125 },
123 .Int, .Enum, .ErrorSet => {126 .Int, .Enum, .ErrorSet => {
124 const int_bits = ty.intInfo(mod).bits;127 const int_bits = ty.intInfo(zcu).bits;
125 if (int_bits <= 64) {128 if (int_bits <= 64) {
126 result[0] = .integer;129 result[0] = .integer;
127 return result;130 return result;
...@@ -134,8 +137,8 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {...@@ -134,8 +137,8 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
134 unreachable; // support > 128 bit int arguments137 unreachable; // support > 128 bit int arguments
135 },138 },
136 .ErrorUnion => {139 .ErrorUnion => {
137 const payload_ty = ty.errorUnionPayload(mod);140 const payload_ty = ty.errorUnionPayload(zcu);
138 const payload_bits = payload_ty.bitSize(mod);141 const payload_bits = payload_ty.bitSize(zcu);
139142
140 // the error union itself143 // the error union itself
141 result[0] = .integer;144 result[0] = .integer;
...@@ -143,7 +146,20 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {...@@ -143,7 +146,20 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class {
143 // anyerror!void can fit into one register146 // anyerror!void can fit into one register
144 if (payload_bits == 0) return result;147 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", .{});
147 },163 },
148 else => |bad_ty| std.debug.panic("classifySystem {s}", .{@tagName(bad_ty)}),164 else => |bad_ty| std.debug.panic("classifySystem {s}", .{@tagName(bad_ty)}),
149 }165 }
src/arch/riscv64/bits.zig+3-3
...@@ -20,7 +20,7 @@ pub const Memory = struct {...@@ -20,7 +20,7 @@ pub const Memory = struct {
20 size: Size,20 size: Size,
21 disp: i32 = 0,21 disp: i32 = 0,
22 },22 },
23 off: u64,23 off: i32,
24 };24 };
2525
26 pub const Size = enum(u4) {26 pub const Size = enum(u4) {
...@@ -33,7 +33,7 @@ pub const Memory = struct {...@@ -33,7 +33,7 @@ pub const Memory = struct {
33 /// Double word, 8 Bytes33 /// Double word, 8 Bytes
34 dword,34 dword,
3535
36 pub fn fromSize(size: u32) Size {36 pub fn fromByteSize(size: u64) Size {
37 return switch (size) {37 return switch (size) {
38 1 => .byte,38 1 => .byte,
39 2 => .hword,39 2 => .hword,
...@@ -66,7 +66,7 @@ pub const Memory = struct {...@@ -66,7 +66,7 @@ pub const Memory = struct {
66 /// Asserts `mem` can be represented as a `FrameLoc`.66 /// Asserts `mem` can be represented as a `FrameLoc`.
67 pub fn toFrameLoc(mem: Memory, mir: Mir) Mir.FrameLoc {67 pub fn toFrameLoc(mem: Memory, mir: Mir) Mir.FrameLoc {
68 const offset: i32 = switch (mem.mod) {68 const offset: i32 = switch (mem.mod) {
69 .off => |off| @intCast(off),69 .off => |off| off,
70 .rm => |rm| rm.disp,70 .rm => |rm| rm.disp,
71 };71 };
7272
test/behavior/basic.zig-1
...@@ -67,7 +67,6 @@ var g2: i32 = 0;...@@ -67,7 +67,6 @@ var g2: i32 = 0;
6767
68test "global variables" {68test "global variables" {
69 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO69 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
70 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
7170
72 try expect(g2 == 0);71 try expect(g2 == 0);
73 g2 = g1;72 g2 = g1;