use crate::emulator::constants::operand_indices;
use crate::emulator::core::decode::OperandType;
use crate::emulator::instructions::VectorMode;
use crate::emulator::{EmulatorInstruction, ForwardComEmulator};
#[inline]
pub fn execute(instruction: &mut EmulatorInstruction, emulator: &mut ForwardComEmulator) {
let size = instruction.operand_type.log_size();
log::trace!(
"Operand size {}, element size {}",
instruction.operand_size,
1 << size
);
let call_count = match instruction.vector_mode {
VectorMode::Element => instruction.operand_size >> size,
VectorMode::Full => 1,
};
for i in 0..call_count {
let offset = i << size;
let mask = emulator
.operands
.get_offset_u8(operand_indices::MASK, offset);
if (mask & 0x01) > 0 {
(instruction.function)(emulator, instruction, offset);
match instruction.operand_type {
OperandType::I8 => {
log::trace!(
"Value after execution: {0} (hex {0:#X})",
emulator
.operands
.get_offset_u8(operand_indices::OUTPUT, offset)
);
}
OperandType::I16 => {
log::trace!(
"Value after execution: {0} (hex {0:#X})",
emulator
.operands
.get_offset_u16(operand_indices::OUTPUT, offset)
);
}
OperandType::I32 => {
log::trace!(
"Value after execution: {0} (hex {0:#X})",
emulator
.operands
.get_offset_u32(operand_indices::OUTPUT, offset)
);
}
OperandType::I64 => {
log::trace!(
"Value after execution: {0} (hex {0:#X})",
emulator
.operands
.get_offset_u64(operand_indices::OUTPUT, offset)
);
}
OperandType::I128 => {}
OperandType::F16 => {
log::trace!(
"Value after execution: {0} (hex {0:#X})",
half::f16::from_bits(
emulator
.operands
.get_offset_u16(operand_indices::OUTPUT, offset)
)
);
}
OperandType::F32 => {
log::trace!(
"Value after execution: {0}",
emulator
.operands
.get_offset_f32(operand_indices::OUTPUT, offset)
);
}
OperandType::F64 => {
log::trace!(
"Value after execution: {0}",
emulator
.operands
.get_offset_f64(operand_indices::OUTPUT, offset)
);
}
OperandType::F128 => {}
}
} else {
emulator.operands.copy(
operand_indices::FALLBACK,
operand_indices::OUTPUT,
offset,
offset,
1 << size,
);
}
}
assert!(instruction.valid, "Committed an invalid instruction");
}