Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_cranelift/src/abi/pass_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ impl<'tcx> ArgAbiExt<'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
}
_ => unreachable!("{:?}", self.layout.backend_repr),
},
PassMode::Cast { ref cast, pad_i32 } => {
assert!(!pad_i32, "padding support not yet implemented");
PassMode::Cast { ref cast, pad_i32_count } => {
assert_eq!(pad_i32_count, 0, "padding support not yet implemented");
cast_target_to_abi_params(cast).into_iter().map(|(_, param)| param).collect()
}
PassMode::Indirect { attrs, meta_attrs: None, on_stack } => {
Expand Down
12 changes: 7 additions & 5 deletions compiler/rustc_codegen_gcc/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,13 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
));
continue;
}
PassMode::Cast { ref cast, pad_i32 } => {
// add padding
if pad_i32 {
argument_tys.push(Reg::i32().gcc_type(cx));
}
PassMode::Cast { ref cast, pad_i32_count } => {
// Add padding.
argument_tys.extend(std::iter::repeat_n(
Reg::i32().gcc_type(cx),
usize::from(pad_i32_count),
));

let ty = cast.gcc_type(cx);
apply_attrs(ty, &cast.attrs, argument_tys.len())
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_gcc/src/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ impl<'gcc, 'tcx> LayoutTypeCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
fn_abi.ptr_to_gcc_type(self)
}

fn reg_backend_type(&self, _ty: &Reg) -> Type<'gcc> {
unimplemented!();
fn reg_backend_type(&self, ty: &Reg) -> Type<'gcc> {
ty.gcc_type(self)
}
Comment thread
bjorn3 marked this conversation as resolved.

