diff options
Diffstat (limited to 'compiler/rustc_target/src/abi/call/mod.rs')
-rw-r--r-- | compiler/rustc_target/src/abi/call/mod.rs | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 577126a95..d2fb8c32f 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -14,7 +14,6 @@ mod m68k; mod mips; mod mips64; mod msp430; -mod nvptx; mod nvptx64; mod powerpc; mod powerpc64; @@ -27,7 +26,7 @@ mod x86; mod x86_64; mod x86_win64; -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, HashStable_Generic)] +#[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub enum PassMode { /// Ignore the argument. /// @@ -41,9 +40,10 @@ pub enum PassMode { /// /// The argument has a layout abi of `ScalarPair`. Pair(ArgAttributes, ArgAttributes), - /// Pass the argument after casting it, to either - /// a single uniform or a pair of registers. - Cast(CastTarget), + /// Pass the argument after casting it, to either a single uniform or a + /// pair of registers. The bool indicates if a `Reg::i32()` dummy argument + /// is emitted before the real argument. + Cast(Box<CastTarget>, bool), /// Pass the argument indirectly via a hidden pointer. /// The `extra_attrs` value, if any, is for the extra data (vtable or length) /// which indicates that it refers to an unsized rvalue. @@ -464,10 +464,6 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub struct ArgAbi<'a, Ty> { pub layout: TyAndLayout<'a, Ty>, - - /// Dummy argument, which is emitted before the real argument. - pub pad: Option<Reg>, - pub mode: PassMode, } @@ -487,7 +483,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { Abi::Vector { .. } => PassMode::Direct(ArgAttributes::new()), Abi::Aggregate { .. } => PassMode::Direct(ArgAttributes::new()), }; - ArgAbi { layout, pad: None, mode } + ArgAbi { layout, mode } } fn indirect_pass_mode(layout: &TyAndLayout<'a, Ty>) -> PassMode { @@ -549,11 +545,11 @@ impl<'a, Ty> ArgAbi<'a, Ty> { } pub fn cast_to<T: Into<CastTarget>>(&mut self, target: T) { - self.mode = PassMode::Cast(target.into()); + self.mode = PassMode::Cast(Box::new(target.into()), false); } - pub fn pad_with(&mut self, reg: Reg) { - self.pad = Some(reg); + pub fn cast_to_and_pad_i32<T: Into<CastTarget>>(&mut self, target: T, pad_i32: bool) { + self.mode = PassMode::Cast(Box::new(target.into()), pad_i32); } pub fn is_indirect(&self) -> bool { @@ -615,7 +611,7 @@ pub enum Conv { #[derive(PartialEq, Eq, Hash, Debug, HashStable_Generic)] pub struct FnAbi<'a, Ty> { /// The LLVM types of each argument. - pub args: Vec<ArgAbi<'a, Ty>>, + pub args: Box<[ArgAbi<'a, Ty>]>, /// LLVM return type. pub ret: ArgAbi<'a, Ty>, @@ -626,7 +622,7 @@ pub struct FnAbi<'a, Ty> { /// /// Should only be different from args.len() when c_variadic is true. /// This can be used to know whether an argument is variadic or not. - pub fixed_count: usize, + pub fixed_count: u32, pub conv: Conv, @@ -689,7 +685,14 @@ impl<'a, Ty> FnAbi<'a, Ty> { } } }, - "aarch64" => aarch64::compute_abi_info(cx, self), + "aarch64" => { + let param_policy = if cx.target_spec().is_like_osx { + aarch64::ParamExtension::ExtendTo32Bits + } else { + aarch64::ParamExtension::NoExtension + }; + aarch64::compute_abi_info(cx, self, param_policy) + } "amdgpu" => amdgpu::compute_abi_info(cx, self), "arm" => arm::compute_abi_info(cx, self), "avr" => avr::compute_abi_info(self), @@ -702,7 +705,6 @@ impl<'a, Ty> FnAbi<'a, Ty> { "msp430" => msp430::compute_abi_info(self), "sparc" => sparc::compute_abi_info(cx, self), "sparc64" => sparc64::compute_abi_info(cx, self), - "nvptx" => nvptx::compute_abi_info(self), "nvptx64" => { if cx.target_spec().adjust_abi(abi) == spec::abi::Abi::PtxKernel { nvptx64::compute_ptx_kernel_abi_info(cx, self) @@ -732,3 +734,13 @@ impl<'a, Ty> FnAbi<'a, Ty> { Ok(()) } } + +// Some types are used a lot. Make sure they don't unintentionally get bigger. +#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] +mod size_asserts { + use super::*; + use rustc_data_structures::static_assert_size; + // These are in alphabetical order, which is easy to maintain. + static_assert_size!(ArgAbi<'_, usize>, 56); + static_assert_size!(FnAbi<'_, usize>, 80); +} |