rustc_target/callconv/avr.rs
1//! LLVM-frontend specific AVR calling convention implementation.
2//!
3//! # Current calling convention ABI
4//!
5//! Inherited from Clang's `clang::DefaultABIInfo` implementation - self described
6//! as
7//!
8//! > the default implementation for ABI specific details. This implementation
9//! > provides information which results in
10//! > self-consistent and sensible LLVM IR generation, but does not
11//! > conform to any particular ABI.
12//! >
13//! > - Doxygen Documentation of `clang::DefaultABIInfo`
14//!
15//! This calling convention may not match AVR-GCC in all cases.
16//!
17//! In the future, an AVR-GCC compatible argument classification ABI should be
18//! adopted in both Rust and Clang.
19//!
20//! *NOTE*: Currently, this module implements the same calling convention
21//! that clang with AVR currently does - the default, simple, unspecialized
22//! ABI implementation available to all targets. This ABI is not
23//! binary-compatible with AVR-GCC. Once LLVM [PR46140](https://bugs.llvm.org/show_bug.cgi?id=46140)
24//! is completed, this module should be updated to match so that both Clang
25//! and Rust emit code to the same AVR-GCC compatible ABI.
26//!
27//! In particular, both Clang and Rust may not have the same semantics
28//! when promoting arguments to indirect references as AVR-GCC. It is important
29//! to note that the core AVR ABI implementation within LLVM itself is ABI
30//! compatible with AVR-GCC - Rust and AVR-GCC only differ in the small amount
31//! of compiler frontend specific calling convention logic implemented here.
32
33use rustc_abi::TyAbiInterface;
34
35use crate::callconv::{ArgAbi, FnAbi};
36
37fn classify_ret_ty<Ty>(ret: &mut ArgAbi<'_, Ty>) {
38 if ret.layout.is_aggregate() {
39 ret.make_indirect();
40 }
41}
42
43fn classify_arg_ty<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
44where
45 Ty: TyAbiInterface<'a, C> + Copy,
46{
47 if arg.layout.pass_indirectly_in_non_rustic_abis(cx) {
48 arg.make_indirect();
49 return;
50 }
51 if arg.layout.is_aggregate() {
52 arg.make_indirect();
53 }
54}
55
56pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fty: &mut FnAbi<'a, Ty>)
57where
58 Ty: TyAbiInterface<'a, C> + Copy,
59{
60 if !fty.ret.is_ignore() {
61 classify_ret_ty(&mut fty.ret);
62 }
63
64 for arg in fty.args.iter_mut() {
65 if arg.is_ignore() {
66 continue;
67 }
68
69 classify_arg_ty(cx, arg);
70 }
71}