use crate::mc_streamer::x86_opcodes;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ProcResource {
Port0,
Port1,
Port2,
Port3,
Port4,
Port5,
Port6,
Port7,
Port8,
Port9,
Port10,
Port11,
Port12,
Port13,
Port14,
Port15,
ALU0,
ALU1,
ALU2,
ALU3,
ALU4,
ALU5,
AGU0,
AGU1,
AGU2,
AGU3,
FPU0,
FPU1,
FPU2,
FPU3,
UnifiedScheduler,
LoadUnit,
StoreUnit,
BranchUnit,
IntegerDivider,
IntegerMultiplier,
VectorALU,
VectorShuffle,
VectorMultiplier,
}
#[derive(Debug, Clone)]
pub struct WriteRes {
pub resource: ProcResource,
pub cycles: u32,
}
#[derive(Debug, Clone)]
pub struct ReadAdvance {
pub write_resource: ProcResource,
pub cycles: u32,
}
#[derive(Debug, Clone)]
pub struct WriteLatency {
pub resource: ProcResource,
pub cycles: u32,
}
#[derive(Debug, Clone)]
pub struct InstrItinerary {
pub opcode: u32,
pub latency: u32,
pub uops: u32,
pub write_resources: Vec<WriteRes>,
pub read_advances: Vec<ReadAdvance>,
pub write_latencies: Vec<WriteLatency>,
}
#[derive(Debug, Clone)]
pub struct SchedMachineModel {
pub name: &'static str,
pub issue_width: u32,
pub micro_op_buffer_size: u32,
pub load_latency: u32,
pub store_latency: u32,
pub high_latency: u32,
pub misfetch_penalty: u32,
pub rob_size: u32,
pub phys_reg_count: u32,
pub out_of_order: bool,
pub load_buffers: u32,
pub store_buffers: u32,
pub l1i_cache_size: u32,
pub l1d_cache_size: u32,
pub l2_cache_size: u32,
pub l3_cache_size: u32,
}
#[derive(Debug, Clone)]
pub struct SchedModel {
pub machine: SchedMachineModel,
pub resources: Vec<ProcResource>,
pub itineraries: Vec<InstrItinerary>,
}
pub fn skylake_client_model() -> SchedModel {
let machine = SchedMachineModel {
name: "Intel Skylake Client",
issue_width: 8,
micro_op_buffer_size: 64,
load_latency: 4,
store_latency: 1,
high_latency: 20,
misfetch_penalty: 16,
rob_size: 224,
phys_reg_count: 168,
out_of_order: true,
load_buffers: 72,
store_buffers: 56,
l1i_cache_size: 32768,
l1d_cache_size: 32768,
l2_cache_size: 262144,
l3_cache_size: 8388608,
};
let resources = vec![
ProcResource::Port0,
ProcResource::Port1,
ProcResource::Port2,
ProcResource::Port3,
ProcResource::Port4,
ProcResource::Port5,
ProcResource::Port6,
ProcResource::Port7,
];
let itineraries = skylake_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn skylake_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::NOP,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 23,
uops: 36,
write_resources: vec![
WriteRes {
resource: ProcResource::Port0,
cycles: 9,
},
WriteRes {
resource: ProcResource::Port1,
cycles: 6,
},
WriteRes {
resource: ProcResource::Port5,
cycles: 9,
},
WriteRes {
resource: ProcResource::Port6,
cycles: 8,
},
],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 23,
}],
},
InstrItinerary {
opcode: x86_opcodes::PUSH,
latency: 1,
uops: 2,
write_resources: vec![
WriteRes {
resource: ProcResource::Port2,
cycles: 1,
},
WriteRes {
resource: ProcResource::Port4,
cycles: 1,
},
],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::POP,
latency: 4,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port2,
cycles: 4,
}],
},
InstrItinerary {
opcode: x86_opcodes::CALL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RET,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::NOT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NEG,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::INC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::DEC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::TEST,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSWAP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XCHG,
latency: 2,
uops: 2,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 2,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 2,
}],
},
InstrItinerary {
opcode: x86_opcodes::BT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTS,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSF,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSR,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::MOVSX,
latency: 1,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOVZX,
latency: 1,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOVSXD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::CMOVE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::CMOVNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADC,
latency: 1,
uops: 2,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 2,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SBB,
latency: 1,
uops: 2,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 2,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::RDTSC,
latency: 20,
uops: 18,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 18,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 20,
}],
},
InstrItinerary {
opcode: x86_opcodes::CPUID,
latency: 100,
uops: 100,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CBW,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CWDE,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CDQE,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::SYSCALL,
latency: 30,
uops: 30,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn ice_lake_model() -> SchedModel {
let machine = SchedMachineModel {
name: "Intel Ice Lake Client",
issue_width: 10,
micro_op_buffer_size: 70,
load_latency: 4,
store_latency: 1,
high_latency: 20,
misfetch_penalty: 18,
rob_size: 352,
phys_reg_count: 224,
out_of_order: true,
load_buffers: 128,
store_buffers: 72,
l1i_cache_size: 32768,
l1d_cache_size: 49152,
l2_cache_size: 524288,
l3_cache_size: 8388608,
};
let resources = vec![
ProcResource::Port0,
ProcResource::Port1,
ProcResource::Port2,
ProcResource::Port3,
ProcResource::Port4,
ProcResource::Port5,
ProcResource::Port6,
ProcResource::Port7,
ProcResource::Port8,
ProcResource::Port9,
];
let itineraries = ice_lake_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn ice_lake_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 17,
uops: 18,
write_resources: vec![
WriteRes {
resource: ProcResource::Port0,
cycles: 5,
},
WriteRes {
resource: ProcResource::Port1,
cycles: 4,
},
WriteRes {
resource: ProcResource::Port5,
cycles: 5,
},
WriteRes {
resource: ProcResource::Port6,
cycles: 4,
},
],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 17,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::PUSH,
latency: 1,
uops: 2,
write_resources: vec![
WriteRes {
resource: ProcResource::Port2,
cycles: 1,
},
WriteRes {
resource: ProcResource::Port4,
cycles: 1,
},
],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::POP,
latency: 4,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port2,
cycles: 4,
}],
},
InstrItinerary {
opcode: x86_opcodes::CALL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RET,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NOT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NEG,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::INC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::DEC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::TEST,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSWAP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XCHG,
latency: 2,
uops: 2,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 2,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 2,
}],
},
InstrItinerary {
opcode: x86_opcodes::BT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTS,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSF,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSR,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::MOVSX,
latency: 1,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOVZX,
latency: 1,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOVSXD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::CMOVE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::CMOVNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADC,
latency: 1,
uops: 2,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 2,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SBB,
latency: 1,
uops: 2,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 2,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::RDTSC,
latency: 20,
uops: 18,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 18,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 20,
}],
},
InstrItinerary {
opcode: x86_opcodes::CPUID,
latency: 100,
uops: 100,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::SYSCALL,
latency: 30,
uops: 30,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn alder_lake_pcore_model() -> SchedModel {
let machine = SchedMachineModel {
name: "Intel Alder Lake P-core (Golden Cove)",
issue_width: 12,
micro_op_buffer_size: 72,
load_latency: 4,
store_latency: 1,
high_latency: 20,
misfetch_penalty: 20,
rob_size: 512,
phys_reg_count: 280,
out_of_order: true,
load_buffers: 192,
store_buffers: 114,
l1i_cache_size: 32768,
l1d_cache_size: 49152,
l2_cache_size: 1310720,
l3_cache_size: 31457280,
};
let resources = vec![
ProcResource::Port0,
ProcResource::Port1,
ProcResource::Port2,
ProcResource::Port3,
ProcResource::Port4,
ProcResource::Port5,
ProcResource::Port6,
ProcResource::Port7,
ProcResource::Port8,
ProcResource::Port9,
ProcResource::Port10,
ProcResource::Port11,
];
let itineraries = alder_lake_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn alder_lake_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 14,
uops: 16,
write_resources: vec![
WriteRes {
resource: ProcResource::Port0,
cycles: 4,
},
WriteRes {
resource: ProcResource::Port1,
cycles: 4,
},
WriteRes {
resource: ProcResource::Port5,
cycles: 4,
},
WriteRes {
resource: ProcResource::Port6,
cycles: 4,
},
],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 14,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::PUSH,
latency: 1,
uops: 2,
write_resources: vec![
WriteRes {
resource: ProcResource::Port2,
cycles: 1,
},
WriteRes {
resource: ProcResource::Port4,
cycles: 1,
},
],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::POP,
latency: 4,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port2,
cycles: 4,
}],
},
InstrItinerary {
opcode: x86_opcodes::CALL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RET,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NOT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NEG,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SYSCALL,
latency: 25,
uops: 25,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn granite_rapids_model() -> SchedModel {
let machine = SchedMachineModel {
name: "Intel Granite Rapids (Redwood Cove)",
issue_width: 8,
micro_op_buffer_size: 96,
load_latency: 4,
store_latency: 1,
high_latency: 20,
misfetch_penalty: 18,
rob_size: 512,
phys_reg_count: 320,
out_of_order: true,
load_buffers: 256,
store_buffers: 128,
l1i_cache_size: 65536,
l1d_cache_size: 49152,
l2_cache_size: 2097152,
l3_cache_size: 1073741824,
};
let resources = vec![
ProcResource::Port0,
ProcResource::Port1,
ProcResource::Port2,
ProcResource::Port3,
ProcResource::Port4,
ProcResource::Port5,
ProcResource::Port6,
ProcResource::Port7,
];
let itineraries = granite_rapids_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn granite_rapids_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 12,
uops: 14,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 14,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 12,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::SYSCALL,
latency: 22,
uops: 22,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn zen3_model() -> SchedModel {
let machine = SchedMachineModel {
name: "AMD Zen 3",
issue_width: 6,
micro_op_buffer_size: 48,
load_latency: 4,
store_latency: 1,
high_latency: 20,
misfetch_penalty: 16,
rob_size: 256,
phys_reg_count: 192,
out_of_order: true,
load_buffers: 116,
store_buffers: 64,
l1i_cache_size: 32768,
l1d_cache_size: 32768,
l2_cache_size: 524288,
l3_cache_size: 33554432,
};
let resources = vec![
ProcResource::ALU0,
ProcResource::ALU1,
ProcResource::ALU2,
ProcResource::ALU3,
ProcResource::AGU0,
ProcResource::AGU1,
ProcResource::AGU2,
ProcResource::FPU0,
ProcResource::FPU1,
];
let itineraries = zen3_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn zen3_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::AGU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 17,
uops: 17,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 17,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 17,
}],
},
InstrItinerary {
opcode: x86_opcodes::PUSH,
latency: 1,
uops: 2,
write_resources: vec![
WriteRes {
resource: ProcResource::AGU0,
cycles: 1,
},
WriteRes {
resource: ProcResource::AGU1,
cycles: 1,
},
],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::POP,
latency: 4,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::AGU0,
cycles: 4,
}],
},
InstrItinerary {
opcode: x86_opcodes::CALL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RET,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SYSCALL,
latency: 28,
uops: 28,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn zen4_model() -> SchedModel {
let machine = SchedMachineModel {
name: "AMD Zen 4",
issue_width: 6,
micro_op_buffer_size: 64,
load_latency: 4,
store_latency: 1,
high_latency: 20,
misfetch_penalty: 16,
rob_size: 320,
phys_reg_count: 224,
out_of_order: true,
load_buffers: 120,
store_buffers: 72,
l1i_cache_size: 32768,
l1d_cache_size: 32768,
l2_cache_size: 1048576,
l3_cache_size: 33554432,
};
let resources = vec![
ProcResource::ALU0,
ProcResource::ALU1,
ProcResource::ALU2,
ProcResource::ALU3,
ProcResource::AGU0,
ProcResource::AGU1,
ProcResource::AGU2,
ProcResource::FPU0,
ProcResource::FPU1,
];
let itineraries = zen4_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn zen4_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::AGU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 15,
uops: 15,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 15,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 15,
}],
},
InstrItinerary {
opcode: x86_opcodes::SYSCALL,
latency: 24,
uops: 24,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn zen5_model() -> SchedModel {
let machine = SchedMachineModel {
name: "AMD Zen 5",
issue_width: 8,
micro_op_buffer_size: 72,
load_latency: 4,
store_latency: 1,
high_latency: 20,
misfetch_penalty: 16,
rob_size: 448,
phys_reg_count: 256,
out_of_order: true,
load_buffers: 144,
store_buffers: 96,
l1i_cache_size: 32768,
l1d_cache_size: 49152,
l2_cache_size: 1048576,
l3_cache_size: 33554432,
};
let resources = vec![
ProcResource::ALU0,
ProcResource::ALU1,
ProcResource::ALU2,
ProcResource::ALU3,
ProcResource::ALU4,
ProcResource::ALU5,
ProcResource::AGU0,
ProcResource::AGU1,
ProcResource::AGU2,
ProcResource::AGU3,
ProcResource::FPU0,
ProcResource::FPU1,
ProcResource::FPU2,
ProcResource::FPU3,
];
let itineraries = zen5_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn zen5_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::AGU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 2,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 2,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 2,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 2,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 12,
uops: 12,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 12,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 12,
}],
},
InstrItinerary {
opcode: x86_opcodes::SYSCALL,
latency: 20,
uops: 20,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn meteor_lake_pcore_model() -> SchedModel {
let machine = SchedMachineModel {
name: "Intel Meteor Lake P-core (Redwood Cove)",
issue_width: 8,
micro_op_buffer_size: 96,
load_latency: 4,
store_latency: 1,
high_latency: 22,
misfetch_penalty: 16,
rob_size: 512,
phys_reg_count: 280,
out_of_order: true,
load_buffers: 192,
store_buffers: 114,
l1i_cache_size: 65536,
l1d_cache_size: 49152,
l2_cache_size: 2097152,
l3_cache_size: 25165824,
};
let resources = vec![
ProcResource::Port0,
ProcResource::Port1,
ProcResource::Port2,
ProcResource::Port3,
ProcResource::Port4,
ProcResource::Port5,
ProcResource::Port6,
ProcResource::Port7,
];
let itineraries = meteor_lake_pcore_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn meteor_lake_pcore_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::NOP,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 17,
uops: 24,
write_resources: vec![
WriteRes {
resource: ProcResource::Port0,
cycles: 6,
},
WriteRes {
resource: ProcResource::Port1,
cycles: 6,
},
WriteRes {
resource: ProcResource::Port5,
cycles: 6,
},
WriteRes {
resource: ProcResource::Port6,
cycles: 6,
},
],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 17,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::INC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::DEC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NOT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NEG,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::TEST,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SBB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSWAP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::PUSH,
latency: 1,
uops: 2,
write_resources: vec![
WriteRes {
resource: ProcResource::Port2,
cycles: 1,
},
WriteRes {
resource: ProcResource::Port4,
cycles: 1,
},
],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::POP,
latency: 4,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port2,
cycles: 4,
}],
},
InstrItinerary {
opcode: x86_opcodes::CALL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RET,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::SAR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ROL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ROR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::MOVSX,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::MOVZX,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTS,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSF,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSR,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::CBW,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CWDE,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CDQE,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RDTSC,
latency: 20,
uops: 18,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 18,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 20,
}],
},
InstrItinerary {
opcode: x86_opcodes::CPUID,
latency: 100,
uops: 100,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::SYSCALL,
latency: 30,
uops: 30,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn meteor_lake_ecore_model() -> SchedModel {
let machine = SchedMachineModel {
name: "Intel Meteor Lake E-core (Crestmont)",
issue_width: 6,
micro_op_buffer_size: 48,
load_latency: 5,
store_latency: 1,
high_latency: 18,
misfetch_penalty: 18,
rob_size: 128,
phys_reg_count: 96,
out_of_order: true,
load_buffers: 48,
store_buffers: 32,
l1i_cache_size: 65536,
l1d_cache_size: 32768,
l2_cache_size: 2097152,
l3_cache_size: 25165824,
};
let resources = vec![
ProcResource::ALU0,
ProcResource::ALU1,
ProcResource::ALU2,
ProcResource::ALU3,
ProcResource::AGU0,
ProcResource::AGU1,
ProcResource::BranchUnit,
];
let itineraries = meteor_lake_ecore_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn meteor_lake_ecore_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::NOP,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 4,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 4,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 4,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 4,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 25,
uops: 30,
write_resources: vec![
WriteRes {
resource: ProcResource::ALU0,
cycles: 10,
},
WriteRes {
resource: ProcResource::ALU1,
cycles: 10,
},
WriteRes {
resource: ProcResource::ALU2,
cycles: 10,
},
],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 25,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::INC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::DEC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NOT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NEG,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::TEST,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::PUSH,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::POP,
latency: 5,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::AGU1,
cycles: 5,
}],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CALL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RET,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::BSWAP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::MOVSX,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::MOVZX,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SAR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::CPUID,
latency: 120,
uops: 120,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ThreadDirectorClass {
EE = 1,
Efficient = 2,
Balanced = 3,
Performance = 4,
Peak = 5,
}
#[derive(Debug, Clone)]
pub struct ThreadDirectorHint {
pub preferred_core: HybridCoreType,
pub class: ThreadDirectorClass,
pub perf_score: u8,
pub energy_score: u8,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HybridCoreType {
Pcore,
Ecore,
Any,
}
pub fn thread_director_hint(
has_avx512: bool,
has_branch_density_high: bool,
is_latency_bound: bool,
is_throughput_heavy: bool,
) -> ThreadDirectorHint {
if has_avx512 || is_latency_bound {
ThreadDirectorHint {
preferred_core: HybridCoreType::Pcore,
class: ThreadDirectorClass::Peak,
perf_score: 255,
energy_score: 0,
}
} else if has_branch_density_high {
ThreadDirectorHint {
preferred_core: HybridCoreType::Pcore,
class: ThreadDirectorClass::Performance,
perf_score: 200,
energy_score: 50,
}
} else if is_throughput_heavy {
ThreadDirectorHint {
preferred_core: HybridCoreType::Ecore,
class: ThreadDirectorClass::Efficient,
perf_score: 100,
energy_score: 180,
}
} else {
ThreadDirectorHint {
preferred_core: HybridCoreType::Any,
class: ThreadDirectorClass::Balanced,
perf_score: 128,
energy_score: 128,
}
}
}
#[derive(Debug, Clone)]
pub struct Avx512FreqInfo {
pub base_freq_mhz: u32,
pub avx512_light_freq_mhz: u32,
pub avx512_heavy_freq_mhz: u32,
pub freq_offset_per_core: u32,
pub all_core_avx512_max_mhz: u32,
}
impl Avx512FreqInfo {
pub fn effective_freq_mhz(&self, active_avx512_cores: u32, is_heavy: bool) -> u32 {
let base = if is_heavy {
self.avx512_heavy_freq_mhz
} else {
self.avx512_light_freq_mhz
};
let offset = self
.freq_offset_per_core
.saturating_mul(active_avx512_cores.saturating_sub(1));
let freq = base.saturating_sub(offset);
freq.max(self.all_core_avx512_max_mhz)
}
pub fn avx512_penalty_ratio(&self) -> f64 {
self.avx512_heavy_freq_mhz as f64 / self.base_freq_mhz as f64
}
pub fn meteor_lake() -> Self {
Self {
base_freq_mhz: 3700,
avx512_light_freq_mhz: 3200,
avx512_heavy_freq_mhz: 2800,
freq_offset_per_core: 100,
all_core_avx512_max_mhz: 2400,
}
}
pub fn lunar_lake() -> Self {
Self {
base_freq_mhz: 4000,
avx512_light_freq_mhz: 3500,
avx512_heavy_freq_mhz: 3000,
freq_offset_per_core: 100,
all_core_avx512_max_mhz: 2600,
}
}
pub fn zen5() -> Self {
Self {
base_freq_mhz: 4700,
avx512_light_freq_mhz: 4400,
avx512_heavy_freq_mhz: 4100,
freq_offset_per_core: 75,
all_core_avx512_max_mhz: 3800,
}
}
pub fn zen6() -> Self {
Self {
base_freq_mhz: 5000,
avx512_light_freq_mhz: 4700,
avx512_heavy_freq_mhz: 4500,
freq_offset_per_core: 50,
all_core_avx512_max_mhz: 4200,
}
}
}
pub fn lunar_lake_pcore_model() -> SchedModel {
let machine = SchedMachineModel {
name: "Intel Lunar Lake P-core (Lion Cove)",
issue_width: 8,
micro_op_buffer_size: 112,
load_latency: 4,
store_latency: 1,
high_latency: 24,
misfetch_penalty: 14,
rob_size: 576,
phys_reg_count: 320,
out_of_order: true,
load_buffers: 224,
store_buffers: 128,
l1i_cache_size: 65536,
l1d_cache_size: 49152,
l2_cache_size: 2621440,
l3_cache_size: 12582912,
};
let resources = vec![
ProcResource::Port0,
ProcResource::Port1,
ProcResource::Port2,
ProcResource::Port3,
ProcResource::Port4,
ProcResource::Port5,
ProcResource::Port6,
ProcResource::Port7,
];
let itineraries = lunar_lake_pcore_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn lunar_lake_pcore_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::NOP,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 15,
uops: 22,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 22,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 15,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::INC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::DEC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NOT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NEG,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::TEST,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SBB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSWAP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::PUSH,
latency: 1,
uops: 2,
write_resources: vec![
WriteRes {
resource: ProcResource::Port2,
cycles: 1,
},
WriteRes {
resource: ProcResource::Port4,
cycles: 1,
},
],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::POP,
latency: 4,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port2,
cycles: 4,
}],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CALL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RET,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::SAR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ROL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ROR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::MOVSX,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::MOVZX,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTS,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSF,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSR,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::CBW,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CWDE,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CDQE,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RDTSC,
latency: 18,
uops: 16,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 16,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 18,
}],
},
InstrItinerary {
opcode: x86_opcodes::CPUID,
latency: 90,
uops: 90,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::SYSCALL,
latency: 25,
uops: 25,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn lunar_lake_ecore_model() -> SchedModel {
let machine = SchedMachineModel {
name: "Intel Lunar Lake E-core (Skymont)",
issue_width: 9,
micro_op_buffer_size: 72,
load_latency: 5,
store_latency: 1,
high_latency: 18,
misfetch_penalty: 16,
rob_size: 192,
phys_reg_count: 128,
out_of_order: true,
load_buffers: 72,
store_buffers: 48,
l1i_cache_size: 65536,
l1d_cache_size: 32768,
l2_cache_size: 2097152,
l3_cache_size: 12582912,
};
let resources = vec![
ProcResource::ALU0,
ProcResource::ALU1,
ProcResource::ALU2,
ProcResource::ALU3,
ProcResource::ALU4,
ProcResource::ALU5,
ProcResource::AGU0,
ProcResource::AGU1,
ProcResource::AGU2,
ProcResource::BranchUnit,
];
let itineraries = lunar_lake_ecore_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn lunar_lake_ecore_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::NOP,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 20,
uops: 24,
write_resources: vec![
WriteRes {
resource: ProcResource::ALU0,
cycles: 8,
},
WriteRes {
resource: ProcResource::ALU1,
cycles: 8,
},
WriteRes {
resource: ProcResource::ALU2,
cycles: 8,
},
],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 20,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::INC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::DEC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CALL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RET,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::BSWAP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SAR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::CPUID,
latency: 100,
uops: 100,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn arrow_lake_pcore_model() -> SchedModel {
let machine = SchedMachineModel {
name: "Intel Arrow Lake P-core (Lion Cove Desktop)",
issue_width: 8,
micro_op_buffer_size: 112,
load_latency: 4,
store_latency: 1,
high_latency: 24,
misfetch_penalty: 14,
rob_size: 576,
phys_reg_count: 320,
out_of_order: true,
load_buffers: 256,
store_buffers: 144,
l1i_cache_size: 65536,
l1d_cache_size: 49152,
l2_cache_size: 3145728,
l3_cache_size: 37748736,
};
let resources = vec![
ProcResource::Port0,
ProcResource::Port1,
ProcResource::Port2,
ProcResource::Port3,
ProcResource::Port4,
ProcResource::Port5,
ProcResource::Port6,
ProcResource::Port7,
];
let itineraries = arrow_lake_pcore_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn arrow_lake_pcore_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::NOP,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 15,
uops: 22,
write_resources: vec![WriteRes {
resource: ProcResource::Port1,
cycles: 22,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port1,
cycles: 15,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port6,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::PUSH,
latency: 1,
uops: 2,
write_resources: vec![
WriteRes {
resource: ProcResource::Port2,
cycles: 1,
},
WriteRes {
resource: ProcResource::Port4,
cycles: 1,
},
],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::POP,
latency: 4,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::Port2,
cycles: 4,
}],
},
InstrItinerary {
opcode: x86_opcodes::CALL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RET,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::Port6,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CPUID,
latency: 90,
uops: 90,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn sierra_forest_model() -> SchedModel {
let machine = SchedMachineModel {
name: "Intel Sierra Forest (Sierra Glen)",
issue_width: 6,
micro_op_buffer_size: 48,
load_latency: 5,
store_latency: 1,
high_latency: 22,
misfetch_penalty: 20,
rob_size: 128,
phys_reg_count: 96,
out_of_order: true,
load_buffers: 48,
store_buffers: 32,
l1i_cache_size: 65536,
l1d_cache_size: 32768,
l2_cache_size: 4194304,
l3_cache_size: 113246208,
};
let resources = vec![
ProcResource::ALU0,
ProcResource::ALU1,
ProcResource::ALU2,
ProcResource::ALU3,
ProcResource::AGU0,
ProcResource::AGU1,
ProcResource::BranchUnit,
];
let itineraries = sierra_forest_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn sierra_forest_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::NOP,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 4,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 4,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 4,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 4,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 28,
uops: 32,
write_resources: vec![
WriteRes {
resource: ProcResource::ALU0,
cycles: 12,
},
WriteRes {
resource: ProcResource::ALU1,
cycles: 10,
},
WriteRes {
resource: ProcResource::ALU2,
cycles: 10,
},
],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 28,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::PUSH,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::POP,
latency: 5,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::AGU1,
cycles: 5,
}],
},
InstrItinerary {
opcode: x86_opcodes::CALL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RET,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CPUID,
latency: 130,
uops: 130,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn clearwater_forest_model() -> SchedModel {
let machine = SchedMachineModel {
name: "Intel Clearwater Forest (Darkmont)",
issue_width: 9,
micro_op_buffer_size: 72,
load_latency: 5,
store_latency: 1,
high_latency: 24,
misfetch_penalty: 18,
rob_size: 224,
phys_reg_count: 144,
out_of_order: true,
load_buffers: 80,
store_buffers: 48,
l1i_cache_size: 65536,
l1d_cache_size: 49152,
l2_cache_size: 4194304,
l3_cache_size: 150994944,
};
let resources = vec![
ProcResource::ALU0,
ProcResource::ALU1,
ProcResource::ALU2,
ProcResource::ALU3,
ProcResource::ALU4,
ProcResource::ALU5,
ProcResource::AGU0,
ProcResource::AGU1,
ProcResource::AGU2,
ProcResource::BranchUnit,
];
let itineraries = clearwater_forest_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn clearwater_forest_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::NOP,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 18,
uops: 20,
write_resources: vec![
WriteRes {
resource: ProcResource::ALU0,
cycles: 8,
},
WriteRes {
resource: ProcResource::ALU1,
cycles: 6,
},
WriteRes {
resource: ProcResource::ALU2,
cycles: 6,
},
],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 18,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::INC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::DEC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::PUSH,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::POP,
latency: 5,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::AGU1,
cycles: 5,
}],
},
InstrItinerary {
opcode: x86_opcodes::CPUID,
latency: 100,
uops: 100,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn zen5c_model() -> SchedModel {
let machine = SchedMachineModel {
name: "AMD Zen 5c (Prometheus Dense)",
issue_width: 6,
micro_op_buffer_size: 48,
load_latency: 4,
store_latency: 1,
high_latency: 20,
misfetch_penalty: 18,
rob_size: 256,
phys_reg_count: 224,
out_of_order: true,
load_buffers: 72,
store_buffers: 48,
l1i_cache_size: 32768,
l1d_cache_size: 32768,
l2_cache_size: 1048576,
l3_cache_size: 16777216,
};
let resources = vec![
ProcResource::ALU0,
ProcResource::ALU1,
ProcResource::ALU2,
ProcResource::ALU3,
ProcResource::ALU4,
ProcResource::ALU5,
ProcResource::AGU0,
ProcResource::AGU1,
ProcResource::AGU2,
ProcResource::AGU3,
ProcResource::FPU0,
ProcResource::FPU1,
ProcResource::FPU2,
ProcResource::FPU3,
ProcResource::BranchUnit,
];
let itineraries = zen5c_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn zen5c_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::NOP,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 15,
uops: 15,
write_resources: vec![WriteRes {
resource: ProcResource::IntegerDivider,
cycles: 15,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::IntegerDivider,
cycles: 15,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::INC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::DEC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NOT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NEG,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::TEST,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSWAP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::PUSH,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::POP,
latency: 4,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::AGU0,
cycles: 4,
}],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CALL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RET,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::SAR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ROL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ROR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::MOVSX,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::MOVZX,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTS,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BTC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSF,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSR,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::CBW,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CWDE,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CDQE,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RDTSC,
latency: 25,
uops: 22,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 22,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 25,
}],
},
InstrItinerary {
opcode: x86_opcodes::CPUID,
latency: 110,
uops: 110,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::SYSCALL,
latency: 35,
uops: 35,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn zen6_model() -> SchedModel {
let machine = SchedMachineModel {
name: "AMD Zen 6 (Morpheus)",
issue_width: 8,
micro_op_buffer_size: 80,
load_latency: 4,
store_latency: 1,
high_latency: 22,
misfetch_penalty: 14,
rob_size: 640,
phys_reg_count: 384,
out_of_order: true,
load_buffers: 144,
store_buffers: 96,
l1i_cache_size: 65536,
l1d_cache_size: 49152,
l2_cache_size: 2097152,
l3_cache_size: 67108864,
};
let resources = vec![
ProcResource::ALU0,
ProcResource::ALU1,
ProcResource::ALU2,
ProcResource::ALU3,
ProcResource::ALU4,
ProcResource::ALU5,
ProcResource::AGU0,
ProcResource::AGU1,
ProcResource::AGU2,
ProcResource::AGU3,
ProcResource::FPU0,
ProcResource::FPU1,
ProcResource::FPU2,
ProcResource::FPU3,
ProcResource::VectorALU,
ProcResource::VectorMultiplier,
ProcResource::VectorShuffle,
ProcResource::BranchUnit,
];
let itineraries = zen6_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn zen6_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::NOP,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 2,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 2,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 2,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 2,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 10,
uops: 10,
write_resources: vec![WriteRes {
resource: ProcResource::IntegerDivider,
cycles: 10,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::IntegerDivider,
cycles: 10,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::INC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::DEC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NOT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::NEG,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::TEST,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SBB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSWAP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::PUSH,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::POP,
latency: 4,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::AGU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::AGU0,
cycles: 4,
}],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CALL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RET,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::SAR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ROL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ROR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::MOVSX,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::MOVZX,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BT,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSF,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::BSR,
latency: 3,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 3,
}],
},
InstrItinerary {
opcode: x86_opcodes::CBW,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CWDE,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CDQE,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RDTSC,
latency: 15,
uops: 12,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 12,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 15,
}],
},
InstrItinerary {
opcode: x86_opcodes::CPUID,
latency: 80,
uops: 80,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::SYSCALL,
latency: 18,
uops: 18,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
pub fn zen6c_model() -> SchedModel {
let machine = SchedMachineModel {
name: "AMD Zen 6c (Morpheus Dense)",
issue_width: 6,
micro_op_buffer_size: 64,
load_latency: 4,
store_latency: 1,
high_latency: 20,
misfetch_penalty: 16,
rob_size: 384,
phys_reg_count: 256,
out_of_order: true,
load_buffers: 96,
store_buffers: 64,
l1i_cache_size: 32768,
l1d_cache_size: 32768,
l2_cache_size: 1048576,
l3_cache_size: 33554432,
};
let resources = vec![
ProcResource::ALU0,
ProcResource::ALU1,
ProcResource::ALU2,
ProcResource::ALU3,
ProcResource::ALU4,
ProcResource::ALU5,
ProcResource::AGU0,
ProcResource::AGU1,
ProcResource::AGU2,
ProcResource::FPU0,
ProcResource::FPU1,
ProcResource::FPU2,
ProcResource::FPU3,
ProcResource::BranchUnit,
];
let itineraries = zen6c_itineraries();
SchedModel {
machine,
resources,
itineraries,
}
}
fn zen6c_itineraries() -> Vec<InstrItinerary> {
vec![
InstrItinerary {
opcode: x86_opcodes::NOP,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::MOV,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::ADD,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SUB,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::AND,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU2,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU2,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::OR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::XOR,
latency: 0,
uops: 0,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::LEA,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU5,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU5,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::IMUL,
latency: 2,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 2,
}],
},
InstrItinerary {
opcode: x86_opcodes::MUL,
latency: 2,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU3,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU3,
cycles: 2,
}],
},
InstrItinerary {
opcode: x86_opcodes::DIV,
latency: 12,
uops: 12,
write_resources: vec![WriteRes {
resource: ProcResource::IntegerDivider,
cycles: 12,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::IntegerDivider,
cycles: 12,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::SHR,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU4,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU4,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::INC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU0,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU0,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::DEC,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::ALU1,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![WriteLatency {
resource: ProcResource::ALU1,
cycles: 1,
}],
},
InstrItinerary {
opcode: x86_opcodes::JMP,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::JNE,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CALL,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::RET,
latency: 1,
uops: 1,
write_resources: vec![WriteRes {
resource: ProcResource::BranchUnit,
cycles: 1,
}],
read_advances: vec![],
write_latencies: vec![],
},
InstrItinerary {
opcode: x86_opcodes::CPUID,
latency: 90,
uops: 90,
write_resources: vec![],
read_advances: vec![],
write_latencies: vec![],
},
]
}
#[derive(Debug, Clone)]
pub struct HybridSchedDecision {
pub core_type: HybridCoreType,
pub reason: &'static str,
pub avx512_available: bool,
}
pub fn hybrid_sched_decision(
has_pcores: bool,
has_ecores: bool,
is_single_thread_bound: bool,
has_avx512_instructions: bool,
is_low_power_mode: bool,
thread_count: u32,
) -> HybridSchedDecision {
if !has_pcores && has_ecores {
return HybridSchedDecision {
core_type: HybridCoreType::Ecore,
reason: "Only E-cores available",
avx512_available: false,
};
}
if !has_ecores && has_pcores {
return HybridSchedDecision {
core_type: HybridCoreType::Pcore,
reason: "Only P-cores available",
avx512_available: true,
};
}
if has_avx512_instructions {
return HybridSchedDecision {
core_type: HybridCoreType::Pcore,
reason: "AVX-512 requires P-core",
avx512_available: true,
};
}
if is_single_thread_bound {
return HybridSchedDecision {
core_type: HybridCoreType::Pcore,
reason: "Single-thread latency prefers P-core",
avx512_available: true,
};
}
if is_low_power_mode || thread_count > 8 {
return HybridSchedDecision {
core_type: HybridCoreType::Ecore,
reason: "Throughput / power efficiency prefers E-core",
avx512_available: false,
};
}
HybridSchedDecision {
core_type: HybridCoreType::Any,
reason: "Balanced: any core acceptable",
avx512_available: false,
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum X86SchedModelKind {
SkylakeClient,
IceLake,
IceLakeClient,
AlderLakePcore,
AlderLakeP,
GraniteRapids,
Zen3,
Zen4,
Zen5,
MeteorLakePcore,
MeteorLakeEcore,
LunarLakePcore,
LunarLakeEcore,
ArrowLakePcore,
SierraForest,
ClearwaterForest,
Zen5c,
Zen6,
Zen6c,
SandyBridge,
IvyBridge,
Haswell,
Broadwell,
Goldmont,
GoldmontPlus,
Generic,
}
impl X86SchedModelKind {
pub fn model(self) -> SchedModel {
match self {
X86SchedModelKind::SkylakeClient => skylake_client_model(),
X86SchedModelKind::IceLake => ice_lake_model(),
X86SchedModelKind::AlderLakePcore => alder_lake_pcore_model(),
X86SchedModelKind::GraniteRapids => granite_rapids_model(),
X86SchedModelKind::Zen3 => zen3_model(),
X86SchedModelKind::Zen4 => zen4_model(),
X86SchedModelKind::Zen5 => zen5_model(),
X86SchedModelKind::MeteorLakePcore => meteor_lake_pcore_model(),
X86SchedModelKind::MeteorLakeEcore => meteor_lake_ecore_model(),
X86SchedModelKind::LunarLakePcore => lunar_lake_pcore_model(),
X86SchedModelKind::LunarLakeEcore => lunar_lake_ecore_model(),
X86SchedModelKind::ArrowLakePcore => arrow_lake_pcore_model(),
X86SchedModelKind::SierraForest => sierra_forest_model(),
X86SchedModelKind::ClearwaterForest => clearwater_forest_model(),
X86SchedModelKind::Zen5c => zen5c_model(),
X86SchedModelKind::Zen6 => zen6_model(),
X86SchedModelKind::Zen6c => zen6c_model(),
X86SchedModelKind::IceLakeClient => ice_lake_model(),
X86SchedModelKind::AlderLakeP => alder_lake_pcore_model(),
X86SchedModelKind::SandyBridge => skylake_client_model(),
X86SchedModelKind::IvyBridge => skylake_client_model(),
X86SchedModelKind::Haswell => skylake_client_model(),
X86SchedModelKind::Broadwell => skylake_client_model(),
X86SchedModelKind::Goldmont => skylake_client_model(),
X86SchedModelKind::GoldmontPlus => skylake_client_model(),
X86SchedModelKind::Generic => skylake_client_model(),
}
}
pub fn name(self) -> &'static str {
match self {
X86SchedModelKind::SkylakeClient => "Intel Skylake Client",
X86SchedModelKind::IceLake => "Intel Ice Lake",
X86SchedModelKind::AlderLakePcore => "Intel Alder Lake (Golden Cove)",
X86SchedModelKind::GraniteRapids => "Intel Granite Rapids (Redwood Cove)",
X86SchedModelKind::Zen3 => "AMD Zen 3",
X86SchedModelKind::Zen4 => "AMD Zen 4",
X86SchedModelKind::Zen5 => "AMD Zen 5",
X86SchedModelKind::MeteorLakePcore => "Intel Meteor Lake P-core (Redwood Cove)",
X86SchedModelKind::MeteorLakeEcore => "Intel Meteor Lake E-core (Crestmont)",
X86SchedModelKind::LunarLakePcore => "Intel Lunar Lake P-core (Lion Cove)",
X86SchedModelKind::LunarLakeEcore => "Intel Lunar Lake E-core (Skymont)",
X86SchedModelKind::ArrowLakePcore => "Intel Arrow Lake P-core (Lion Cove Desktop)",
X86SchedModelKind::SierraForest => "Intel Sierra Forest (Sierra Glen)",
X86SchedModelKind::ClearwaterForest => "Intel Clearwater Forest (Darkmont)",
X86SchedModelKind::Zen5c => "AMD Zen 5c (Prometheus Dense)",
X86SchedModelKind::Zen6 => "AMD Zen 6 (Morpheus)",
X86SchedModelKind::Zen6c => "AMD Zen 6c (Morpheus Dense)",
X86SchedModelKind::IceLakeClient => "Intel Ice Lake Client",
X86SchedModelKind::AlderLakeP => "Intel Alder Lake P-core",
X86SchedModelKind::SandyBridge => "Intel Sandy Bridge",
X86SchedModelKind::IvyBridge => "Intel Ivy Bridge",
X86SchedModelKind::Haswell => "Intel Haswell",
X86SchedModelKind::Broadwell => "Intel Broadwell",
X86SchedModelKind::Goldmont => "Intel Goldmont",
X86SchedModelKind::GoldmontPlus => "Intel Goldmont Plus",
X86SchedModelKind::Generic => "Generic X86",
}
}
pub fn is_pcore(self) -> bool {
matches!(
self,
X86SchedModelKind::SkylakeClient
| X86SchedModelKind::IceLake
| X86SchedModelKind::AlderLakePcore
| X86SchedModelKind::GraniteRapids
| X86SchedModelKind::Zen3
| X86SchedModelKind::Zen4
| X86SchedModelKind::Zen5
| X86SchedModelKind::MeteorLakePcore
| X86SchedModelKind::LunarLakePcore
| X86SchedModelKind::ArrowLakePcore
| X86SchedModelKind::Zen6
| X86SchedModelKind::IceLakeClient
| X86SchedModelKind::AlderLakeP
| X86SchedModelKind::SandyBridge
| X86SchedModelKind::IvyBridge
| X86SchedModelKind::Haswell
| X86SchedModelKind::Broadwell
| X86SchedModelKind::Generic
)
}
pub fn is_ecore(self) -> bool {
matches!(
self,
X86SchedModelKind::MeteorLakeEcore
| X86SchedModelKind::LunarLakeEcore
| X86SchedModelKind::SierraForest
| X86SchedModelKind::ClearwaterForest
)
}
pub fn is_dense(self) -> bool {
matches!(self, X86SchedModelKind::Zen5c | X86SchedModelKind::Zen6c)
}
pub fn has_avx512(self) -> bool {
matches!(
self,
X86SchedModelKind::SkylakeClient
| X86SchedModelKind::IceLake
| X86SchedModelKind::AlderLakePcore
| X86SchedModelKind::GraniteRapids
| X86SchedModelKind::Zen4
| X86SchedModelKind::Zen5
| X86SchedModelKind::Zen5c
| X86SchedModelKind::Zen6
| X86SchedModelKind::Zen6c
| X86SchedModelKind::MeteorLakePcore
| X86SchedModelKind::LunarLakePcore
| X86SchedModelKind::ArrowLakePcore
| X86SchedModelKind::IceLakeClient
| X86SchedModelKind::AlderLakeP
)
}
}
pub fn lookup_itinerary(model: &SchedModel, opcode: u32) -> Option<&InstrItinerary> {
model.itineraries.iter().find(|i| i.opcode == opcode)
}
pub fn instruction_latency(model: &SchedModel, opcode: u32) -> Option<u32> {
lookup_itinerary(model, opcode).map(|i| i.latency)
}
pub fn instruction_uops(model: &SchedModel, opcode: u32) -> Option<u32> {
lookup_itinerary(model, opcode).map(|i| i.uops)
}
pub fn instruction_resources(model: &SchedModel, opcode: u32) -> Vec<ProcResource> {
lookup_itinerary(model, opcode)
.map(|i| i.write_resources.iter().map(|wr| wr.resource).collect())
.unwrap_or_default()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_skylake_model_exists() {
let model = skylake_client_model();
assert_eq!(model.machine.name, "Intel Skylake Client");
assert_eq!(model.machine.issue_width, 8);
assert_eq!(model.machine.rob_size, 224);
assert!(!model.itineraries.is_empty());
}
#[test]
fn test_icelake_model_exists() {
let model = ice_lake_model();
assert_eq!(model.machine.name, "Intel Ice Lake Client");
assert_eq!(model.machine.issue_width, 10);
assert_eq!(model.machine.rob_size, 352);
}
#[test]
fn test_alderlake_model_exists() {
let model = alder_lake_pcore_model();
assert_eq!(model.machine.rob_size, 512);
}
#[test]
fn test_granite_rapids_model_exists() {
let model = granite_rapids_model();
assert_eq!(model.machine.name, "Intel Granite Rapids (Redwood Cove)");
}
#[test]
fn test_zen3_model_exists() {
let model = zen3_model();
assert_eq!(model.machine.name, "AMD Zen 3");
assert_eq!(model.machine.rob_size, 256);
}
#[test]
fn test_zen4_model_exists() {
let model = zen4_model();
assert_eq!(model.machine.name, "AMD Zen 4");
assert_eq!(model.machine.rob_size, 320);
}
#[test]
fn test_zen5_model_exists() {
let model = zen5_model();
assert_eq!(model.machine.name, "AMD Zen 5");
assert_eq!(model.machine.rob_size, 448);
}
#[test]
fn test_lookup_itinerary_add() {
let model = skylake_client_model();
let itinerary = lookup_itinerary(&model, x86_opcodes::ADD);
assert!(itinerary.is_some());
assert_eq!(itinerary.unwrap().latency, 1);
}
#[test]
fn test_lookup_itinerary_mov() {
let model = skylake_client_model();
let itinerary = lookup_itinerary(&model, x86_opcodes::MOV);
assert!(itinerary.is_some());
}
#[test]
fn test_lookup_itinerary_div() {
let model = skylake_client_model();
let itinerary = lookup_itinerary(&model, x86_opcodes::DIV);
assert!(itinerary.is_some());
assert!(itinerary.unwrap().latency > 10); }
#[test]
fn test_lookup_missing_opcode() {
let model = skylake_client_model();
let itinerary = lookup_itinerary(&model, 9999);
assert!(itinerary.is_none());
}
#[test]
fn test_xor_zero_latency() {
let model = skylake_client_model();
let itinerary = lookup_itinerary(&model, x86_opcodes::XOR).unwrap();
assert_eq!(itinerary.latency, 0);
assert_eq!(itinerary.uops, 0);
}
#[test]
fn test_model_kind_enum() {
let kinds = vec![
X86SchedModelKind::SkylakeClient,
X86SchedModelKind::IceLake,
X86SchedModelKind::AlderLakePcore,
X86SchedModelKind::GraniteRapids,
X86SchedModelKind::Zen3,
X86SchedModelKind::Zen4,
X86SchedModelKind::Zen5,
];
for kind in kinds {
let model = kind.model();
assert!(!model.itineraries.is_empty());
assert!(!kind.name().is_empty());
}
}
#[test]
fn test_instruction_latency_helper() {
let model = skylake_client_model();
assert_eq!(instruction_latency(&model, x86_opcodes::ADD), Some(1));
assert_eq!(instruction_latency(&model, x86_opcodes::MOV), Some(1));
assert_eq!(instruction_latency(&model, x86_opcodes::XOR), Some(0));
assert_eq!(instruction_latency(&model, 99999), None);
}
#[test]
fn test_instruction_uops_helper() {
let model = skylake_client_model();
assert_eq!(instruction_uops(&model, x86_opcodes::ADD), Some(1));
assert_eq!(instruction_uops(&model, x86_opcodes::XOR), Some(0));
assert_eq!(instruction_uops(&model, x86_opcodes::DIV), Some(36));
}
#[test]
fn test_instruction_resources_helper() {
let model = skylake_client_model();
let resources = instruction_resources(&model, x86_opcodes::DIV);
assert!(!resources.is_empty()); }
#[test]
fn test_meteor_lake_pcore_model_exists() {
let model = meteor_lake_pcore_model();
assert_eq!(
model.machine.name,
"Intel Meteor Lake P-core (Redwood Cove)"
);
assert_eq!(model.machine.rob_size, 512);
assert_eq!(model.machine.issue_width, 8);
}
#[test]
fn test_meteor_lake_ecore_model_exists() {
let model = meteor_lake_ecore_model();
assert_eq!(model.machine.name, "Intel Meteor Lake E-core (Crestmont)");
assert_eq!(model.machine.rob_size, 128);
assert_eq!(model.machine.issue_width, 6);
}
#[test]
fn test_lunar_lake_pcore_model_exists() {
let model = lunar_lake_pcore_model();
assert_eq!(model.machine.rob_size, 576);
assert_eq!(model.machine.issue_width, 8);
}
#[test]
fn test_lunar_lake_ecore_model_exists() {
let model = lunar_lake_ecore_model();
assert_eq!(model.machine.rob_size, 192);
assert_eq!(model.machine.issue_width, 9);
}
#[test]
fn test_sierra_forest_model_exists() {
let model = sierra_forest_model();
assert_eq!(model.machine.name, "Intel Sierra Forest (Sierra Glen)");
assert_eq!(model.machine.rob_size, 128);
}
#[test]
fn test_clearwater_forest_model_exists() {
let model = clearwater_forest_model();
assert_eq!(model.machine.rob_size, 224);
assert_eq!(model.machine.issue_width, 9);
}
#[test]
fn test_zen5c_model_exists() {
let model = zen5c_model();
assert_eq!(model.machine.name, "AMD Zen 5c (Prometheus Dense)");
assert_eq!(model.machine.issue_width, 6);
}
#[test]
fn test_zen6_model_exists() {
let model = zen6_model();
assert_eq!(model.machine.name, "AMD Zen 6 (Morpheus)");
assert_eq!(model.machine.rob_size, 640);
assert_eq!(model.machine.issue_width, 8);
}
#[test]
fn test_zen6c_model_exists() {
let model = zen6c_model();
assert_eq!(model.machine.rob_size, 384);
assert_eq!(model.machine.issue_width, 6);
}
#[test]
fn test_model_kind_enum_all() {
let kinds = vec![
X86SchedModelKind::SkylakeClient,
X86SchedModelKind::IceLake,
X86SchedModelKind::AlderLakePcore,
X86SchedModelKind::GraniteRapids,
X86SchedModelKind::Zen3,
X86SchedModelKind::Zen4,
X86SchedModelKind::Zen5,
X86SchedModelKind::MeteorLakePcore,
X86SchedModelKind::MeteorLakeEcore,
X86SchedModelKind::LunarLakePcore,
X86SchedModelKind::LunarLakeEcore,
X86SchedModelKind::ArrowLakePcore,
X86SchedModelKind::SierraForest,
X86SchedModelKind::ClearwaterForest,
X86SchedModelKind::Zen5c,
X86SchedModelKind::Zen6,
X86SchedModelKind::Zen6c,
];
for kind in kinds {
let model = kind.model();
assert!(!model.itineraries.is_empty());
assert!(!kind.name().is_empty());
}
}
#[test]
fn test_is_pcore_ecore_dense() {
assert!(X86SchedModelKind::MeteorLakePcore.is_pcore());
assert!(!X86SchedModelKind::MeteorLakePcore.is_ecore());
assert!(X86SchedModelKind::MeteorLakeEcore.is_ecore());
assert!(!X86SchedModelKind::MeteorLakeEcore.is_pcore());
assert!(X86SchedModelKind::Zen5c.is_dense());
assert!(!X86SchedModelKind::Zen5.is_dense());
assert!(X86SchedModelKind::Zen6c.is_dense());
}
#[test]
fn test_has_avx512() {
assert!(X86SchedModelKind::Zen5.has_avx512());
assert!(X86SchedModelKind::Zen6.has_avx512());
assert!(!X86SchedModelKind::Zen3.has_avx512());
assert!(!X86SchedModelKind::SierraForest.has_avx512());
assert!(X86SchedModelKind::LunarLakePcore.has_avx512());
assert!(!X86SchedModelKind::LunarLakeEcore.has_avx512());
}
#[test]
fn test_thread_director_hint_avx512() {
let hint = thread_director_hint(true, false, false, false);
assert_eq!(hint.preferred_core, HybridCoreType::Pcore);
assert_eq!(hint.class, ThreadDirectorClass::Peak);
assert_eq!(hint.perf_score, 255);
}
#[test]
fn test_thread_director_hint_latency() {
let hint = thread_director_hint(false, false, true, false);
assert_eq!(hint.preferred_core, HybridCoreType::Pcore);
}
#[test]
fn test_thread_director_hint_throughput() {
let hint = thread_director_hint(false, false, false, true);
assert_eq!(hint.preferred_core, HybridCoreType::Ecore);
assert_eq!(hint.class, ThreadDirectorClass::Efficient);
}
#[test]
fn test_thread_director_hint_balanced() {
let hint = thread_director_hint(false, false, false, false);
assert_eq!(hint.preferred_core, HybridCoreType::Any);
assert_eq!(hint.class, ThreadDirectorClass::Balanced);
}
#[test]
fn test_hybrid_sched_decision_pcores_only() {
let dec = hybrid_sched_decision(true, false, false, false, false, 1);
assert_eq!(dec.core_type, HybridCoreType::Pcore);
assert_eq!(dec.reason, "Only P-cores available");
}
#[test]
fn test_hybrid_sched_decision_ecores_only() {
let dec = hybrid_sched_decision(false, true, false, false, false, 1);
assert_eq!(dec.core_type, HybridCoreType::Ecore);
}
#[test]
fn test_hybrid_sched_decision_avx512() {
let dec = hybrid_sched_decision(true, true, false, true, false, 4);
assert_eq!(dec.core_type, HybridCoreType::Pcore);
assert_eq!(dec.reason, "AVX-512 requires P-core");
}
#[test]
fn test_hybrid_sched_decision_single_thread() {
let dec = hybrid_sched_decision(true, true, true, false, false, 1);
assert_eq!(dec.core_type, HybridCoreType::Pcore);
}
#[test]
fn test_hybrid_sched_decision_low_power() {
let dec = hybrid_sched_decision(true, true, false, false, true, 4);
assert_eq!(dec.core_type, HybridCoreType::Ecore);
}
#[test]
fn test_avx512_freq_info_meteor_lake() {
let info = Avx512FreqInfo::meteor_lake();
assert_eq!(info.base_freq_mhz, 3700);
let eff = info.effective_freq_mhz(2, true);
assert!(eff >= info.all_core_avx512_max_mhz);
assert!(eff <= info.avx512_heavy_freq_mhz);
}
#[test]
fn test_avx512_freq_info_lunar_lake() {
let info = Avx512FreqInfo::lunar_lake();
assert_eq!(info.base_freq_mhz, 4000);
assert!(info.avx512_penalty_ratio() > 0.0 && info.avx512_penalty_ratio() <= 1.0);
}
#[test]
fn test_avx512_freq_info_zen5() {
let info = Avx512FreqInfo::zen5();
assert_eq!(info.base_freq_mhz, 4700);
let eff = info.effective_freq_mhz(4, false);
assert!(eff >= info.all_core_avx512_max_mhz);
}
#[test]
fn test_avx512_freq_info_zen6() {
let info = Avx512FreqInfo::zen6();
assert_eq!(info.base_freq_mhz, 5000);
assert!(info.avx512_penalty_ratio() > 0.8);
}
#[test]
fn test_arrow_lake_pcore_model() {
let model = arrow_lake_pcore_model();
assert_eq!(
model.machine.name,
"Intel Arrow Lake P-core (Lion Cove Desktop)"
);
assert_eq!(model.machine.rob_size, 576);
}
#[test]
fn test_all_models_have_itineraries() {
let models = vec![
meteor_lake_pcore_model(),
meteor_lake_ecore_model(),
lunar_lake_pcore_model(),
lunar_lake_ecore_model(),
arrow_lake_pcore_model(),
sierra_forest_model(),
clearwater_forest_model(),
zen5c_model(),
zen6_model(),
zen6c_model(),
];
for model in models {
assert!(
!model.itineraries.is_empty(),
"Model {} has empty itineraries",
model.machine.name
);
assert!(model.machine.issue_width > 0);
assert!(model.machine.rob_size > 0);
}
}
#[test]
fn test_all_models_have_valid_cache_sizes() {
let models = vec![
meteor_lake_pcore_model(),
lunar_lake_pcore_model(),
zen6_model(),
zen5c_model(),
];
for model in models {
assert!(model.machine.l1i_cache_size > 0);
assert!(model.machine.l1d_cache_size > 0);
assert!(model.machine.l2_cache_size > 0);
assert!(model.machine.l3_cache_size > 0);
}
}
#[test]
fn test_hybrid_sched_decision_balanced() {
let dec = hybrid_sched_decision(true, true, false, false, false, 2);
assert_eq!(dec.core_type, HybridCoreType::Any);
}
#[test]
fn test_thread_director_hint_branch_density() {
let hint = thread_director_hint(false, true, false, false);
assert_eq!(hint.preferred_core, HybridCoreType::Pcore);
assert_eq!(hint.class, ThreadDirectorClass::Performance);
}
#[test]
fn test_avx512_freq_info_effective_freq() {
let info = Avx512FreqInfo::meteor_lake();
let eff = info.effective_freq_mhz(0, false);
assert_eq!(eff, 3200);
let heavy = info.effective_freq_mhz(8, true);
assert_eq!(heavy, 2800 - 700); }
#[test]
fn test_has_avx512_all_models() {
assert!(!X86SchedModelKind::MeteorLakeEcore.has_avx512());
assert!(!X86SchedModelKind::ClearwaterForest.has_avx512());
assert!(X86SchedModelKind::Zen5c.has_avx512());
assert!(X86SchedModelKind::Zen6c.has_avx512());
}
}