| author | |
| committer | |
| log | a615fbc1f8330e455d02fdda5c6de257b0cde7f4 |
| tree | d18e559387fc70023dfe72607bea9a4866708add |
| parent | d9e0cafe64dd7dc56fc2d46bc29c18630a108356 |
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)]; |
| 1454 | 1454 | ||
| 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 | } |
| 1503 | 1503 | ||
| ... | @@ -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; |
| 4 | const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager; | 4 | const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager; |
| 5 | const Type = @import("../../type.zig").Type; | 5 | const Type = @import("../../type.zig").Type; |
| 6 | const Module = @import("../../Module.zig"); | 6 | const Module = @import("../../Module.zig"); |
| 7 | const assert = std.debug.assert; | ||
| 7 | 8 | ||
| 8 | pub const Class = enum { memory, byval, integer, double_integer, fields, none }; | 9 | pub const Class = enum { memory, byval, integer, double_integer, fields, none }; |
| 9 | 10 | ||
| ... | @@ -93,14 +94,16 @@ pub fn classifyType(ty: Type, mod: *Module) Class { | ... | @@ -93,14 +94,16 @@ pub fn classifyType(ty: Type, mod: *Module) Class { |
| 93 | 94 | ||
| 94 | /// There are a maximum of 8 possible return slots. Returned values are in | 95 | /// 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. |
| 96 | pub fn classifySystem(ty: Type, mod: *Module) [8]Class { | 97 | pub 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 arguments | 137 | 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); |
| 139 | 142 | ||
| 140 | // the error union itself | 143 | // 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 register | 146 | // anyerror!void can fit into one register |
| 144 | if (payload_bits == 0) return result; | 147 | if (payload_bits == 0) return result; |
| 145 | 148 | ||
| 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 | }; |
| 25 | 25 | ||
| 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 Bytes | 33 | /// Double word, 8 Bytes |
| 34 | dword, | 34 | dword, |
| 35 | 35 | ||
| 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 | }; |
| 72 | 72 |
test/behavior/basic.zig-1| ... | @@ -67,7 +67,6 @@ var g2: i32 = 0; | ... | @@ -67,7 +67,6 @@ var g2: i32 = 0; |
| 67 | 67 | ||
| 68 | test "global variables" { | 68 | test "global variables" { |
| 69 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | 69 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 70 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | ||
| 71 | 70 | ||
| 72 | try expect(g2 == 0); | 71 | try expect(g2 == 0); |
| 73 | g2 = g1; | 72 | g2 = g1; |