authorgravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-07-04 17:38:03-07:00
committergravatar for david@vortan.devDavid Rubin <david@vortan.dev> 2024-07-26 04:05:38-07:00
log9766b68c475438e24885dd75cf137d51e72ccfa3
tree85096570a8f57a68f209c741c5960d7bfb036786
parentf2bf6c1b11702179329a4693cea429d550f519e1
signaturelock-open Commit is signed but in an unrecognized format.

riscv: un-cache the `avl` and `vtype` when returning from a function call

the csrs `avl` and `vtype` are considered caller-saved so it could have changed while inside of the function. the easiest way to handle this is to just set the cached `vtype` and `avl` to null, so that the next time something needs to set it, it'll emit an instruction instead of relying on a potentially invalid setting.

5 files changed, 24 insertions(+), 3 deletions(-)

src/arch/riscv64/CodeGen.zig+10-1
...@@ -2481,6 +2481,11 @@ fn genBinOp(...@@ -2481,6 +2481,11 @@ fn genBinOp(
2481 .Float => .vfsubvv,2481 .Float => .vfsubvv,
2482 else => unreachable,2482 else => unreachable,
2483 },2483 },
2484 .mul => switch (child_ty.zigTypeTag(zcu)) {
2485 .Int => .vmulvv,
2486 .Float => .vfmulvv,
2487 else => unreachable,
2488 },
2484 else => return func.fail("TODO: genBinOp {s} Vector", .{@tagName(tag)}),2489 else => return func.fail("TODO: genBinOp {s} Vector", .{@tagName(tag)}),
2485 };2490 };
24862491
...@@ -2490,7 +2495,7 @@ fn genBinOp(...@@ -2490,7 +2495,7 @@ fn genBinOp(
2490 16 => .@"16",2495 16 => .@"16",
2491 32 => .@"32",2496 32 => .@"32",
2492 64 => .@"64",2497 64 => .@"64",
2493 else => unreachable,2498 else => return func.fail("TODO: genBinOp > 64 bit elements, found {d}", .{elem_size}),
2494 },2499 },
2495 .vlmul = .m1,2500 .vlmul = .m1,
2496 .vma = true,2501 .vma = true,
...@@ -4638,6 +4643,10 @@ fn genCall(...@@ -4638,6 +4643,10 @@ fn genCall(
4638 .lib => return func.fail("TODO: lib func calls", .{}),4643 .lib => return func.fail("TODO: lib func calls", .{}),
4639 }4644 }
46404645
4646 // reset the vector settings as they might have changed in the function
4647 func.avl = null;
4648 func.vtype = null;
4649
4641 return call_info.return_value.short;4650 return call_info.return_value.short;
4642}4651}
46434652
src/arch/riscv64/Encoding.zig+7
...@@ -288,6 +288,9 @@ pub const Mnemonic = enum {...@@ -288,6 +288,9 @@ pub const Mnemonic = enum {
288 vfaddvv,288 vfaddvv,
289 vfsubvv,289 vfsubvv,
290290
291 vmulvv,
292 vfmulvv,
293
291 vadcvv,294 vadcvv,
292295
293 vmvvx,296 vmvvx,
...@@ -546,9 +549,11 @@ pub const Mnemonic = enum {...@@ -546,9 +549,11 @@ pub const Mnemonic = enum {
546 .vsetvli => .{ .opcode = .OP_V, .data = .{ .f = .{ .funct3 = 0b111 } } },549 .vsetvli => .{ .opcode = .OP_V, .data = .{ .f = .{ .funct3 = 0b111 } } },
547 .vaddvv => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b000000, .funct3 = .OPIVV } } },550 .vaddvv => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b000000, .funct3 = .OPIVV } } },
548 .vsubvv => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b000010, .funct3 = .OPIVV } } },551 .vsubvv => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b000010, .funct3 = .OPIVV } } },
552 .vmulvv => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b100101, .funct3 = .OPIVV } } },
549 553
550 .vfaddvv => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b000000, .funct3 = .OPFVV } } },554 .vfaddvv => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b000000, .funct3 = .OPFVV } } },
551 .vfsubvv => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b000010, .funct3 = .OPFVV } } },555 .vfsubvv => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b000010, .funct3 = .OPFVV } } },
556 .vfmulvv => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b100100, .funct3 = .OPFVV } } },
552 557
553 .vadcvv => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b010000, .funct3 = .OPMVV } } },558 .vadcvv => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b010000, .funct3 = .OPMVV } } },
554 .vmvvx => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b010111, .funct3 = .OPIVX } } },559 .vmvvx => .{ .opcode = .OP_V, .data = .{ .vecmath = .{ .vm = true, .funct6 = 0b010111, .funct3 = .OPIVX } } },
...@@ -710,8 +715,10 @@ pub const InstEnc = enum {...@@ -710,8 +715,10 @@ pub const InstEnc = enum {
710715
711 .vaddvv,716 .vaddvv,
712 .vsubvv,717 .vsubvv,
718 .vmulvv,
713 .vfaddvv,719 .vfaddvv,
714 .vfsubvv,720 .vfsubvv,
721 .vfmulvv,
715 .vadcvv,722 .vadcvv,
716 .vmvvx,723 .vmvvx,
717 .vslidedownvx,724 .vslidedownvx,
src/arch/riscv64/Mir.zig+2
...@@ -145,6 +145,8 @@ pub const Inst = struct {...@@ -145,6 +145,8 @@ pub const Inst = struct {
145 vfaddvv,145 vfaddvv,
146 vsubvv,146 vsubvv,
147 vfsubvv,147 vfsubvv,
148 vmulvv,
149 vfmulvv,
148 vslidedownvx,150 vslidedownvx,
149151
150 /// A pseudo-instruction. Used for anything that isn't 1:1 with an152 /// A pseudo-instruction. Used for anything that isn't 1:1 with an
src/arch/riscv64/abi.zig+2
...@@ -200,6 +200,8 @@ pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass {...@@ -200,6 +200,8 @@ pub fn classifySystem(ty: Type, pt: Zcu.PerThread) [8]SystemClass {
200 result[0] = .integer;200 result[0] = .integer;
201 return result;201 return result;
202 }202 }
203 // we should pass vector registers of size <= 128 through 2 integer registers
204 // but we haven't implemented seperating vector registers into register_pairs
203 return memory_class;205 return memory_class;
204 },206 },
205 else => |bad_ty| std.debug.panic("classifySystem {s}", .{@tagName(bad_ty)}),207 else => |bad_ty| std.debug.panic("classifySystem {s}", .{@tagName(bad_ty)}),
test/behavior/vector.zig+3-2
...@@ -102,7 +102,6 @@ test "vector float operators" {...@@ -102,7 +102,6 @@ test "vector float operators" {
102 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO102 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
103 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;103 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
104 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;104 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest;
105 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
106 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO105 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
107106
108 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {107 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) {
...@@ -119,7 +118,7 @@ test "vector float operators" {...@@ -119,7 +118,7 @@ test "vector float operators" {
119 try expectEqual(v + x, .{ 11, 22, 33, 44 });118 try expectEqual(v + x, .{ 11, 22, 33, 44 });
120 try expectEqual(v - x, .{ 9, 18, 27, 36 });119 try expectEqual(v - x, .{ 9, 18, 27, 36 });
121 try expectEqual(v * x, .{ 10, 40, 90, 160 });120 try expectEqual(v * x, .{ 10, 40, 90, 160 });
122 try expectEqual(-x, .{ -1, -2, -3, -4 });121 if (builtin.zig_backend != .stage2_riscv64) try expectEqual(-x, .{ -1, -2, -3, -4 });
123 }122 }
124 };123 };
125124
...@@ -129,6 +128,8 @@ test "vector float operators" {...@@ -129,6 +128,8 @@ test "vector float operators" {
129 try S.doTheTest(f64);128 try S.doTheTest(f64);
130 try comptime S.doTheTest(f64);129 try comptime S.doTheTest(f64);
131130
131 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
132
132 try S.doTheTest(f16);133 try S.doTheTest(f16);
133 try comptime S.doTheTest(f16);134 try comptime S.doTheTest(f16);
134135