use core::{mem, slice, str};
use drone_core::ffi::{c_char, c_void};
use drone_micropython_raw::{
gc_collect_end, gc_collect_root, gc_collect_start, mp_uint_t,
};
static mut STACK_TOP: usize = 0;
#[doc(hidden)]
#[no_mangle]
pub unsafe extern "C" fn mp_hal_stdout_tx_strn(
s: *const c_char,
len: mp_uint_t,
) {
print!(
"{}",
str::from_utf8(slice::from_raw_parts(s, len as usize)).unwrap()
);
}
#[doc(hidden)]
#[no_mangle]
pub extern "C" fn gc_collect() {
unsafe {
gc_collect_start();
let mut regs: [usize; 10] = mem::uninitialized();
let sp: usize;
asm!("
str r4, [r0], #4
str r5, [r0], #4
str r6, [r0], #4
str r7, [r0], #4
str r8, [r0], #4
str r9, [r0], #4
str r10, [r0], #4
str r11, [r0], #4
str r12, [r0], #4
str r13, [r0], #4
mov r0, sp
" : "={r0}"(sp)
: "{r0}"(&mut regs)
: "memory"
: "volatile");
gc_collect_root(
sp as *mut *mut c_void,
(STACK_TOP - sp) / mem::size_of::<usize>(),
);
gc_collect_end();
}
}
pub(crate) fn init_stack() {
unsafe {
asm!("str sp, [$0]" :: "r"(&mut STACK_TOP) : "memory" : "volatile");
}
}