authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-03-25 00:51:01+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-03-25 00:51:01+01:00
logb0ab55b8ea82145aba23accdf480efe5632660fd
treead1a50d92ee16c357c40289a3153f3e49b49a1d4
parent558a5c7913434547c55355af0075a9d34db0d4bc
parent164d01c1dc258068c23016ec2110e2b6080b8a2d

Merge pull request 'Add psp os' (#31609) from IridescentRose/zig:psp-os-target into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31609 Reviewed-by: Andrew Kelley <andrew@ziglang.org> Reviewed-by: Alex Rønne Petersen <alex@alexrp.com>

9 files changed, 98 insertions(+), 5 deletions(-)

lib/std/Io/Dir.zig+1-1
...@@ -52,7 +52,7 @@ pub const max_path_bytes = switch (native_os) {...@@ -52,7 +52,7 @@ pub const max_path_bytes = switch (native_os) {
52/// On WASI, file name components are encoded as valid UTF-8.52/// On WASI, file name components are encoded as valid UTF-8.
53/// On other platforms, `[]u8` components are an opaque sequence of bytes with no particular encoding.53/// On other platforms, `[]u8` components are an opaque sequence of bytes with no particular encoding.
54pub const max_name_bytes = switch (native_os) {54pub const max_name_bytes = switch (native_os) {
55 .linux, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos, .freebsd, .openbsd, .netbsd, .dragonfly, .illumos, .serenity => std.posix.NAME_MAX,55 .linux, .driverkit, .ios, .maccatalyst, .macos, .tvos, .visionos, .watchos, .freebsd, .openbsd, .netbsd, .dragonfly, .illumos, .serenity, .psp => std.posix.NAME_MAX,
56 // Haiku's NAME_MAX includes the null terminator, so subtract one.56 // Haiku's NAME_MAX includes the null terminator, so subtract one.
57 .haiku => std.posix.NAME_MAX - 1,57 .haiku => std.posix.NAME_MAX - 1,
58 // Each WTF-16LE character may be expanded to 3 WTF-8 bytes.58 // Each WTF-16LE character may be expanded to 3 WTF-8 bytes.
lib/std/Target.zig+20-2
...@@ -53,6 +53,7 @@ pub const Os = struct {...@@ -53,6 +53,7 @@ pub const Os = struct {
53 ps3,53 ps3,
54 ps4,54 ps4,
55 ps5,55 ps5,
56 psp,
56 vita,57 vita,
5758
58 emscripten,59 emscripten,
...@@ -194,6 +195,7 @@ pub const Os = struct {...@@ -194,6 +195,7 @@ pub const Os = struct {
194195
195 .@"3ds",196 .@"3ds",
196197
198 .psp,
197 .vita,199 .vita,
198200
199 .wasi,201 .wasi,
...@@ -612,6 +614,15 @@ pub const Os = struct {...@@ -612,6 +614,15 @@ pub const Os = struct {
612 },614 },
613 },615 },
614616
617 .psp => .{
618 .semver = .{
619 // https://www.psdevwiki.com/psp/Official_Firmware_(OFW)#1.XX_Kernel
620 // It appears that the kernel started with semver for 1.XX before later changing to MAJ.MINPATCH in later releases (e.g. 3.60, 6.61)
621 .min = .{ .major = 1, .minor = 0, .patch = 3 },
622 .max = .{ .major = 6, .minor = 61, .patch = 0 },
623 },
624 },
625
615 .vita => .{626 .vita => .{
616 .semver = .{627 .semver = .{
617 // 1.3 is the first public release628 // 1.3 is the first public release
...@@ -919,6 +930,7 @@ pub const Abi = enum {...@@ -919,6 +930,7 @@ pub const Abi = enum {
919 .tvos,930 .tvos,
920 .visionos,931 .visionos,
921 .watchos,932 .watchos,
933 .psp,
922 .ps3,934 .ps3,
923 .ps4,935 .ps4,
924 .ps5,936 .ps5,
...@@ -2023,7 +2035,10 @@ pub const Cpu = struct {...@@ -2023,7 +2035,10 @@ pub const Cpu = struct {
2023 .lanai => &lanai.cpu.v11, // clang does not have a generic lanai model.2035 .lanai => &lanai.cpu.v11, // clang does not have a generic lanai model.
2024 .loongarch64 => &loongarch.cpu.la64v1_0,2036 .loongarch64 => &loongarch.cpu.la64v1_0,
2025 .m68k => &m68k.cpu.M68000,2037 .m68k => &m68k.cpu.M68000,
2026 .mips, .mipsel => &mips.cpu.mips32r2,2038 .mips, .mipsel => switch (os.tag) {
2039 .psp => &mips.cpu.allegrex,
2040 else => &mips.cpu.mips32r2,
2041 },
2027 .mips64, .mips64el => &mips.cpu.mips64r2,2042 .mips64, .mips64el => &mips.cpu.mips64r2,
2028 .msp430 => &msp430.cpu.msp430,2043 .msp430 => &msp430.cpu.msp430,
2029 .nvptx, .nvptx64 => &nvptx.cpu.sm_52,2044 .nvptx, .nvptx64 => &nvptx.cpu.sm_52,
...@@ -2204,6 +2219,7 @@ pub fn requiresLibC(target: *const Target) bool {...@@ -2204,6 +2219,7 @@ pub fn requiresLibC(target: *const Target) bool {
2204 .amdhsa,2219 .amdhsa,
2205 .ps4,2220 .ps4,
2206 .ps5,2221 .ps5,
2222 .psp,
2207 .vita,2223 .vita,
2208 .mesa3d,2224 .mesa3d,
2209 .contiki,2225 .contiki,
...@@ -2379,6 +2395,7 @@ pub const DynamicLinker = struct {...@@ -2379,6 +2395,7 @@ pub const DynamicLinker = struct {
2379 .ps3,2395 .ps3,
2380 .ps4,2396 .ps4,
2381 .ps5,2397 .ps5,
2398 .psp,
2382 .vita,2399 .vita,
2383 => .none,2400 => .none,
2384 };2401 };
...@@ -2783,6 +2800,7 @@ pub const DynamicLinker = struct {...@@ -2783,6 +2800,7 @@ pub const DynamicLinker = struct {
27832800
2784 .@"3ds",2801 .@"3ds",
27852802
2803 .psp,
2786 .vita,2804 .vita,
27872805
2788 .emscripten,2806 .emscripten,
...@@ -3338,7 +3356,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {...@@ -3338,7 +3356,7 @@ pub fn cTypeBitSize(target: *const Target, c_type: CType) u16 {
3338 .longlong, .ulonglong, .double => return 64,3356 .longlong, .ulonglong, .double => return 64,
3339 .longdouble => return 80,3357 .longdouble => return 80,
3340 },3358 },
3341 .vita => switch (c_type) {3359 .psp, .vita => switch (c_type) {
3342 .char => return 8,3360 .char => return 8,
3343 .short, .ushort => return 16,3361 .short, .ushort => return 16,
3344 .int, .uint, .float => return 32,3362 .int, .uint, .float => return 32,
lib/std/Target/mips.zig+15
...@@ -49,6 +49,7 @@ pub const Feature = enum {...@@ -49,6 +49,7 @@ pub const Feature = enum {
49 noabicalls,49 noabicalls,
50 nomadd4,50 nomadd4,
51 nooddspreg,51 nooddspreg,
52 notraps,
52 p5600,53 p5600,
53 ptr64,54 ptr64,
54 single_float,55 single_float,
...@@ -353,6 +354,11 @@ pub const all_features = blk: {...@@ -353,6 +354,11 @@ pub const all_features = blk: {
353 .description = "Disable odd numbered single-precision registers",354 .description = "Disable odd numbered single-precision registers",
354 .dependencies = featureSet(&[_]Feature{}),355 .dependencies = featureSet(&[_]Feature{}),
355 };356 };
357 result[@intFromEnum(Feature.notraps)] = .{
358 .llvm_name = null,
359 .description = "Disable trap instructions",
360 .dependencies = featureSet(&[_]Feature{}),
361 };
356 result[@intFromEnum(Feature.p5600)] = .{362 result[@intFromEnum(Feature.p5600)] = .{
357 .llvm_name = "p5600",363 .llvm_name = "p5600",
358 .description = "The P5600 Processor",364 .description = "The P5600 Processor",
...@@ -419,6 +425,15 @@ pub const all_features = blk: {...@@ -419,6 +425,15 @@ pub const all_features = blk: {
419};425};
420426
421pub const cpu = struct {427pub const cpu = struct {
428 pub const allegrex: CpuModel = .{
429 .name = "allegrex",
430 .llvm_name = null,
431 .features = featureSet(&[_]Feature{
432 .mips2,
433 .notraps,
434 .single_float,
435 }),
436 };
422 pub const generic: CpuModel = .{437 pub const generic: CpuModel = .{
423 .name = "generic",438 .name = "generic",
424 .llvm_name = "generic",439 .llvm_name = "generic",
lib/std/heap.zig+10
...@@ -805,6 +805,11 @@ const page_size_min_default: ?usize = switch (builtin.os.tag) {...@@ -805,6 +805,11 @@ const page_size_min_default: ?usize = switch (builtin.os.tag) {
805 .x86, .x86_64 => 16 << 10,805 .x86, .x86_64 => 16 << 10,
806 else => null,806 else => null,
807 },807 },
808 .psp => switch (builtin.cpu.arch) {
809 // minimum block allocation by testing sceKernel
810 .mips, .mipsel => 1 << 8, // 256
811 else => null,
812 },
808 // system/lib/libc/musl/arch/emscripten/bits/limits.h813 // system/lib/libc/musl/arch/emscripten/bits/limits.h
809 .emscripten => 64 << 10,814 .emscripten => 64 << 10,
810 .linux => switch (builtin.cpu.arch) {815 .linux => switch (builtin.cpu.arch) {
...@@ -963,6 +968,11 @@ const page_size_max_default: ?usize = switch (builtin.os.tag) {...@@ -963,6 +968,11 @@ const page_size_max_default: ?usize = switch (builtin.os.tag) {
963 .x86, .x86_64 => 16 << 10,968 .x86, .x86_64 => 16 << 10,
964 else => null,969 else => null,
965 },970 },
971 .psp => switch (builtin.cpu.arch) {
972 // minimum block allocation by testing sceKernel
973 .mips, .mipsel => 1 << 8, // 256
974 else => null,
975 },
966 // system/lib/libc/musl/arch/emscripten/bits/limits.h976 // system/lib/libc/musl/arch/emscripten/bits/limits.h
967 .emscripten => 64 << 10,977 .emscripten => 64 << 10,
968 .linux => switch (builtin.cpu.arch) {978 .linux => switch (builtin.cpu.arch) {
lib/std/posix.zig+16
...@@ -38,6 +38,22 @@ pub const system = if (use_libc)...@@ -38,6 +38,22 @@ pub const system = if (use_libc)
38else switch (native_os) {38else switch (native_os) {
39 .linux => linux,39 .linux => linux,
40 .plan9 => std.os.plan9,40 .plan9 => std.os.plan9,
41 .psp => struct {
42 pub const fd_t = i32;
43 pub const pid_t = void;
44 pub const pollfd = void;
45 pub const uid_t = void;
46 pub const gid_t = void;
47 pub const mode_t = u32;
48 pub const nlink_t = u32;
49 pub const blksize_t = u32;
50 pub const ino_t = u64;
51 pub const IFNAMESIZE = {};
52 pub const SIG = void;
53
54 // https://github.com/pspdev/newlib/blob/9e0a073634ad73e8e088f2e071c55a9fe5d39709/newlib/libc/sys/psp/sys/dirent.h#L19
55 pub const NAME_MAX = 255;
56 },
41 else => struct {57 else => struct {
42 pub const pid_t = void;58 pub const pid_t = void;
43 pub const pollfd = void;59 pub const pollfd = void;
lib/std/start.zig+1-1
...@@ -65,7 +65,7 @@ comptime {...@@ -65,7 +65,7 @@ comptime {
65 // case it's not required to provide an entrypoint such as main.65 // case it's not required to provide an entrypoint such as main.
66 if (!@hasDecl(root, start_sym_name) and @hasDecl(root, "main")) @export(&wasm_freestanding_start, .{ .name = start_sym_name });66 if (!@hasDecl(root, start_sym_name) and @hasDecl(root, "main")) @export(&wasm_freestanding_start, .{ .name = start_sym_name });
67 } else switch (native_os) {67 } else switch (native_os) {
68 .other, .freestanding, .@"3ds", .vita => {},68 .other, .freestanding, .@"3ds", .psp, .vita => {},
69 else => if (!@hasDecl(root, start_sym_name)) @export(&_start, .{ .name = start_sym_name }),69 else => if (!@hasDecl(root, start_sym_name)) @export(&_start, .{ .name = start_sym_name }),
70 }70 }
71 }71 }
src/Compilation.zig+1
...@@ -6424,6 +6424,7 @@ fn addCommonCCArgs(...@@ -6424,6 +6424,7 @@ fn addCommonCCArgs(
6424 .illumos => try argv.append("__illumos__"),6424 .illumos => try argv.append("__illumos__"),
6425 // Homebrew targets without LLVM support; use communities's preferred macros.6425 // Homebrew targets without LLVM support; use communities's preferred macros.
6426 .@"3ds" => try argv.append("-D__3DS__"),6426 .@"3ds" => try argv.append("-D__3DS__"),
6427 .psp => try argv.append("-D__PSP__"),
6427 .vita => try argv.append("-D__vita__"),6428 .vita => try argv.append("-D__vita__"),
6428 else => {},6429 else => {},
6429 }6430 }
src/codegen/llvm.zig+20-1
...@@ -247,6 +247,7 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8...@@ -247,6 +247,7 @@ pub fn targetTriple(allocator: Allocator, target: *const std.Target) ![]const u8
247 .opengl,247 .opengl,
248 .other,248 .other,
249 .plan9,249 .plan9,
250 .psp,
250 .vita,251 .vita,
251 => "unknown",252 => "unknown",
252 };253 };
...@@ -9536,7 +9537,25 @@ pub const FuncGen = struct {...@@ -9536,7 +9537,25 @@ pub const FuncGen = struct {
95369537
9537 fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !void {9538 fn airTrap(self: *FuncGen, inst: Air.Inst.Index) !void {
9538 _ = inst;9539 _ = inst;
9539 _ = try self.wip.callIntrinsic(.normal, .none, .trap, &.{}, &.{}, "");9540 const target = self.ng.object.target;
9541 if ((target.cpu.arch == .mips or target.cpu.arch == .mipsel) and
9542 target.cpu.has(.mips, .notraps))
9543 {
9544 // Emit a MIPS `break` instruction followed by an infinite loop (to fulfill the noreturn)
9545 // since this CPU does not support trap instructions.
9546 const o = self.ng.object;
9547 _ = try self.wip.callAsm(
9548 .none,
9549 try o.builder.fnType(.void, &.{}, .normal),
9550 .{ .sideeffect = true },
9551 try o.builder.string("break\n0:\nj 0b\nnop"),
9552 try o.builder.string("~{memory}"),
9553 &.{},
9554 "",
9555 );
9556 } else {
9557 _ = try self.wip.callIntrinsic(.normal, .none, .trap, &.{}, &.{}, "");
9558 }
9540 _ = try self.wip.@"unreachable"();9559 _ = try self.wip.@"unreachable"();
9541 }9560 }
95429561
tools/update_cpu_features.zig+14
...@@ -1299,6 +1299,20 @@ const targets = [_]ArchTarget{...@@ -1299,6 +1299,20 @@ const targets = [_]ArchTarget{
1299 .name = "Mips",1299 .name = "Mips",
1300 .td_name = "Mips",1300 .td_name = "Mips",
1301 },1301 },
1302 .extra_features = &.{
1303 .{
1304 .zig_name = "notraps",
1305 .desc = "Disable trap instructions",
1306 .deps = &.{},
1307 },
1308 },
1309 .extra_cpus = &.{
1310 .{
1311 .llvm_name = null,
1312 .zig_name = "allegrex",
1313 .features = &.{ "mips2", "single_float", "notraps" },
1314 },
1315 },
1302 },1316 },
1303 .{1317 .{
1304 .zig_name = "nvptx",1318 .zig_name = "nvptx",