Merge pull request #462 from Patryk27/avr
This commit is contained in:
commit
f1fe94e882
3 changed files with 38 additions and 1 deletions
|
|
@ -9,6 +9,7 @@ macro_rules! sdivmod {
|
|||
$($attr:tt),* // attributes
|
||||
) => {
|
||||
intrinsics! {
|
||||
#[avr_skip]
|
||||
$(
|
||||
#[$attr]
|
||||
)*
|
||||
|
|
@ -50,6 +51,7 @@ macro_rules! sdiv {
|
|||
$($attr:tt),* // attributes
|
||||
) => {
|
||||
intrinsics! {
|
||||
#[avr_skip]
|
||||
$(
|
||||
#[$attr]
|
||||
)*
|
||||
|
|
@ -85,6 +87,7 @@ macro_rules! smod {
|
|||
$($attr:tt),* // attributes
|
||||
) => {
|
||||
intrinsics! {
|
||||
#[avr_skip]
|
||||
$(
|
||||
#[$attr]
|
||||
)*
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ intrinsics! {
|
|||
u32_div_rem(n, d).1
|
||||
}
|
||||
|
||||
#[avr_skip]
|
||||
#[maybe_use_optimized_c_shim]
|
||||
/// Returns `n / d` and sets `*rem = n % d`
|
||||
pub extern "C" fn __udivmodsi4(n: u32, d: u32, rem: Option<&mut u32>) -> u32 {
|
||||
|
|
@ -28,18 +29,21 @@ intrinsics! {
|
|||
quo_rem.0
|
||||
}
|
||||
|
||||
#[avr_skip]
|
||||
#[maybe_use_optimized_c_shim]
|
||||
/// Returns `n / d`
|
||||
pub extern "C" fn __udivdi3(n: u64, d: u64) -> u64 {
|
||||
u64_div_rem(n, d).0
|
||||
}
|
||||
|
||||
#[avr_skip]
|
||||
#[maybe_use_optimized_c_shim]
|
||||
/// Returns `n % d`
|
||||
pub extern "C" fn __umoddi3(n: u64, d: u64) -> u64 {
|
||||
u64_div_rem(n, d).1
|
||||
}
|
||||
|
||||
#[avr_skip]
|
||||
#[maybe_use_optimized_c_shim]
|
||||
/// Returns `n / d` and sets `*rem = n % d`
|
||||
pub extern "C" fn __udivmoddi4(n: u64, d: u64, rem: Option<&mut u64>) -> u64 {
|
||||
|
|
@ -77,6 +81,7 @@ intrinsics! {
|
|||
}
|
||||
}
|
||||
|
||||
#[avr_skip]
|
||||
#[win64_128bit_abi_hack]
|
||||
/// Returns `n / d` and sets `*rem = n % d`
|
||||
pub extern "C" fn __udivmodti4(n: u128, d: u128, rem: Option<&mut u128>) -> u128 {
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@ macro_rules! intrinsics {
|
|||
|
||||
$($rest:tt)*
|
||||
) => (
|
||||
|
||||
#[cfg($name = "optimized-c")]
|
||||
pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
|
||||
extern $abi {
|
||||
|
|
@ -333,6 +332,36 @@ macro_rules! intrinsics {
|
|||
intrinsics!($($rest)*);
|
||||
);
|
||||
|
||||
// For division and modulo, AVR uses a custom calling convention¹ that does
|
||||
// not match our definitions here. Ideally we would just use hand-written
|
||||
// naked functions, but that's quite a lot of code to port² - so for the
|
||||
// time being we are just ignoring the problematic functions, letting
|
||||
// avr-gcc (which is required to compile to AVR anyway) link them from
|
||||
// libgcc.
|
||||
//
|
||||
// ¹ https://gcc.gnu.org/wiki/avr-gcc (see "Exceptions to the Calling
|
||||
// Convention")
|
||||
// ² https://github.com/gcc-mirror/gcc/blob/31048012db98f5ec9c2ba537bfd850374bdd771f/libgcc/config/avr/lib1funcs.S
|
||||
(
|
||||
#[avr_skip]
|
||||
$(#[$($attr:tt)*])*
|
||||
pub extern $abi:tt fn $name:ident( $($argname:ident: $ty:ty),* ) $(-> $ret:ty)? {
|
||||
$($body:tt)*
|
||||
}
|
||||
|
||||
$($rest:tt)*
|
||||
) => (
|
||||
#[cfg(not(target_arch = "avr"))]
|
||||
intrinsics! {
|
||||
$(#[$($attr)*])*
|
||||
pub extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
|
||||
$($body)*
|
||||
}
|
||||
}
|
||||
|
||||
intrinsics!($($rest)*);
|
||||
);
|
||||
|
||||
// This is the final catch-all rule. At this point we generate an
|
||||
// intrinsic with a conditional `#[no_mangle]` directive to avoid
|
||||
// interfering with duplicate symbols and whatnot during testing.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue