|
1 | 1 | using JSON
|
| 2 | +using Base.BinaryPlatforms: arch_march_isa_mapping, set_compare_strategy! |
| 3 | +using Base.BinaryPlatforms.CPUID |
2 | 4 |
|
3 | 5 | ## We start with definitions of instruction mnemonics, broken down by category:
|
4 | 6 | const instruction_categories = JSON.parsefile(joinpath(@__DIR__, "instructions.json");
|
@@ -168,3 +170,46 @@ function analyze_instruction_set(oh::ObjectHandle, platform::AbstractPlatform; v
|
168 | 170 | # Otherwise, return `min_march` and let 'em know!
|
169 | 171 | return min_march
|
170 | 172 | end
|
| 173 | + |
| 174 | +function march_comparison_strategy(a::String, b::String, a_requested::Bool, b_requested::Bool) |
| 175 | + # If both b and a requested, then we fall back to equality: |
| 176 | + if a_requested && b_requested |
| 177 | + return a == b |
| 178 | + end |
| 179 | + |
| 180 | + function get_arch_isa(isa_name::String) |
| 181 | + for (arch, isas) in arch_march_isa_mapping |
| 182 | + for (name, isa) in isas |
| 183 | + name == isa_name && return arch, isa |
| 184 | + end |
| 185 | + end |
| 186 | + return nothing, nothing |
| 187 | + end |
| 188 | + |
| 189 | + a_arch, a_isa = get_arch_isa(a) |
| 190 | + b_arch, b_isa = get_arch_isa(b) |
| 191 | + if any(isnothing, (a_arch, b_arch)) || a_arch != b_arch |
| 192 | + # Architectures are definitely not compatible, exit early |
| 193 | + return false |
| 194 | + end |
| 195 | + |
| 196 | + if a_requested |
| 197 | + # ISA `b` is compatible with ISA `a` only if it's a subset of `a` |
| 198 | + return b_isa ≤ a_isa |
| 199 | + else |
| 200 | + # ISA `a` is compatible with ISA `b` only if it's a subset of `b` |
| 201 | + return a_isa ≤ b_isa |
| 202 | + end |
| 203 | + return |
| 204 | +end |
| 205 | + |
| 206 | +function augment_microarchitecture!(platform::Platform) |
| 207 | + haskey(platform, "march") && return platform |
| 208 | + |
| 209 | + host_arch = arch(HostPlatform()) |
| 210 | + host_isas = arch_march_isa_mapping[host_arch] |
| 211 | + idx = findlast(((name, isa),) -> isa <= CPUID.cpu_isa(), host_isas) |
| 212 | + platform["march"] = first(host_isas[idx]) |
| 213 | + set_compare_strategy!(platform, "march", march_comparison_strategy) |
| 214 | + return platform |
| 215 | +end |
0 commit comments