| ... | ... | @@ -347,6 +347,114 @@ const m68k = struct { |
| 347 | 347 | } |
| 348 | 348 | }; |
| 349 | 349 | |
| 350 | const mips = struct { |
| 351 | const cpuinfo = struct { |
| 352 | const Impl = struct { |
| 353 | model: ?*const Target.Cpu.Model = null, |
| 354 | |
| 355 | const cpu_names = .{ |
| 356 | .{ "Cavium Octeon III", &Target.mips.cpu.@"octeon+" }, |
| 357 | .{ "Cavium Octeon II", &Target.mips.cpu.@"octeon+" }, |
| 358 | .{ "Cavium Octeon+", &Target.mips.cpu.@"octeon+" }, |
| 359 | .{ "Cavium Octeon", &Target.mips.cpu.octeon }, |
| 360 | .{ "MIPS I6400", &Target.mips.cpu.i6400 }, |
| 361 | .{ "MIPS I6500", &Target.mips.cpu.i6500 }, |
| 362 | .{ "MIPS P5600", &Target.mips.cpu.p5600 }, |
| 363 | .{ "R3000A", &Target.mips.cpu.r3000a }, |
| 364 | }; |
| 365 | |
| 366 | const isa_names = .{ |
| 367 | .{ "mips64r6", &Target.mips.cpu.mips64r6 }, |
| 368 | .{ "mips64r5", &Target.mips.cpu.mips64r5 }, |
| 369 | .{ "mips64r2", &Target.mips.cpu.mips64r2 }, |
| 370 | .{ "mips64r1", &Target.mips.cpu.mips64 }, |
| 371 | .{ "mips32r6", &Target.mips.cpu.mips32r6 }, |
| 372 | .{ "mips32r5", &Target.mips.cpu.mips32r5 }, |
| 373 | .{ "mips32r2", &Target.mips.cpu.mips32r2 }, |
| 374 | .{ "mips32r1", &Target.mips.cpu.mips32 }, |
| 375 | .{ "mips5", &Target.mips.cpu.mips5 }, |
| 376 | .{ "mips4", &Target.mips.cpu.mips4 }, |
| 377 | .{ "mips3", &Target.mips.cpu.mips3 }, |
| 378 | .{ "mips2", &Target.mips.cpu.mips2 }, |
| 379 | .{ "mips1", &Target.mips.cpu.mips1 }, |
| 380 | }; |
| 381 | |
| 382 | fn lineHook(self: *Impl, key: []const u8, value: []const u8) !bool { |
| 383 | // The `cpu model` line always comes before `isa`, which is perfect for us since we |
| 384 | // want the explicit model to take precedence over the generic ISA identifier. |
| 385 | if (mem.eql(u8, key, "cpu model")) { |
| 386 | inline for (cpu_names) |pair| { |
| 387 | if (mem.find(u8, value, pair[0]) != null) { |
| 388 | self.model = pair[1]; |
| 389 | return false; |
| 390 | } |
| 391 | } |
| 392 | } else if (mem.eql(u8, key, "isa")) { |
| 393 | inline for (isa_names) |pair| { |
| 394 | if (mem.find(u8, value, pair[0]) != null) { |
| 395 | self.model = pair[1]; |
| 396 | break; |
| 397 | } |
| 398 | } |
| 399 | |
| 400 | // If we haven't found anything useful by here, we we may as well stop. |
| 401 | return false; |
| 402 | } |
| 403 | |
| 404 | return true; |
| 405 | } |
| 406 | |
| 407 | fn finalize(self: *const Impl, arch: Target.Cpu.Arch) ?Target.Cpu { |
| 408 | const model = self.model orelse return null; |
| 409 | return .{ |
| 410 | .arch = arch, |
| 411 | .model = model, |
| 412 | .features = model.features, |
| 413 | }; |
| 414 | } |
| 415 | }; |
| 416 | |
| 417 | const Parser = CpuinfoParser(Impl); |
| 418 | }; |
| 419 | |
| 420 | test cpuinfo { |
| 421 | try testParser(cpuinfo.Parser, .mips64, &Target.mips.cpu.@"octeon+", |
| 422 | \\system type : UBNT_E300 |
| 423 | \\machine : Unknown |
| 424 | \\processor : 0 |
| 425 | \\cpu model : Cavium Octeon III V0.2 FPU V0.0 |
| 426 | \\BogoMIPS : 2000.00 |
| 427 | \\wait instruction : yes |
| 428 | \\microsecond timers : yes |
| 429 | \\tlb_entries : 256 |
| 430 | \\extra interrupt vector : yes |
| 431 | \\hardware watchpoint : yes, count: 2, address/irw mask: [0x0ffc, 0x0ffb] |
| 432 | \\isa : mips1 mips2 mips3 mips4 mips5 mips64r2 |
| 433 | \\ASEs implemented : vz |
| 434 | \\shadow register sets : 1 |
| 435 | \\kscratch registers : 4 |
| 436 | \\package : 0 |
| 437 | \\core : 0 |
| 438 | \\VCED exceptions : not available |
| 439 | \\VCEI exceptions : not available |
| 440 | ); |
| 441 | } |
| 442 | |
| 443 | pub fn detectNativeCpu(io: Io, arch: Target.Cpu.Arch) ?Target.Cpu { |
| 444 | var file = Io.Dir.openFileAbsolute(io, "/proc/cpuinfo", .{}) catch return null; |
| 445 | defer file.close(io); |
| 446 | |
| 447 | var buffer: [4096]u8 = undefined; |
| 448 | var file_reader = file.reader(io, &buffer); |
| 449 | |
| 450 | var cpu = (cpuinfo.Parser.parse(arch, &file_reader.interface) catch null) orelse return null; |
| 451 | |
| 452 | cpu.features.populateDependencies(cpu.arch.allFeaturesList()); |
| 453 | |
| 454 | return cpu; |
| 455 | } |
| 456 | }; |
| 457 | |
| 350 | 458 | const powerpc = struct { |
| 351 | 459 | const cpuinfo = struct { |
| 352 | 460 | const Impl = struct { |
| ... | ... | @@ -874,6 +982,7 @@ pub fn detectNativeCpuAndFeatures(io: Io) ?Target.Cpu { |
| 874 | 982 | .arm, .armeb, .thumb, .thumbeb => arm.detectNativeCpu(io, current_arch), |
| 875 | 983 | .csky => csky.detectNativeCpu(io, current_arch), |
| 876 | 984 | .m68k => m68k.detectNativeCpu(io, current_arch), |
| 985 | .mips, .mipsel, .mips64, .mips64el => mips.detectNativeCpu(io, current_arch), |
| 877 | 986 | .powerpc, .powerpcle, .powerpc64, .powerpc64le => powerpc.detectNativeCpu(io, current_arch), |
| 878 | 987 | .riscv64, .riscv32 => riscv.detectNativeCpuAndFeatures(io, current_arch), |
| 879 | 988 | .s390x => s390x.detectNativeCpu(io, current_arch), |