Commit a615fbc1f8
Changed files (4)
src
arch
riscv64
test
behavior
src/arch/riscv64/abi.zig
@@ -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)}),
}
src/arch/riscv64/bits.zig
@@ -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,
};
src/arch/riscv64/CodeGen.zig
@@ -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| {
test/behavior/basic.zig
@@ -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;