use super::err::CoreNameError;
use super::Vendor;
pub const fn core_name(
vendor: Vendor,
family: u8,
model: u8,
) -> Result<&'static str, CoreNameError> {
debug_assert!(family <= 0x1E);
match vendor {
Vendor::Intel => intel_core_name(family, model),
Vendor::Amd => amd_core_name(family, model),
_ => Err(CoreNameError::NoKnownNamesForVendor(vendor)),
}
}
const fn amd_core_name(family: u8, model: u8) -> Result<&'static str, CoreNameError> {
match family {
0x05 => match model {
0x00..=0x05 => Ok("K5"),
_ => Ok("K6"),
},
0x06 => Ok("K7"),
0x0F => match model {
0x00..=0x1F => Ok("Hammer rev. B-D"),
_ => Ok("Hammer rev. E-G"),
},
0x10 => Ok("Greyhound"),
0x11 => Ok("Griffin"),
0x12 => Ok("Husky"),
0x14 => Ok("Bobcat"),
0x15 => match model {
0x00..=0x01 => Ok("Bulldozer"),
0x02..=0x1F => Ok("Piledriver"),
0x30..=0x3F => Ok("Steamroller"),
0x60..=0x7F => Ok("Excavator"),
_ => Err(CoreNameError::NoKnownNamesForModel(model)),
},
0x16 => Ok("Jaguar"),
0x17 => match model {
0x00..=0x2F | 0x50..=0x5F => Ok("Zen 1"),
0x30..=0x4F | 0x60..=0xAF => Ok("Zen 2"),
_ => Err(CoreNameError::NoKnownNamesForModel(model)),
},
0x18 => Ok("Zen 1"),
0x19 => match model {
0x00..=0x0F | 0x20..=0x5F => Ok("Zen 3"),
0x10..=0x1F | 0x60..=0xAF => Ok("Zen 4"),
_ => Err(CoreNameError::NoKnownNamesForModel(model)),
},
0x1A => match model {
0x00..=0x2F | 0x40..=0x4F | 0x60..=0x7F => Ok("Zen 5"),
0x50..=0x5F | 0x90..=0xAF | 0xC0..=0xCF => Ok("Zen 6"),
_ => Err(CoreNameError::NoKnownNamesForModel(model)),
},
_ => Err(CoreNameError::NoKnownNamesForFamily(family)),
}
}
const fn intel_core_name(family: u8, model: u8) -> Result<&'static str, CoreNameError> {
match family {
0x05 => Ok("P5"),
0x06 => match model {
0x00..=0x08 | 0x0A | 0x0B => Ok("P6"),
0x09 | 0x0D | 0x0E => Ok("Mobile"),
0x0F..=0x16 => Ok("Merom"),
0x17 | 0x1D => Ok("Penryn"),
0x1A | 0x1E | 0x1F | 0x2E => Ok("Nehalem"),
0x25 | 0x2C | 0x2F => Ok("Westmere"),
0x2A | 0x2D => Ok("Sandy Bridge"),
0x3A | 0x3E => Ok("Ivy Bridge"),
0x3C | 0x3F | 0x45 | 0x46 => Ok("Haswell"),
0x3D | 0x47 | 0x4F | 0x56 => Ok("Broadwell"),
0x4E | 0x55 | 0x5E | 0x8E | 0x9E | 0xA5 | 0xA6 => Ok("Skylake"),
0x66 => Ok("Palm Cove"),
0x6A | 0x6C | 0x7D | 0x7E | 0x9D => Ok("Sunny Cove"),
0x8C | 0x8D => Ok("Willow Cove"),
0xA7 => Ok("Cypress Cove"),
0x8F => Ok("Golden Cove"),
0xCF | 0xD7 => Ok("Raptor Cove"),
0xAD | 0xAE => Ok("Redwood Cove"),
0x8A => Ok("Sunny Cove + Tremont"),
0x97 | 0x9A => Ok("Golden Cove + Gracemont"),
0xB7 | 0xBA | 0xBF => Ok("Raptor Cove + Gracemont"),
0xAA | 0xAC => Ok("Redwood Cove + Crestmont"),
0xB5 | 0xBD | 0xC5 | 0xC6 => Ok("Lion Cove + Skymont"),
0xCC => Ok("Cougar Cove + Darkmont"),
0x1C | 0x26 => Ok("Bonnell"),
0x27 | 0x35 | 0x36 => Ok("Saltwell"),
0x37 | 0x4A | 0x4D | 0x5A | 0x5D => Ok("Silvermont"),
0x4C | 0x57 | 0x75 | 0x85 => Ok("Airmont"),
0x5C | 0x5F => Ok("Goldmont"),
0x7A => Ok("Goldmont Plus"),
0x86 | 0x96 | 0x9C => Ok("Tremont"),
0xBE => Ok("Gracemont"),
0xAF | 0xB6 => Ok("Crestmont"),
0xDD => Ok("Darkmont"),
_ => Err(CoreNameError::NoKnownNamesForModel(model)),
},
0x0F => match model {
0x00 | 0x01 => Ok("Willamette"),
0x02 => Ok("Northwood"),
0x03 | 0x04 => Ok("Prescott"),
0x06 => Ok("Cedar Mill"),
_ => Err(CoreNameError::NoKnownNamesForModel(model)),
},
0x12 => match model {
0x01 | 0x03 => Ok("Coyote Cove + Arctic Wolf"),
_ => Err(CoreNameError::NoKnownNamesForModel(model)),
},
0x13 => match model {
0x01 => Ok("Panther Cove"),
_ => Err(CoreNameError::NoKnownNamesForModel(model)),
},
_ => Err(CoreNameError::NoKnownNamesForFamily(family)),
}
}
#[cfg(test)]
mod tests {
use super::*;
use strum::IntoEnumIterator;
#[test]
#[should_panic]
fn invalid_family() {
let _ = core_name(Vendor::Intel, 0xFF, 0x4E);
}
#[test]
fn no_matches_for_vendor() {
assert!(core_name(Vendor::Sis, 0x00, 0x0F).is_err())
}
#[test]
fn valid_inputs_never_panic() {
Vendor::iter().for_each(|vendor| {
for family in 0..=0x1E {
for model in 0..=u8::MAX {
let _ = core_name(vendor, family, model);
}
}
});
}
}