use core::arch::naked_asm;
#[cfg(riscv64_moana)]
#[unsafe(naked)]
#[unsafe(no_mangle)]
extern "C" fn clear_page(addr: usize) {
naked_asm!(
"li t0, {PAGE_SIZE}",
"add t0, t0, a0",
"1:",
"sd zero, 0(a0)",
"sd zero, 8(a0)",
"sd zero, 16(a0)",
"sd zero, 24(a0)",
"sd zero, 32(a0)",
"sd zero, 40(a0)",
"sd zero, 48(a0)",
"sd zero, 56(a0)",
"addi a0, a0, 64",
"bltu a0, t0, 1b",
"ret",
PAGE_SIZE = const moa_vmem::PAGE_SIZE,
);
}
#[unsafe(naked)]
#[unsafe(no_mangle)]
extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
naked_asm!(
"mv t0, a0", "li t1, 8",
"1:",
"bltu a2, t1, 2f",
"ld t2, 0(a1)",
"sd t2, 0(t0)",
"addi a1, a1, 8",
"addi t0, t0, 8",
"addi a2, a2, -8",
"j 1b",
"2:",
"beqz a2, 3f",
"4:",
"lbu t2, 0(a1)",
"sb t2, 0(t0)",
"addi a1, a1, 1",
"addi t0, t0, 1",
"addi a2, a2, -1",
"bnez a2, 4b",
"3:",
"ret",
);
}
#[unsafe(naked)]
#[unsafe(no_mangle)]
extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
naked_asm!(
"mv t0, a0",
"bgeu a1, a0, 5f", "add t0, t0, a2",
"add a1, a1, a2",
"li t1, 8",
"1:",
"bltu a2, t1, 2f",
"addi a1, a1, -8",
"addi t0, t0, -8",
"ld t2, 0(a1)",
"sd t2, 0(t0)",
"addi a2, a2, -8",
"j 1b",
"2:",
"beqz a2, 9f",
"3:",
"addi a1, a1, -1",
"addi t0, t0, -1",
"lbu t2, 0(a1)",
"sb t2, 0(t0)",
"addi a2, a2, -1",
"bnez a2, 3b",
"9:",
"ret",
"5:", "li t1, 8",
"6:",
"bltu a2, t1, 7f",
"ld t2, 0(a1)",
"sd t2, 0(t0)",
"addi a1, a1, 8",
"addi t0, t0, 8",
"addi a2, a2, -8",
"j 6b",
"7:",
"beqz a2, 8f",
"4:",
"lbu t2, 0(a1)",
"sb t2, 0(t0)",
"addi a1, a1, 1",
"addi t0, t0, 1",
"addi a2, a2, -1",
"bnez a2, 4b",
"8:",
"ret",
);
}
#[unsafe(naked)]
#[unsafe(no_mangle)]
extern "C" fn memset(dest: *mut u8, c: i32, n: usize) -> *mut u8 {
naked_asm!(
"mv t0, a0",
"andi a1, a1, 0xff", "slli t1, a1, 8",
"or a1, a1, t1",
"slli t1, a1, 16",
"or a1, a1, t1",
"slli t1, a1, 32",
"or a1, a1, t1",
"li t2, 8",
"1:",
"bltu a2, t2, 2f",
"sd a1, 0(t0)",
"addi t0, t0, 8",
"addi a2, a2, -8",
"j 1b",
"2:",
"beqz a2, 3f",
"4:",
"sb a1, 0(t0)",
"addi t0, t0, 1",
"addi a2, a2, -1",
"bnez a2, 4b",
"3:",
"ret",
);
}
#[unsafe(naked)]
#[unsafe(no_mangle)]
extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
naked_asm!(
"li t2, 8",
"1:", "bltu a2, t2, 2f",
"ld t0, 0(a0)",
"ld t1, 0(a1)",
"bne t0, t1, 2f", "addi a0, a0, 8",
"addi a1, a1, 8",
"addi a2, a2, -8",
"j 1b",
"2:", "beqz a2, 3f",
"5:",
"lbu t0, 0(a0)",
"lbu t1, 0(a1)",
"addi a0, a0, 1",
"addi a1, a1, 1",
"addi a2, a2, -1",
"bne t0, t1, 4f",
"bnez a2, 5b",
"3:",
"li a0, 0",
"ret",
"4:",
"sub a0, t0, t1", "ret",
);
}