use core::mem;
cfg_if::cfg_if! {
if #[cfg(any(
target_vendor = "apple",
all(windows, target_arch = "x86"),
))] {
macro_rules! asm_mangle {
($name:literal) => { concat!("_", $name) };
}
} else {
macro_rules! asm_mangle {
($name:literal) => { $name };
}
}
}
cfg_if::cfg_if! {
if #[cfg(any(windows, target_os = "uefi"))] {
macro_rules! asm_function_begin {
($name:literal) => {
concat!(
".globl ", asm_mangle!($name), "\n",
".def ", asm_mangle!($name), "\n",
".scl 2\n",
".type 32\n",
".endef ", asm_mangle!($name), "\n",
asm_mangle!($name), ":\n",
)
};
}
macro_rules! asm_function_alt_entry {
($name:literal) => {
asm_function_begin!($name)
};
}
macro_rules! asm_function_end {
($name:literal) => {
""
};
}
#[allow(unused_macros)]
macro_rules! cfi_signal_frame {
() => { ".cfi_signal_frame" }
}
} else if #[cfg(target_vendor = "apple")] {
macro_rules! asm_function_begin {
($name:literal) => {
concat!(
".globl ", asm_mangle!($name), "\n",
".private_extern ", asm_mangle!($name), "\n",
asm_mangle!($name), ":\n",
)
};
}
macro_rules! asm_function_alt_entry {
($name:literal) => {
concat!(
".alt_entry ", asm_mangle!($name), "\n",
asm_function_begin!($name),
)
};
}
macro_rules! asm_function_end {
($name:literal) => {
""
};
}
macro_rules! cfi_signal_frame {
() => { "" }
}
} else {
#[cfg(not(target_arch = "arm"))]
macro_rules! asm_function_type {
() => { "@function" }
}
#[cfg(target_arch = "arm")]
macro_rules! asm_function_type {
() => { "%function" }
}
macro_rules! asm_function_begin {
($name:literal) => {
concat!(
".globl ", asm_mangle!($name), "\n",
".type ", asm_mangle!($name), ", ", asm_function_type!(), "\n",
asm_mangle!($name), ":\n",
)
};
}
macro_rules! asm_function_alt_entry {
($name:literal) => {
asm_function_begin!($name)
};
}
macro_rules! asm_function_end {
($name:literal) => {
concat!(".size ", asm_mangle!($name), ", . - ", asm_mangle!($name), "\n")
};
}
macro_rules! cfi_signal_frame {
() => { ".cfi_signal_frame" }
}
}
}
#[inline]
unsafe fn allocate_obj_on_stack<T>(sp: &mut usize, sp_offset: usize, obj: T) {
assert!(mem::size_of::<T>() <= 1024, "type is too big to transfer");
if mem::align_of::<T>() > STACK_ALIGNMENT {
*sp -= mem::size_of::<T>();
*sp &= !(mem::align_of::<T>() - 1);
} else {
let total_size = sp_offset + mem::size_of::<T>();
let align_offset = total_size % STACK_ALIGNMENT;
if align_offset != 0 {
*sp -= STACK_ALIGNMENT - align_offset;
}
*sp -= mem::size_of::<T>();
}
(*sp as *mut T).write(obj);
debug_assert_eq!(*sp % STACK_ALIGNMENT, 0);
}
cfg_if::cfg_if! {
if #[cfg(all(target_arch = "x86_64", not(windows)))] {
mod x86_64;
pub use self::x86_64::*;
} else if #[cfg(all(target_arch = "x86_64", windows))] {
mod x86_64_windows;
pub use self::x86_64_windows::*;
} else if #[cfg(all(target_arch = "x86", not(windows)))] {
mod x86;
pub use self::x86::*;
} else if #[cfg(all(target_arch = "x86", windows))] {
mod x86_windows;
pub use self::x86_windows::*;
} else if #[cfg(all(target_arch = "aarch64", not(windows)))] {
mod aarch64;
pub use self::aarch64::*;
} else if #[cfg(all(target_arch = "arm", not(any(windows, target_vendor = "apple"))))] {
mod arm;
pub use self::arm::*;
} else if #[cfg(all(any(target_arch = "riscv64", target_arch = "riscv32"), not(windows)))] {
mod riscv;
pub use self::riscv::*;
} else if #[cfg(all(target_arch = "loongarch64", not(windows)))] {
mod loongarch64;
pub use self::loongarch64::*;
} else if #[cfg(all(target_arch = "powerpc64", target_abi = "elfv2", not(windows)))] {
mod powerpc64;
pub use self::powerpc64::*;
} else {
compile_error!("Unsupported target");
}
}
#[inline]
unsafe fn push(sp: &mut usize, val: Option<StackWord>) {
*sp -= mem::size_of::<StackWord>();
if let Some(val) = val {
*(*sp as *mut StackWord) = val;
}
}