#![no_std]
#![no_main]
use core::mem::size_of;
use et_abi::{CACHE_LINE, DeviceArgs, MINIONS_PER_SHIRE, SimdTestArgs};
use et_kernel::{cache::cache_writeback, fence, hart_id, kernel_entry, shire_id};
kernel_entry!();
#[unsafe(no_mangle)]
pub extern "C" fn entry_point(args_ptr: usize) -> i64 {
let args: &SimdTestArgs = unsafe { SimdTestArgs::from_ptr(args_ptr as *const u8) };
let h = hart_id();
if h & 1 != 0 {
return 0;
}
let shire = shire_id();
let hart_in_shire = h & 63;
let minion_in_shire = hart_in_shire >> 1;
let my_minion = shire * MINIONS_PER_SHIRE + minion_in_shire;
let total_minions = args.n_shires as u32 * MINIONS_PER_SHIRE;
if my_minion >= total_minions {
return 0;
}
let input_bits = ((my_minion + 1) as f32).to_bits() as u64;
let alpha_bits = 3.0_f32.to_bits() as u64;
let result_bits: u64;
unsafe {
core::arch::asm!(
"fmv.w.x f2, {input_bits}",
".insn i 0x0b, 3, f28, {alpha_bits}, 0",
".insn r 0x7b, 0, 8, f2, f2, f28",
"fmv.x.w {result_bits}, f2",
input_bits = in(reg) input_bits,
alpha_bits = in(reg) alpha_bits,
result_bits = out(reg) result_bits,
out("f2") _,
out("f28") _,
options(nostack, preserves_flags),
);
}
let result = f32::from_bits(result_bits as u32);
let cell_addr = args.output as usize + my_minion as usize * CACHE_LINE;
unsafe {
core::ptr::write_volatile(cell_addr as *mut f32, result);
}
fence();
unsafe {
cache_writeback(cell_addr, size_of::<f32>());
}
fence();
0
}
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {
unsafe { core::arch::asm!("wfi") };
}
}