| ... | ... | @@ -1,6 +1,16 @@ |
| 1 | 1 | const builtin = @import("builtin"); |
| 2 | 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 | 14 | pub fn detectNativeCpuAndFeatures( |
| 5 | 15 | arch: std.Target.Cpu.Arch, |
| 6 | 16 | os: std.Target.Os, |
| ... | ... | @@ -9,9 +19,6 @@ pub fn detectNativeCpuAndFeatures( |
| 9 | 19 | _ = os; |
| 10 | 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 | 22 | var cpu: std.Target.Cpu = .{ |
| 16 | 23 | .arch = arch, |
| 17 | 24 | .model = switch (cpucfg(0) & 0xf000) { |
| ... | ... | @@ -23,6 +30,31 @@ pub fn detectNativeCpuAndFeatures( |
| 23 | 30 | }; |
| 24 | 31 | |
| 25 | 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 | 58 | cpu.features.populateDependencies(cpu.arch.allFeaturesList()); |
| 27 | 59 | |
| 28 | 60 | return cpu; |