summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_target/src/abi/call/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_target/src/abi/call/mod.rs')
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs60
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.")),
}
}