-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Closed
Labels
bugObserved behavior contradicts documented or intended behaviorObserved behavior contradicts documented or intended behaviorfrontendTokenization, parsing, AstGen, Sema, and Liveness.Tokenization, parsing, AstGen, Sema, and Liveness.
Milestone
Description
Zig Version
0.10.0-dev.3685+dae7aeb33
Steps to Reproduce
const std = @import("std");
/// This struct will just provide some example ARMv4 instructions to fill the pipeline with
const Cpu = struct {
const Self = @This();
pc: u32,
pub fn fetch(self: *Self) u32 {
defer self.pc += 1;
return switch (self.pc) {
0 => 0xea00002e,
1 => 0x51aeff24,
2 => 0xe59fd0d0,
else => 0x00000000,
};
}
};
/// 3-stage Pipeline like what would be found in an ARM7TDMI
const Pipeline = struct {
const Self = @This();
/// Fetch and Decoding Stages of the pipeline
stage: [2]?u32,
pub fn init() Self {
return .{ .stage = [_]?u32{null} ** 2 };
}
/// Progresses the state of the pipeline by "one stage"
pub fn step(self: *Self, cpu: *Cpu) ?u32 {
// In stage1, L38 would copy the contents of `self.stage[0]` so that
// L40 could happen and the variable `opcode` which is declared and assigned in L38
// would then hold the old value of `self.stage[0]`.
//
// However, in stage2, this is not the case. L40 changes the value held in `opcode`
const opcode = self.stage[0];
self.stage[0] = self.stage[1];
self.stage[1] = cpu.fetch();
return opcode;
}
};
pub fn main() !void {
std.debug.print("run zig build test on stage1 and then stage2!", .{});
}
test "pipeline struct behaves like a 3 stage pipeline" {
var cpu: Cpu = .{ .pc = 0 };
var pipeline = Pipeline.init();
// On the third time calling Pipeline.step we should receive our first instruction
try std.testing.expectEqual(@as(?u32, null), pipeline.step(&cpu));
try std.testing.expectEqual(@as(?u32, null), pipeline.step(&cpu)); // stage 2 will fail here, as Pipeline.step returns 0xea00002e
try std.testing.expectEqual(@as(?u32, 0xea00002e), pipeline.step(&cpu));
try std.testing.expectEqual(@as(?u32, 0x51aeff24), pipeline.step(&cpu));
try std.testing.expectEqual(@as(?u32, 0xe59fd0d0), pipeline.step(&cpu));
try std.testing.expectEqual(@as(?u32, 0x00000000), pipeline.step(&cpu));
try std.testing.expectEqual(@as(?u32, 0x00000000), pipeline.step(&cpu));
}Expected Behavior
I expect the test to pass as it does on stage1.
To be more specific, I expect the line const opcode = self.stage[0]; to copy the value (it being a ?u32). So that the line below it self.stage[0] = self.stage[1]; does not mutate the value that opcode is bound to.
Actual Behavior
Currently, self.stage[0] = self.stage[1]; will mutate the value assigned to opcode.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugObserved behavior contradicts documented or intended behaviorObserved behavior contradicts documented or intended behaviorfrontendTokenization, parsing, AstGen, Sema, and Liveness.Tokenization, parsing, AstGen, Sema, and Liveness.