diff options
Diffstat (limited to 'compiler/rustc_target/src/abi/call/mod.rs')
-rw-r--r-- | compiler/rustc_target/src/abi/call/mod.rs | 60 |
1 files changed, 48 insertions, 12 deletions
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index c4abf6f4b..8fab13d5d 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -9,6 +9,7 @@ mod amdgpu; mod arm; mod avr; mod bpf; +mod csky; mod hexagon; mod loongarch; mod m68k; @@ -494,9 +495,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> { .set(ArgAttribute::NonNull) .set(ArgAttribute::NoUndef); attrs.pointee_size = layout.size; - // FIXME(eddyb) We should be doing this, but at least on - // i686-pc-windows-msvc, it results in wrong stack offsets. - // attrs.pointee_align = Some(layout.align.abi); + attrs.pointee_align = Some(layout.align.abi); let extra_attrs = layout.is_unsized().then_some(ArgAttributes::new()); @@ -513,11 +512,19 @@ impl<'a, Ty> ArgAbi<'a, Ty> { self.mode = Self::indirect_pass_mode(&self.layout); } - pub fn make_indirect_byval(&mut self) { + pub fn make_indirect_byval(&mut self, byval_align: Option<Align>) { self.make_indirect(); match self.mode { - PassMode::Indirect { attrs: _, extra_attrs: _, ref mut on_stack } => { + PassMode::Indirect { ref mut attrs, extra_attrs: _, ref mut on_stack } => { *on_stack = true; + + // Some platforms, like 32-bit x86, change the alignment of the type when passing + // `byval`. Account for that. + if let Some(byval_align) = byval_align { + // On all targets with byval align this is currently true, so let's assert it. + debug_assert!(byval_align >= Align::from_bytes(4).unwrap()); + attrs.pointee_align = Some(byval_align); + } } _ => unreachable!(), } @@ -597,6 +604,25 @@ pub enum Conv { AmdGpuKernel, AvrInterrupt, AvrNonBlockingInterrupt, + + RiscvInterrupt { + kind: RiscvInterruptKind, + }, +} + +#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable_Generic)] +pub enum RiscvInterruptKind { + Machine, + Supervisor, +} + +impl RiscvInterruptKind { + pub fn as_str(&self) -> &'static str { + match self { + Self::Machine => "machine", + Self::Supervisor => "supervisor", + } + } } /// Metadata describing how the arguments to a native function @@ -644,7 +670,8 @@ impl<'a, Ty> FnAbi<'a, Ty> { { if abi == spec::abi::Abi::X86Interrupt { if let Some(arg) = self.args.first_mut() { - arg.make_indirect_byval(); + // FIXME(pcwalton): This probably should use the x86 `byval` ABI... + arg.make_indirect_byval(None); } return Ok(()); } @@ -672,20 +699,23 @@ impl<'a, Ty> FnAbi<'a, Ty> { } }, "aarch64" => { - let param_policy = if cx.target_spec().is_like_osx { - aarch64::ParamExtension::ExtendTo32Bits + let kind = if cx.target_spec().is_like_osx { + aarch64::AbiKind::DarwinPCS + } else if cx.target_spec().is_like_windows { + aarch64::AbiKind::Win64 } else { - aarch64::ParamExtension::NoExtension + aarch64::AbiKind::AAPCS }; - aarch64::compute_abi_info(cx, self, param_policy) + aarch64::compute_abi_info(cx, self, kind) } "amdgpu" => amdgpu::compute_abi_info(cx, self), "arm" => arm::compute_abi_info(cx, self), "avr" => avr::compute_abi_info(self), "loongarch64" => loongarch::compute_abi_info(cx, self), "m68k" => m68k::compute_abi_info(self), - "mips" => mips::compute_abi_info(cx, self), - "mips64" => mips64::compute_abi_info(cx, self), + "csky" => csky::compute_abi_info(self), + "mips" | "mips32r6" => mips::compute_abi_info(cx, self), + "mips64" | "mips64r6" => mips64::compute_abi_info(cx, self), "powerpc" => powerpc::compute_abi_info(self), "powerpc64" => powerpc64::compute_abi_info(cx, self), "s390x" => s390x::compute_abi_info(cx, self), @@ -744,6 +774,12 @@ impl FromStr for Conv { "AmdGpuKernel" => Ok(Conv::AmdGpuKernel), "AvrInterrupt" => Ok(Conv::AvrInterrupt), "AvrNonBlockingInterrupt" => Ok(Conv::AvrNonBlockingInterrupt), + "RiscvInterrupt(machine)" => { + Ok(Conv::RiscvInterrupt { kind: RiscvInterruptKind::Machine }) + } + "RiscvInterrupt(supervisor)" => { + Ok(Conv::RiscvInterrupt { kind: RiscvInterruptKind::Supervisor }) + } _ => Err(format!("'{s}' is not a valid value for entry function call convention.")), } } |