fn fn_decl_backend_type(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Type<'gcc> {
Expand Down
28 changes: 15 additions & 13 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
PassMode::Indirect { attrs: _, meta_attrs: Some(_), on_stack: _ } => {
bug!("unsized `ArgAbi` cannot be stored");
}
PassMode::Cast { cast, pad_i32: _ } => {
PassMode::Cast { cast, pad_i32_count: _ } => {
// The ABI mandates that the value is passed as a different struct representation.
// Spill and reload it from the stack to convert from the ABI representation to
// the Rust representation.
Expand Down Expand Up @@ -366,7 +366,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
let llreturn_ty = match &self.ret.mode {
PassMode::Ignore => cx.type_void(),
PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_llvm_type(cx),
PassMode::Cast { cast, pad_i32: _ } => cast.llvm_type(cx),
PassMode::Cast { cast, pad_i32_count: _ } => cast.llvm_type(cx),
PassMode::Indirect { .. } => {
llargument_tys.push(cx.type_ptr());
cx.type_void()
Expand Down Expand Up @@ -405,11 +405,13 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
continue;
}
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: _ } => cx.type_ptr(),
PassMode::Cast { cast, pad_i32 } => {
// add padding
if *pad_i32 {
llargument_tys.push(Reg::i32().llvm_type(cx));
}
PassMode::Cast { cast, pad_i32_count } => {
// Add padding.
llargument_tys.extend(std::iter::repeat_n(
Reg::i32().llvm_type(cx),
usize::from(*pad_i32_count),
));

// Compute the LLVM type we use for this function from the cast type.
// We assume here that ABI-compatible Rust types have the same cast type.
cast.llvm_type(cx)
Expand Down Expand Up @@ -511,7 +513,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
);
}
}
PassMode::Cast { cast, pad_i32: _ } => {
PassMode::Cast { cast, pad_i32_count: _ } => {
cast.attrs.apply_attrs_to_llfn(llvm::AttributePlace::ReturnValue, cx, llfn);
}
_ => {}
Expand Down Expand Up @@ -580,8 +582,8 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
apply_range_attr(llvm::AttributePlace::Argument(ii), scalar_b);
}
}
PassMode::Cast { cast, pad_i32 } => {
if *pad_i32 {
PassMode::Cast { cast, pad_i32_count } => {
for _ in 0..*pad_i32_count {
apply(&ArgAttributes::new());
}
apply(&cast.attrs);
Expand Down Expand Up @@ -630,7 +632,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
);
attributes::apply_to_callsite(callsite, llvm::AttributePlace::Argument(i), &[sret]);
}
PassMode::Cast { cast, pad_i32: _ } => {
PassMode::Cast { cast, pad_i32_count: _ } => {
cast.attrs.apply_attrs_to_callsite(
llvm::AttributePlace::ReturnValue,
bx.cx,
Expand Down Expand Up @@ -666,8 +668,8 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
apply(bx.cx, a);
apply(bx.cx, b);
}
PassMode::Cast { cast, pad_i32 } => {
if *pad_i32 {
PassMode::Cast { cast, pad_i32_count } => {
for _ in 0..*pad_i32_count {
apply(bx.cx, &ArgAttributes::new());
}
apply(bx.cx, &cast.attrs);
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_codegen_ssa/src/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,7 +588,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}

PassMode::Cast { cast: cast_ty, pad_i32: _ } => {
PassMode::Cast { cast: cast_ty, pad_i32_count: _ } => {
let op = match self.locals[mir::RETURN_PLACE] {
LocalRef::Operand(op) => op,
LocalRef::PendingOperand => bug!("use of return before def"),
Expand Down Expand Up @@ -1936,9 +1936,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
) {
match arg.mode {
PassMode::Ignore => return,
PassMode::Cast { pad_i32: true, .. } => {
PassMode::Cast { pad_i32_count, .. } => {
// Fill padding with undef value, where applicable.
llargs.push(bx.const_undef(bx.reg_backend_type(&Reg::i32())));
let undef = bx.const_undef(bx.reg_backend_type(&Reg::i32()));
llargs.extend(std::iter::repeat_n(undef, usize::from(pad_i32_count)));
}
PassMode::Pair(..) => match op.val {
Pair(a, b) => {
Expand Down Expand Up @@ -2025,7 +2026,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {

if by_ref && !arg.is_indirect() {
// Have to load the argument, maybe while casting it.
if let PassMode::Cast { cast, pad_i32: _ } = &arg.mode {
if let PassMode::Cast { cast, pad_i32_count: _ } = &arg.mode {
// The ABI mandates that the value is passed as a different struct representation.
// Spill and reload it from the stack to convert from the Rust representation to
// the ABI representation.
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_ssa/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,8 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
for i in 0..tupled_arg_tys.len() {
let arg = &fx.fn_abi.args[idx];
idx += 1;
if let PassMode::Cast { pad_i32: true, .. } = arg.mode {
llarg_idx += 1;
if let PassMode::Cast { pad_i32_count, .. } = arg.mode {
llarg_idx += usize::from(pad_i32_count);
}
let pr_field = place.project_field(bx, i);
bx.store_fn_arg(arg, &mut llarg_idx, pr_field);
Expand All @@ -529,8 +529,8 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(

let arg = &fx.fn_abi.args[idx];
idx += 1;
if let PassMode::Cast { pad_i32: true, .. } = arg.mode {
llarg_idx += 1;
if let PassMode::Cast { pad_i32_count, .. } = arg.mode {
llarg_idx += usize::from(pad_i32_count);
}

if !memory_locals.contains(local) {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/mir/naked_asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,9 +472,9 @@ fn wasm_type<'tcx>(signature: &mut String, arg_abi: &ArgAbi<'_, Ty<'tcx>>, ptr_t
}
other => unreachable!("{other:?}"),
},
PassMode::Cast { pad_i32, ref cast } => {
PassMode::Cast { pad_i32_count, ref cast } => {
// For wasm, Cast is used for single-field primitive wrappers like `struct Wrapper(i64);`
assert!(!pad_i32, "not currently used by wasm calling convention");
assert_eq!(pad_i32_count, 0, "not currently used by wasm calling convention");
assert!(cast.prefix.is_empty(), "no prefix");
assert_eq!(cast.rest.total, arg_abi.layout.size, "single item");

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ enum UsesVectorRegisters {
fn passes_vectors_by_value(mode: &PassMode, repr: &BackendRepr) -> UsesVectorRegisters {
match mode {
PassMode::Ignore | PassMode::Indirect { .. } => UsesVectorRegisters::No,
PassMode::Cast { pad_i32: _, cast }
PassMode::Cast { pad_i32_count: _, cast }
if cast.prefix.iter().any(|x| matches!(x.kind, RegKind::Vector { .. }))
|| matches!(cast.rest.unit.kind, RegKind::Vector { .. }) =>
{
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_public/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub enum PassMode {
/// The argument has a layout abi of `ScalarPair`.
Pair(Opaque, Opaque),
/// Pass the argument after casting it.
Cast { pad_i32: bool, cast: Opaque },
Cast { pad_i32_count: u8, cast: Opaque },
/// Pass the argument indirectly via a hidden pointer.
Indirect { attrs: Opaque, meta_attrs: Opaque, on_stack: bool },
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_public/src/unstable/convert/stable/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ impl<'tcx> Stable<'tcx> for callconv::PassMode {
callconv::PassMode::Pair(first, second) => {
PassMode::Pair(opaque(first), opaque(second))
}
callconv::PassMode::Cast { pad_i32, cast } => {
PassMode::Cast { pad_i32: *pad_i32, cast: opaque(cast) }
callconv::PassMode::Cast { pad_i32_count, cast } => {
PassMode::Cast { pad_i32_count: *pad_i32_count, cast: opaque(cast) }
}
callconv::PassMode::Indirect { attrs, meta_attrs, on_stack } => PassMode::Indirect {
attrs: opaque(attrs),
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/callconv/mips.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ where

let size = arg.layout.size;
if arg.layout.is_aggregate() {
let pad_i32 = !offset.is_aligned(align);
let pad_i32 = u8::from(!offset.is_aligned(align));
arg.cast_to_and_pad_i32(Uniform::new(Reg::i32(), size), pad_i32);
} else {
arg.extend_integer_width_to(32);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/callconv/mips64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ where

// Detect need for padding
let align = Ord::clamp(arg.layout.align.abi, dl.i64_align, dl.i128_align);
let pad_i32 = !offset.is_aligned(align);
let pad_i32 = u8::from(!offset.is_aligned(align));

if !arg.layout.is_aggregate() {
extend_integer_width_mips(arg, 64);
Expand Down
17 changes: 9 additions & 8 deletions compiler/rustc_target/src/callconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ pub enum PassMode {
Pair(ArgAttributes, ArgAttributes),
/// Pass the argument after casting it. See the `CastTarget` docs for details.
///
/// `pad_i32` indicates if a `Reg::i32()` dummy argument is emitted before the real argument.
Cast { pad_i32: bool, cast: Box<CastTarget> },
/// `pad_i32` indicates how many `Reg::i32()` dummy arguments are emitted before the real
/// argument.
Cast { pad_i32_count: u8, cast: Box<CastTarget> },
/// Pass the argument indirectly via a hidden pointer.
///
/// The `meta_attrs` value, if any, is for the metadata (vtable or length) of an unsized
Expand Down Expand Up @@ -84,8 +85,8 @@ impl PassMode {
(PassMode::Direct(a1), PassMode::Direct(a2)) => a1.eq_abi(a2),
(PassMode::Pair(a1, b1), PassMode::Pair(a2, b2)) => a1.eq_abi(a2) && b1.eq_abi(b2),
(
PassMode::Cast { cast: c1, pad_i32: pad1 },
PassMode::Cast { cast: c2, pad_i32: pad2 },
PassMode::Cast { cast: c1, pad_i32_count: pad1 },
PassMode::Cast { cast: c2, pad_i32_count: pad2 },
) => c1.eq_abi(c2) && pad1 == pad2,
(
PassMode::Indirect { attrs: a1, meta_attrs: None, on_stack: s1 },
Expand Down Expand Up @@ -507,12 +508,12 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
}

pub fn cast_to<T: Into<CastTarget>>(&mut self, target: T) {
self.mode = PassMode::Cast { cast: Box::new(target.into()), pad_i32: false };
self.mode = PassMode::Cast { cast: Box::new(target.into()), pad_i32_count: 0 };
}

pub fn cast_to_with_attrs<T: Into<CastTarget>>(&mut self, target: T, attrs: ArgAttributes) {
self.mode =
PassMode::Cast { cast: Box::new(target.into().with_attrs(attrs)), pad_i32: false };
PassMode::Cast { cast: Box::new(target.into().with_attrs(attrs)), pad_i32_count: 0 };
}

/// Cast to `target`, forwarding `NoUndef` only when the layout provably has no uninit
Expand All @@ -535,8 +536,8 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
self.cast_to_with_attrs(target, attr.into());
}

pub fn cast_to_and_pad_i32<T: Into<CastTarget>>(&mut self, target: T, pad_i32: bool) {
self.mode = PassMode::Cast { cast: Box::new(target.into()), pad_i32 };
pub fn cast_to_and_pad_i32<T: Into<CastTarget>>(&mut self, target: T, pad_i32_count: u8) {
self.mode = PassMode::Cast { cast: Box::new(target.into()), pad_i32_count };
}

pub fn is_indirect(&self) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/callconv/sparc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ where
let align = arg.layout.align.abi.max(dl.i32_align).min(dl.i64_align);

if arg.layout.is_aggregate() {
let pad_i32 = !offset.is_aligned(align);
let pad_i32 = u8::from(!offset.is_aligned(align));
arg.cast_to_and_pad_i32(Uniform::new(Reg::i32(), size), pad_i32);
} else {
arg.extend_integer_width_to(32);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_target/src/callconv/sparc64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ fn classify_arg<'a, Ty, C>(
_ => CastTarget::prefixed(regs, Uniform::new(Reg::i8(), Size::ZERO)),
};

arg.cast_to_and_pad_i32(cast_target.with_attrs(attrs.into()), pad);
arg.cast_to_and_pad_i32(cast_target.with_attrs(attrs.into()), u8::from(pad));
}

pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/abi/pass-indirectly-attr.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ error: fn_abi_of(extern_rust) = FnAbi {
},
},
mode: Cast {
pad_i32: false,
pad_i32_count: 0,
cast: CastTarget {
prefix: [],
rest_offset: None,
Expand Down
Loading