| //! LLVM-frontend specific AVR calling convention implementation. | |
| //! | |
| //! # Current calling convention ABI | |
| //! | |
| //! Inherited from Clang's `clang::DefaultABIInfo` implementation - self described | |
| //! as | |
| //! | |
| //! > the default implementation for ABI specific details. This implementation | |
| //! > provides information which results in | |
| //! > self-consistent and sensible LLVM IR generation, but does not | |
| //! > conform to any particular ABI. | |
| //! > | |
| //! > - Doxygen Documentation of `clang::DefaultABIInfo` | |
| //! | |
| //! This calling convention may not match AVR-GCC in all cases. | |
| //! | |
| //! In the future, an AVR-GCC compatible argument classification ABI should be | |
| //! adopted in both Rust and Clang. | |
| //! | |
| //! *NOTE*: Currently, this module implements the same calling convention | |
| //! that clang with AVR currently does - the default, simple, unspecialized | |
| //! ABI implementation available to all targets. This ABI is not | |
| //! binary-compatible with AVR-GCC. Once LLVM [PR46140](https://bugs.llvm.org/show_bug.cgi?id=46140) | |
| //! is completed, this module should be updated to match so that both Clang | |
| //! and Rust emit code to the same AVR-GCC compatible ABI. | |
| //! | |
| //! In particular, both Clang and Rust may not have the same semantics | |
| //! when promoting arguments to indirect references as AVR-GCC. It is important | |
| //! to note that the core AVR ABI implementation within LLVM itself is ABI | |
| //! compatible with AVR-GCC - Rust and AVR-GCC only differ in the small amount | |
| //! of compiler frontend specific calling convention logic implemented here. | |
| use rustc_abi::TyAbiInterface; | |
| use crate::callconv::{ArgAbi, FnAbi}; | |
| fn classify_ret_ty<Ty>(ret: &mut ArgAbi<'_, Ty>) { | |
| if ret.layout.is_aggregate() { | |
| ret.make_indirect(); | |
| } | |
| } | |
| fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) | |
| where | |
| Ty: TyAbiInterface<'a, C> + Copy, | |
| { | |
| if arg.layout.pass_indirectly_in_non_rustic_abis(cx) { | |
| arg.make_indirect(); | |
| return; | |
| } | |
| if arg.layout.is_aggregate() { | |
| arg.make_indirect(); | |
| } | |
| } | |
| pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnAbi<'a, Ty>) | |
| where | |
| Ty: TyAbiInterface<'a, C> + Copy, | |
| { | |
| if !fty.ret.is_ignore() { | |
| classify_ret_ty(&mut fty.ret); | |
| } | |
| for arg in fty.args.iter_mut() { | |
| if arg.is_ignore() { | |
| continue; | |
| } | |
| classify_arg_ty(cx, arg); | |
| } | |
| } |