| 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 | 1452 | const spill_frame_size = frame_size[@intFromEnum(FrameIndex.spill_frame)]; |
| 1453 | 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 | 1456 | // maybe everything can go from the bottom? |
| 1457 | 1457 | const acc_frame_size: i32 = std.mem.alignForward( |
| 1458 | 1458 | i32, |
| ... | ... | @@ -1497,7 +1497,7 @@ fn memSize(self: *Self, ty: Type) Memory.Size { |
| 1497 | 1497 | const mod = self.bin_file.comp.module.?; |
| 1498 | 1498 | return switch (ty.zigTypeTag(mod)) { |
| 1499 | 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 | 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 | 4336 | .load_frame => |frame| return self.genSetStack(ty, frame, src_mcv), |
| 4322 | 4337 | .memory => return self.fail("TODO: genCopy memory", .{}), |
| 4323 | 4338 | .register_pair => |dst_regs| { |
src/arch/riscv64/abi.zig+24-8| ... | ... | @@ -4,6 +4,7 @@ const Register = bits.Register; |
| 4 | 4 | const RegisterManagerFn = @import("../../register_manager.zig").RegisterManager; |
| 5 | 5 | const Type = @import("../../type.zig").Type; |
| 6 | 6 | const Module = @import("../../Module.zig"); |
| 7 | const assert = std.debug.assert; | |
| 7 | 8 | |
| 8 | 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 | 94 | |
| 94 | 95 | /// There are a maximum of 8 possible return slots. Returned values are in |
| 95 | 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 | 99 | var result = [1]Class{.none} ** 8; |
| 98 | switch (ty.zigTypeTag(mod)) { | |
| 100 | ||
| 101 | switch (ty.zigTypeTag(zcu)) { | |
| 99 | 102 | .Bool, .Void, .NoReturn => { |
| 100 | 103 | result[0] = .integer; |
| 101 | 104 | return result; |
| 102 | 105 | }, |
| 103 | .Pointer => switch (ty.ptrSize(mod)) { | |
| 106 | .Pointer => switch (ty.ptrSize(zcu)) { | |
| 104 | 107 | .Slice => { |
| 105 | 108 | result[0] = .integer; |
| 106 | 109 | result[1] = .integer; |
| ... | ... | @@ -112,7 +115,7 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class { |
| 112 | 115 | }, |
| 113 | 116 | }, |
| 114 | 117 | .Optional => { |
| 115 | if (ty.isPtrLikeOptional(mod)) { | |
| 118 | if (ty.isPtrLikeOptional(zcu)) { | |
| 116 | 119 | result[0] = .integer; |
| 117 | 120 | return result; |
| 118 | 121 | } |
| ... | ... | @@ -121,7 +124,7 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class { |
| 121 | 124 | return result; |
| 122 | 125 | }, |
| 123 | 126 | .Int, .Enum, .ErrorSet => { |
| 124 | const int_bits = ty.intInfo(mod).bits; | |
| 127 | const int_bits = ty.intInfo(zcu).bits; | |
| 125 | 128 | if (int_bits <= 64) { |
| 126 | 129 | result[0] = .integer; |
| 127 | 130 | return result; |
| ... | ... | @@ -134,8 +137,8 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class { |
| 134 | 137 | unreachable; // support > 128 bit int arguments |
| 135 | 138 | }, |
| 136 | 139 | .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); | |
| 139 | 142 | |
| 140 | 143 | // the error union itself |
| 141 | 144 | result[0] = .integer; |
| ... | ... | @@ -143,7 +146,20 @@ pub fn classifySystem(ty: Type, mod: *Module) [8]Class { |
| 143 | 146 | // anyerror!void can fit into one register |
| 144 | 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 | 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 | 20 | size: Size, |
| 21 | 21 | disp: i32 = 0, |
| 22 | 22 | }, |
| 23 | off: u64, | |
| 23 | off: i32, | |
| 24 | 24 | }; |
| 25 | 25 | |
| 26 | 26 | pub const Size = enum(u4) { |
| ... | ... | @@ -33,7 +33,7 @@ pub const Memory = struct { |
| 33 | 33 | /// Double word, 8 Bytes |
| 34 | 34 | dword, |
| 35 | 35 | |
| 36 | pub fn fromSize(size: u32) Size { | |
| 36 | pub fn fromByteSize(size: u64) Size { | |
| 37 | 37 | return switch (size) { |
| 38 | 38 | 1 => .byte, |
| 39 | 39 | 2 => .hword, |
| ... | ... | @@ -66,7 +66,7 @@ pub const Memory = struct { |
| 66 | 66 | /// Asserts `mem` can be represented as a `FrameLoc`. |
| 67 | 67 | pub fn toFrameLoc(mem: Memory, mir: Mir) Mir.FrameLoc { |
| 68 | 68 | const offset: i32 = switch (mem.mod) { |
| 69 | .off => |off| @intCast(off), | |
| 69 | .off => |off| off, | |
| 70 | 70 | .rm => |rm| rm.disp, |
| 71 | 71 | }; |
| 72 | 72 |
test/behavior/basic.zig-1| ... | ... | @@ -67,7 +67,6 @@ var g2: i32 = 0; |
| 67 | 67 | |
| 68 | 68 | test "global variables" { |
| 69 | 69 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO |
| 70 | if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; | |
| 71 | 70 | |
| 72 | 71 | try expect(g2 == 0); |
| 73 | 72 | g2 = g1; |