authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-15 21:25:42-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-15 21:25:42-07:00
log07606d12daabe8c201dba3d5b27e702ce58d0ffb
treee19a4fb6d5d5859e0378212d9ec9e92b704b98d7
parent7cd94d212361bc5662e8cc6959cd32edca1df03a

stage2: remove SPU Mark II backend

As it stands, the backend is incomplete, and there is no active contributor, making it dead weight. However, anyone is free to resurrect this backend at any time.

7 files changed, 1 insertions(+), 543 deletions(-)

BRANCH_TODO-2
...@@ -1,5 +1,3 @@...@@ -1,5 +1,3 @@
1 * get stage2 tests passing
2 - spu-ii test is saying "unimplemented" for some reason
3 * modify stage2 tests so that only 1 uses _start and the rest use1 * modify stage2 tests so that only 1 uses _start and the rest use
4 pub fn main2 pub fn main
5 * modify stage2 CBE tests so that only 1 uses pub export main and the3 * modify stage2 CBE tests so that only 1 uses pub export main and the
src/codegen.zig-67
...@@ -117,7 +117,6 @@ pub fn generateSymbol(...@@ -117,7 +117,6 @@ pub fn generateSymbol(
117 //.sparcv9 => return Function(.sparcv9).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),117 //.sparcv9 => return Function(.sparcv9).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
118 //.sparcel => return Function(.sparcel).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),118 //.sparcel => return Function(.sparcel).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
119 //.s390x => return Function(.s390x).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),119 //.s390x => return Function(.s390x).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
120 .spu_2 => return Function(.spu_2).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
121 //.tce => return Function(.tce).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),120 //.tce => return Function(.tce).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
122 //.tcele => return Function(.tcele).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),121 //.tcele => return Function(.tcele).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
123 //.thumb => return Function(.thumb).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),122 //.thumb => return Function(.thumb).generateSymbol(bin_file, src_loc, typed_value, code, debug_output),
...@@ -2204,11 +2203,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2204,11 +2203,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2204 .riscv64 => {2203 .riscv64 => {
2205 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ebreak.toU32());2204 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ebreak.toU32());
2206 },2205 },
2207 .spu_2 => {
2208 try self.code.resize(self.code.items.len + 2);
2209 var instr = Instruction{ .condition = .always, .input0 = .zero, .input1 = .zero, .modify_flags = false, .output = .discard, .command = .undefined1 };
2210 mem.writeIntLittle(u16, self.code.items[self.code.items.len - 2 ..][0..2], @bitCast(u16, instr));
2211 },
2212 .arm, .armeb => {2206 .arm, .armeb => {
2213 writeInt(u32, try self.code.addManyAsArray(4), Instruction.bkpt(0).toU32());2207 writeInt(u32, try self.code.addManyAsArray(4), Instruction.bkpt(0).toU32());
2214 },2208 },
...@@ -2317,53 +2311,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2317,53 +2311,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2317 return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});2311 return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});
2318 }2312 }
2319 },2313 },
2320 .spu_2 => {
2321 if (inst.func.value()) |func_value| {
2322 if (info.args.len != 0) {
2323 return self.fail(inst.base.src, "TODO implement call with more than 0 parameters", .{});
2324 }
2325 if (func_value.castTag(.function)) |func_payload| {
2326 const func = func_payload.data;
2327 const got_addr = if (self.bin_file.cast(link.File.Elf)) |elf_file| blk: {
2328 const got = &elf_file.program_headers.items[elf_file.phdr_got_index.?];
2329 break :blk @intCast(u16, got.p_vaddr + func.owner_decl.link.elf.offset_table_index * 2);
2330 } else if (self.bin_file.cast(link.File.Coff)) |coff_file|
2331 @intCast(u16, coff_file.offset_table_virtual_address + func.owner_decl.link.coff.offset_table_index * 2)
2332 else
2333 unreachable;
2334
2335 assert(func.owner_decl.has_tv);
2336 const return_type = func.owner_decl.ty.fnReturnType();
2337 // First, push the return address, then jump; if noreturn, don't bother with the first step
2338 // TODO: implement packed struct -> u16 at comptime and move the bitcast here
2339 var instr = Instruction{ .condition = .always, .input0 = .immediate, .input1 = .zero, .modify_flags = false, .output = .jump, .command = .load16 };
2340 if (return_type.zigTypeTag() == .NoReturn) {
2341 try self.code.resize(self.code.items.len + 4);
2342 mem.writeIntLittle(u16, self.code.items[self.code.items.len - 4 ..][0..2], @bitCast(u16, instr));
2343 mem.writeIntLittle(u16, self.code.items[self.code.items.len - 2 ..][0..2], got_addr);
2344 return MCValue.unreach;
2345 } else {
2346 try self.code.resize(self.code.items.len + 8);
2347 var push = Instruction{ .condition = .always, .input0 = .immediate, .input1 = .zero, .modify_flags = false, .output = .push, .command = .ipget };
2348 mem.writeIntLittle(u16, self.code.items[self.code.items.len - 8 ..][0..2], @bitCast(u16, push));
2349 mem.writeIntLittle(u16, self.code.items[self.code.items.len - 6 ..][0..2], @as(u16, 4));
2350 mem.writeIntLittle(u16, self.code.items[self.code.items.len - 4 ..][0..2], @bitCast(u16, instr));
2351 mem.writeIntLittle(u16, self.code.items[self.code.items.len - 2 ..][0..2], got_addr);
2352 switch (return_type.zigTypeTag()) {
2353 .Void => return MCValue{ .none = {} },
2354 .NoReturn => unreachable,
2355 else => return self.fail(inst.base.src, "TODO implement fn call with non-void return value", .{}),
2356 }
2357 }
2358 } else if (func_value.castTag(.extern_fn)) |_| {
2359 return self.fail(inst.base.src, "TODO implement calling extern functions", .{});
2360 } else {
2361 return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{});
2362 }
2363 } else {
2364 return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});
2365 }
2366 },
2367 .arm, .armeb => {2314 .arm, .armeb => {
2368 for (info.args) |mc_arg, arg_i| {2315 for (info.args) |mc_arg, arg_i| {
2369 const arg = inst.args[arg_i];2316 const arg = inst.args[arg_i];
...@@ -3176,19 +3123,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3176,19 +3123,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
3176 if (!inst.is_volatile and inst.base.isUnused())3123 if (!inst.is_volatile and inst.base.isUnused())
3177 return MCValue.dead;3124 return MCValue.dead;
3178 switch (arch) {3125 switch (arch) {
3179 .spu_2 => {
3180 if (inst.inputs.len > 0 or inst.output_constraint != null) {
3181 return self.fail(inst.base.src, "TODO implement inline asm inputs / outputs for SPU Mark II", .{});
3182 }
3183 if (mem.eql(u8, inst.asm_source, "undefined0")) {
3184 try self.code.resize(self.code.items.len + 2);
3185 var instr = Instruction{ .condition = .always, .input0 = .zero, .input1 = .zero, .modify_flags = false, .output = .discard, .command = .undefined0 };
3186 mem.writeIntLittle(u16, self.code.items[self.code.items.len - 2 ..][0..2], @bitCast(u16, instr));
3187 return MCValue.none;
3188 } else {
3189 return self.fail(inst.base.src, "TODO implement support for more SPU II assembly instructions", .{});
3190 }
3191 },
3192 .arm, .armeb => {3126 .arm, .armeb => {
3193 for (inst.inputs) |input, i| {3127 for (inst.inputs) |input, i| {
3194 if (input.len < 3 or input[0] != '{' or input[input.len - 1] != '}') {3128 if (input.len < 3 or input[0] != '{' or input[input.len - 1] != '}') {
...@@ -4503,7 +4437,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -4503,7 +4437,6 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
4503 .i386 => @import("codegen/x86.zig"),4437 .i386 => @import("codegen/x86.zig"),
4504 .x86_64 => @import("codegen/x86_64.zig"),4438 .x86_64 => @import("codegen/x86_64.zig"),
4505 .riscv64 => @import("codegen/riscv64.zig"),4439 .riscv64 => @import("codegen/riscv64.zig"),
4506 .spu_2 => @import("codegen/spu-mk2.zig"),
4507 .arm, .armeb => @import("codegen/arm.zig"),4440 .arm, .armeb => @import("codegen/arm.zig"),
4508 .aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig"),4441 .aarch64, .aarch64_be, .aarch64_32 => @import("codegen/aarch64.zig"),
4509 else => struct {4442 else => struct {
src/codegen/spu-mk2.zig deleted-170
...@@ -1,170 +0,0 @@
1const std = @import("std");
2
3pub const Interpreter = @import("spu-mk2/interpreter.zig").Interpreter;
4
5pub const ExecutionCondition = enum(u3) {
6 always = 0,
7 when_zero = 1,
8 not_zero = 2,
9 greater_zero = 3,
10 less_than_zero = 4,
11 greater_or_equal_zero = 5,
12 less_or_equal_zero = 6,
13 overflow = 7,
14};
15
16pub const InputBehaviour = enum(u2) {
17 zero = 0,
18 immediate = 1,
19 peek = 2,
20 pop = 3,
21};
22
23pub const OutputBehaviour = enum(u2) {
24 discard = 0,
25 push = 1,
26 jump = 2,
27 jump_relative = 3,
28};
29
30pub const Command = enum(u5) {
31 copy = 0,
32 ipget = 1,
33 get = 2,
34 set = 3,
35 store8 = 4,
36 store16 = 5,
37 load8 = 6,
38 load16 = 7,
39 undefined0 = 8,
40 undefined1 = 9,
41 frget = 10,
42 frset = 11,
43 bpget = 12,
44 bpset = 13,
45 spget = 14,
46 spset = 15,
47 add = 16,
48 sub = 17,
49 mul = 18,
50 div = 19,
51 mod = 20,
52 @"and" = 21,
53 @"or" = 22,
54 xor = 23,
55 not = 24,
56 signext = 25,
57 rol = 26,
58 ror = 27,
59 bswap = 28,
60 asr = 29,
61 lsl = 30,
62 lsr = 31,
63};
64
65pub const Instruction = packed struct {
66 condition: ExecutionCondition,
67 input0: InputBehaviour,
68 input1: InputBehaviour,
69 modify_flags: bool,
70 output: OutputBehaviour,
71 command: Command,
72 reserved: u1 = 0,
73
74 pub fn format(instr: Instruction, comptime fmt: []const u8, options: std.fmt.FormatOptions, out: anytype) !void {
75 try std.fmt.format(out, "0x{x:0<4} ", .{@bitCast(u16, instr)});
76 try out.writeAll(switch (instr.condition) {
77 .always => " ",
78 .when_zero => "== 0",
79 .not_zero => "!= 0",
80 .greater_zero => " > 0",
81 .less_than_zero => " < 0",
82 .greater_or_equal_zero => ">= 0",
83 .less_or_equal_zero => "<= 0",
84 .overflow => "ovfl",
85 });
86 try out.writeAll(" ");
87 try out.writeAll(switch (instr.input0) {
88 .zero => "zero",
89 .immediate => "imm ",
90 .peek => "peek",
91 .pop => "pop ",
92 });
93 try out.writeAll(" ");
94 try out.writeAll(switch (instr.input1) {
95 .zero => "zero",
96 .immediate => "imm ",
97 .peek => "peek",
98 .pop => "pop ",
99 });
100 try out.writeAll(" ");
101 try out.writeAll(switch (instr.command) {
102 .copy => "copy ",
103 .ipget => "ipget ",
104 .get => "get ",
105 .set => "set ",
106 .store8 => "store8 ",
107 .store16 => "store16 ",
108 .load8 => "load8 ",
109 .load16 => "load16 ",
110 .undefined0 => "undefined",
111 .undefined1 => "undefined",
112 .frget => "frget ",
113 .frset => "frset ",
114 .bpget => "bpget ",
115 .bpset => "bpset ",
116 .spget => "spget ",
117 .spset => "spset ",
118 .add => "add ",
119 .sub => "sub ",
120 .mul => "mul ",
121 .div => "div ",
122 .mod => "mod ",
123 .@"and" => "and ",
124 .@"or" => "or ",
125 .xor => "xor ",
126 .not => "not ",
127 .signext => "signext ",
128 .rol => "rol ",
129 .ror => "ror ",
130 .bswap => "bswap ",
131 .asr => "asr ",
132 .lsl => "lsl ",
133 .lsr => "lsr ",
134 });
135 try out.writeAll(" ");
136 try out.writeAll(switch (instr.output) {
137 .discard => "discard",
138 .push => "push ",
139 .jump => "jmp ",
140 .jump_relative => "rjmp ",
141 });
142 try out.writeAll(" ");
143 try out.writeAll(if (instr.modify_flags)
144 "+ flags"
145 else
146 " ");
147 }
148};
149
150pub const FlagRegister = packed struct {
151 zero: bool,
152 negative: bool,
153 carry: bool,
154 carry_enabled: bool,
155 interrupt0_enabled: bool,
156 interrupt1_enabled: bool,
157 interrupt2_enabled: bool,
158 interrupt3_enabled: bool,
159 reserved: u8 = 0,
160};
161
162pub const Register = enum {
163 dummy,
164
165 pub fn allocIndex(self: Register) ?u4 {
166 return null;
167 }
168};
169
170pub const callee_preserved_regs = [_]Register{};
src/codegen/spu-mk2/interpreter.zig deleted-166
...@@ -1,166 +0,0 @@
1const std = @import("std");
2const log = std.log.scoped(.SPU_2_Interpreter);
3const spu = @import("../spu-mk2.zig");
4const FlagRegister = spu.FlagRegister;
5const Instruction = spu.Instruction;
6const ExecutionCondition = spu.ExecutionCondition;
7
8pub fn Interpreter(comptime Bus: type) type {
9 return struct {
10 ip: u16 = 0,
11 sp: u16 = undefined,
12 bp: u16 = undefined,
13 fr: FlagRegister = @bitCast(FlagRegister, @as(u16, 0)),
14 /// This is set to true when we hit an undefined0 instruction, allowing it to
15 /// be used as a trap for testing purposes
16 undefined0: bool = false,
17 /// This is set to true when we hit an undefined1 instruction, allowing it to
18 /// be used as a trap for testing purposes. undefined1 is used as a breakpoint.
19 undefined1: bool = false,
20 bus: Bus,
21
22 pub fn ExecuteBlock(self: *@This(), comptime size: ?u32) !void {
23 var count: usize = 0;
24 while (size == null or count < size.?) {
25 count += 1;
26 var instruction = @bitCast(Instruction, self.bus.read16(self.ip));
27
28 log.debug("Executing {}\n", .{instruction});
29
30 self.ip +%= 2;
31
32 const execute = switch (instruction.condition) {
33 .always => true,
34 .not_zero => !self.fr.zero,
35 .when_zero => self.fr.zero,
36 .overflow => self.fr.carry,
37 ExecutionCondition.greater_or_equal_zero => !self.fr.negative,
38 else => return error.Unimplemented,
39 };
40
41 if (execute) {
42 const val0 = switch (instruction.input0) {
43 .zero => @as(u16, 0),
44 .immediate => i: {
45 const val = self.bus.read16(@intCast(u16, self.ip));
46 self.ip +%= 2;
47 break :i val;
48 },
49 else => |e| e: {
50 // peek or pop; show value at current SP, and if pop, increment sp
51 const val = self.bus.read16(self.sp);
52 if (e == .pop) {
53 self.sp +%= 2;
54 }
55 break :e val;
56 },
57 };
58 const val1 = switch (instruction.input1) {
59 .zero => @as(u16, 0),
60 .immediate => i: {
61 const val = self.bus.read16(@intCast(u16, self.ip));
62 self.ip +%= 2;
63 break :i val;
64 },
65 else => |e| e: {
66 // peek or pop; show value at current SP, and if pop, increment sp
67 const val = self.bus.read16(self.sp);
68 if (e == .pop) {
69 self.sp +%= 2;
70 }
71 break :e val;
72 },
73 };
74
75 const output: u16 = switch (instruction.command) {
76 .get => self.bus.read16(self.bp +% (2 *% val0)),
77 .set => a: {
78 self.bus.write16(self.bp +% 2 *% val0, val1);
79 break :a val1;
80 },
81 .load8 => self.bus.read8(val0),
82 .load16 => self.bus.read16(val0),
83 .store8 => a: {
84 const val = @truncate(u8, val1);
85 self.bus.write8(val0, val);
86 break :a val;
87 },
88 .store16 => a: {
89 self.bus.write16(val0, val1);
90 break :a val1;
91 },
92 .copy => val0,
93 .add => a: {
94 var val: u16 = undefined;
95 self.fr.carry = @addWithOverflow(u16, val0, val1, &val);
96 break :a val;
97 },
98 .sub => a: {
99 var val: u16 = undefined;
100 self.fr.carry = @subWithOverflow(u16, val0, val1, &val);
101 break :a val;
102 },
103 .spset => a: {
104 self.sp = val0;
105 break :a val0;
106 },
107 .bpset => a: {
108 self.bp = val0;
109 break :a val0;
110 },
111 .frset => a: {
112 const val = (@bitCast(u16, self.fr) & val1) | (val0 & ~val1);
113 self.fr = @bitCast(FlagRegister, val);
114 break :a val;
115 },
116 .bswap => (val0 >> 8) | (val0 << 8),
117 .bpget => self.bp,
118 .spget => self.sp,
119 .ipget => self.ip +% (2 *% val0),
120 .lsl => val0 << 1,
121 .lsr => val0 >> 1,
122 .@"and" => val0 & val1,
123 .@"or" => val0 | val1,
124 .xor => val0 ^ val1,
125 .not => ~val0,
126 .undefined0 => {
127 self.undefined0 = true;
128 // Break out of the loop, and let the caller decide what to do
129 return;
130 },
131 .undefined1 => {
132 self.undefined1 = true;
133 // Break out of the loop, and let the caller decide what to do
134 return;
135 },
136 .signext => if ((val0 & 0x80) != 0)
137 (val0 & 0xFF) | 0xFF00
138 else
139 (val0 & 0xFF),
140 else => return error.Unimplemented,
141 };
142
143 switch (instruction.output) {
144 .discard => {},
145 .push => {
146 self.sp -%= 2;
147 self.bus.write16(self.sp, output);
148 },
149 .jump => {
150 self.ip = output;
151 },
152 else => return error.Unimplemented,
153 }
154 if (instruction.modify_flags) {
155 self.fr.negative = (output & 0x8000) != 0;
156 self.fr.zero = (output == 0x0000);
157 }
158 } else {
159 if (instruction.input0 == .immediate) self.ip +%= 2;
160 if (instruction.input1 == .immediate) self.ip +%= 2;
161 break;
162 }
163 }
164 }
165 };
166}
src/test.zig+1-114
...@@ -862,10 +862,7 @@ pub const TestContext = struct {...@@ -862,10 +862,7 @@ pub const TestContext = struct {
862 });862 });
863 } else switch (case.target.getExternalExecutor()) {863 } else switch (case.target.getExternalExecutor()) {
864 .native => try argv.append(exe_path),864 .native => try argv.append(exe_path),
865 .unavailable => {865 .unavailable => return, // Pass test.
866 try self.runInterpreterIfAvailable(allocator, &exec_node, case, tmp.dir, bin_name);
867 return; // Pass test.
868 },
869866
870 .qemu => |qemu_bin_name| if (enable_qemu) {867 .qemu => |qemu_bin_name| if (enable_qemu) {
871 // TODO Ability for test cases to specify whether to link libc.868 // TODO Ability for test cases to specify whether to link libc.
...@@ -953,116 +950,6 @@ pub const TestContext = struct {...@@ -953,116 +950,6 @@ pub const TestContext = struct {
953 }950 }
954 }951 }
955952
956 fn runInterpreterIfAvailable(
957 self: *TestContext,
958 gpa: *Allocator,
959 node: *std.Progress.Node,
960 case: Case,
961 tmp_dir: std.fs.Dir,
962 bin_name: []const u8,
963 ) !void {
964 const arch = case.target.cpu_arch orelse return;
965 switch (arch) {
966 .spu_2 => return self.runSpu2Interpreter(gpa, node, case, tmp_dir, bin_name),
967 else => return,
968 }
969 }
970
971 fn runSpu2Interpreter(
972 self: *TestContext,
973 gpa: *Allocator,
974 update_node: *std.Progress.Node,
975 case: Case,
976 tmp_dir: std.fs.Dir,
977 bin_name: []const u8,
978 ) !void {
979 const spu = @import("codegen/spu-mk2.zig");
980 if (case.target.os_tag) |os| {
981 if (os != .freestanding) {
982 std.debug.panic("Only freestanding makes sense for SPU-II tests!", .{});
983 }
984 } else {
985 std.debug.panic("SPU_2 has no native OS, check the test!", .{});
986 }
987
988 var interpreter = spu.Interpreter(struct {
989 RAM: [0x10000]u8 = undefined,
990
991 pub fn read8(bus: @This(), addr: u16) u8 {
992 return bus.RAM[addr];
993 }
994 pub fn read16(bus: @This(), addr: u16) u16 {
995 return std.mem.readIntLittle(u16, bus.RAM[addr..][0..2]);
996 }
997
998 pub fn write8(bus: *@This(), addr: u16, val: u8) void {
999 bus.RAM[addr] = val;
1000 }
1001
1002 pub fn write16(bus: *@This(), addr: u16, val: u16) void {
1003 std.mem.writeIntLittle(u16, bus.RAM[addr..][0..2], val);
1004 }
1005 }){
1006 .bus = .{},
1007 };
1008
1009 {
1010 var load_node = update_node.start("load", 0);
1011 load_node.activate();
1012 defer load_node.end();
1013
1014 var file = try tmp_dir.openFile(bin_name, .{ .read = true });
1015 defer file.close();
1016
1017 const header = try std.elf.Header.read(&file);
1018 var iterator = header.program_header_iterator(&file);
1019
1020 var none_loaded = true;
1021
1022 while (try iterator.next()) |phdr| {
1023 if (phdr.p_type != std.elf.PT_LOAD) {
1024 std.debug.print("Encountered unexpected ELF program header: type {}\n", .{phdr.p_type});
1025 return error.UnexpectedElfProgramHeader;
1026 }
1027 if (phdr.p_paddr != phdr.p_vaddr) {
1028 std.debug.print("Physical address does not match virtual address in ELF header!\n", .{});
1029 return error.PhysicalAddressMismatchVirt;
1030 }
1031 if (phdr.p_filesz != phdr.p_memsz) {
1032 std.debug.print("Physical size does not match virtual size in ELF header!\n", .{});
1033 return error.PhysicalSizeMismatchVirt;
1034 }
1035 if ((try file.pread(interpreter.bus.RAM[phdr.p_paddr .. phdr.p_paddr + phdr.p_filesz], phdr.p_offset)) != phdr.p_filesz) {
1036 std.debug.print("Read less than expected from ELF file!", .{});
1037 return error.ElfFileEof;
1038 }
1039 std.log.scoped(.spu2_test).debug("Loaded 0x{x} bytes to 0x{x:0<4}\n", .{ phdr.p_filesz, phdr.p_paddr });
1040 none_loaded = false;
1041 }
1042 if (none_loaded) {
1043 std.debug.print("No data found in ELF file!\n", .{});
1044 return error.EmptyElfFile;
1045 }
1046 }
1047
1048 var exec_node = update_node.start("execute", 0);
1049 exec_node.activate();
1050 defer exec_node.end();
1051
1052 var blocks: u16 = 1000;
1053 const block_size = 1000;
1054 while (!interpreter.undefined0) {
1055 const pre_ip = interpreter.ip;
1056 if (blocks > 0) {
1057 blocks -= 1;
1058 try interpreter.ExecuteBlock(block_size);
1059 if (pre_ip == interpreter.ip) {
1060 std.debug.print("Infinite loop detected in SPU II test!\n", .{});
1061 return error.InfiniteLoop;
1062 }
1063 }
1064 }
1065 }
1066};953};
1067954
1068fn dumpArgs(argv: []const []const u8) void {955fn dumpArgs(argv: []const []const u8) void {
test/stage2/spu-ii.zig deleted-23
...@@ -1,23 +0,0 @@
1const std = @import("std");
2const TestContext = @import("../../src/test.zig").TestContext;
3
4const spu = std.zig.CrossTarget{
5 .cpu_arch = .spu_2,
6 .os_tag = .freestanding,
7};
8
9pub fn addCases(ctx: *TestContext) !void {
10 {
11 var case = ctx.exe("SPU-II Basic Test", spu);
12 case.addCompareOutput(
13 \\fn killEmulator() noreturn {
14 \\ asm volatile ("undefined0");
15 \\ unreachable;
16 \\}
17 \\
18 \\pub export fn _start() noreturn {
19 \\ killEmulator();
20 \\}
21 , "");
22 }
23}
test/stage2/test.zig-1
...@@ -13,7 +13,6 @@ const linux_x64 = std.zig.CrossTarget{...@@ -13,7 +13,6 @@ const linux_x64 = std.zig.CrossTarget{
1313
14pub fn addCases(ctx: *TestContext) !void {14pub fn addCases(ctx: *TestContext) !void {
15 try @import("cbe.zig").addCases(ctx);15 try @import("cbe.zig").addCases(ctx);
16 try @import("spu-ii.zig").addCases(ctx);
17 try @import("arm.zig").addCases(ctx);16 try @import("arm.zig").addCases(ctx);
18 try @import("aarch64.zig").addCases(ctx);17 try @import("aarch64.zig").addCases(ctx);
19 try @import("llvm.zig").addCases(ctx);18 try @import("llvm.zig").addCases(ctx);