| ... | @@ -1,6 +1,16 @@ | ... | @@ -1,6 +1,16 @@ |
| 1 | const builtin = @import("builtin"); | 1 | const builtin = @import("builtin"); |
| 2 | const std = @import("std"); | 2 | const std = @import("std"); |
| 3 | | 3 | |
| | 4 | inline fn bit(input: u32, offset: u5) bool { |
| | 5 | return (input >> offset) & 1 != 0; |
| | 6 | } |
| | 7 | |
| | 8 | fn setFeature(cpu: *std.Target.Cpu, feature: std.Target.loongarch.Feature, enabled: bool) void { |
| | 9 | const idx = @as(std.Target.Cpu.Feature.Set.Index, @intFromEnum(feature)); |
| | 10 | |
| | 11 | if (enabled) cpu.features.addFeature(idx) else cpu.features.removeFeature(idx); |
| | 12 | } |
| | 13 | |
| 4 | pub fn detectNativeCpuAndFeatures( | 14 | pub fn detectNativeCpuAndFeatures( |
| 5 | arch: std.Target.Cpu.Arch, | 15 | arch: std.Target.Cpu.Arch, |
| 6 | os: std.Target.Os, | 16 | os: std.Target.Os, |
| ... | @@ -9,9 +19,6 @@ pub fn detectNativeCpuAndFeatures( | ... | @@ -9,9 +19,6 @@ pub fn detectNativeCpuAndFeatures( |
| 9 | _ = os; | 19 | _ = os; |
| 10 | _ = query; | 20 | _ = query; |
| 11 | | 21 | |
| 12 | // Clearly this code could do better in the future by actually querying specific CPU features | | |
| 13 | // with the cpucfg instruction like on x86. But with the small number of well-known LoongArch | | |
| 14 | // models that exist at the moment, simply checking the PRID is plenty. | | |
| 15 | var cpu: std.Target.Cpu = .{ | 22 | var cpu: std.Target.Cpu = .{ |
| 16 | .arch = arch, | 23 | .arch = arch, |
| 17 | .model = switch (cpucfg(0) & 0xf000) { | 24 | .model = switch (cpucfg(0) & 0xf000) { |
| ... | @@ -23,6 +30,31 @@ pub fn detectNativeCpuAndFeatures( | ... | @@ -23,6 +30,31 @@ pub fn detectNativeCpuAndFeatures( |
| 23 | }; | 30 | }; |
| 24 | | 31 | |
| 25 | cpu.features.addFeatureSet(cpu.model.features); | 32 | cpu.features.addFeatureSet(cpu.model.features); |
| | 33 | |
| | 34 | const cfg1 = cpucfg(1); |
| | 35 | const cfg2 = cpucfg(2); |
| | 36 | const cfg3 = cpucfg(3); |
| | 37 | |
| | 38 | setFeature(&cpu, .ual, bit(cfg1, 20)); |
| | 39 | |
| | 40 | const has_fpu = bit(cfg2, 0); |
| | 41 | setFeature(&cpu, .f, has_fpu and bit(cfg2, 1)); |
| | 42 | setFeature(&cpu, .d, has_fpu and bit(cfg2, 2)); |
| | 43 | |
| | 44 | setFeature(&cpu, .lsx, bit(cfg2, 6)); |
| | 45 | setFeature(&cpu, .lasx, bit(cfg2, 7)); |
| | 46 | setFeature(&cpu, .lvz, bit(cfg2, 10)); |
| | 47 | |
| | 48 | setFeature(&cpu, .lbt, bit(cfg2, 18) and bit(cfg2, 19) and bit(cfg2, 20)); |
| | 49 | |
| | 50 | setFeature(&cpu, .frecipe, bit(cfg2, 25)); |
| | 51 | setFeature(&cpu, .div32, bit(cfg2, 26)); |
| | 52 | setFeature(&cpu, .lam_bh, bit(cfg2, 27)); |
| | 53 | setFeature(&cpu, .lamcas, bit(cfg2, 28)); |
| | 54 | setFeature(&cpu, .scq, bit(cfg2, 30)); |
| | 55 | |
| | 56 | setFeature(&cpu, .ld_seq_sa, bit(cfg3, 23)); |
| | 57 | |
| 26 | cpu.features.populateDependencies(cpu.arch.allFeaturesList()); | 58 | cpu.features.populateDependencies(cpu.arch.allFeaturesList()); |
| 27 | | 59 | |
| 28 | return cpu; | 60 | return cpu; |