Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit d39b441

Browse files
committed
Start using ArgAbi
1 parent ae6daf7 commit d39b441

File tree

1 file changed

+53
-27
lines changed

1 file changed

+53
-27
lines changed

src/abi/pass_mode.rs

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use crate::prelude::*;
44

5+
use rustc_target::abi::call::{ArgAbi, ArgAttributes, PassMode as RustcPassMode};
56
pub(super) use EmptySinglePair::*;
67

78
#[derive(Copy, Clone, Debug)]
@@ -83,39 +84,64 @@ pub(super) fn get_pass_mode<'tcx>(tcx: TyCtxt<'tcx>, layout: TyAndLayout<'tcx>)
8384
// WARNING zst arguments must never be passed, as that will break CastKind::ClosureFnPointer
8485
PassMode::NoPass
8586
} else {
86-
match &layout.abi {
87-
Abi::Uninhabited => PassMode::NoPass,
88-
Abi::Scalar(scalar) => PassMode::ByVal(scalar_to_clif_type(tcx, scalar.clone())),
89-
Abi::ScalarPair(a, b) => {
90-
let a = scalar_to_clif_type(tcx, a.clone());
91-
let b = scalar_to_clif_type(tcx, b.clone());
92-
if a == types::I128 && b == types::I128 {
93-
// Returning (i128, i128) by-val-pair would take 4 regs, while only 3 are
94-
// available on x86_64. Cranelift gets confused when too many return params
95-
// are used.
96-
PassMode::ByRef {
97-
size: Some(layout.size),
87+
let arg_abi = ArgAbi::new(&tcx, layout, |_, _, _| ArgAttributes::new());
88+
match arg_abi.mode {
89+
RustcPassMode::Ignore => PassMode::NoPass,
90+
RustcPassMode::Direct(_) => match &arg_abi.layout.abi {
91+
Abi::Scalar(scalar) => PassMode::ByVal(scalar_to_clif_type(tcx, scalar.clone())),
92+
// FIXME implement Vector Abi in a cg_llvm compatible way
93+
Abi::Vector { .. } => {
94+
if let Some(vector_ty) = crate::intrinsics::clif_vector_type(tcx, arg_abi.layout) {
95+
PassMode::ByVal(vector_ty)
96+
} else {
97+
PassMode::ByRef {
98+
size: Some(arg_abi.layout.size),
99+
}
98100
}
99-
} else {
100-
PassMode::ByValPair(a, b)
101101
}
102-
}
103-
104-
// FIXME implement Vector Abi in a cg_llvm compatible way
105-
Abi::Vector { .. } => {
106-
if let Some(vector_ty) = crate::intrinsics::clif_vector_type(tcx, layout) {
107-
PassMode::ByVal(vector_ty)
108-
} else {
109-
PassMode::ByRef {
110-
size: Some(layout.size),
102+
_ => unreachable!("{:?}", arg_abi.layout.abi)
103+
},
104+
RustcPassMode::Pair(_, _) => match &arg_abi.layout.abi {
105+
Abi::ScalarPair(a, b) => {
106+
let a = scalar_to_clif_type(tcx, a.clone());
107+
let b = scalar_to_clif_type(tcx, b.clone());
108+
if a == types::I128 && b == types::I128 {
109+
// Returning (i128, i128) by-val-pair would take 4 regs, while only 3 are
110+
// available on x86_64. Cranelift gets confused when too many return params
111+
// are used.
112+
PassMode::ByRef {
113+
size: Some(arg_abi.layout.size),
114+
}
115+
} else {
116+
PassMode::ByValPair(a, b)
111117
}
112118
}
119+
_ => unreachable!("{:?}", arg_abi.layout.abi)
120+
},
121+
RustcPassMode::Cast(_) | RustcPassMode::Indirect {
122+
attrs: _,
123+
extra_attrs: None,
124+
on_stack: false,
125+
} => PassMode::ByRef {
126+
size: Some(arg_abi.layout.size),
127+
},
128+
RustcPassMode::Indirect {
129+
attrs: _,
130+
extra_attrs,
131+
on_stack: true,
132+
} => {
133+
assert!(extra_attrs.is_none());
134+
PassMode::ByRef {
135+
size: Some(arg_abi.layout.size)
136+
}
113137
}
114-
115-
Abi::Aggregate { sized: true } => PassMode::ByRef {
116-
size: Some(layout.size),
138+
RustcPassMode::Indirect {
139+
attrs: _,
140+
extra_attrs: Some(_),
141+
on_stack: false,
142+
} => PassMode::ByRef {
143+
size: None,
117144
},
118-
Abi::Aggregate { sized: false } => PassMode::ByRef { size: None },
119145
}
120146
}
121147
}

0 commit comments

Comments
 (0)