Skip to content

Commit c1a08a5

Browse files
committed
Allocate registers for padding
Closes #45662.
1 parent 83ba46f commit c1a08a5

File tree

1 file changed

+38
-11
lines changed

1 file changed

+38
-11
lines changed

src/librustc_trans/cabi_x86_64.rs

+38-11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,25 @@ enum Class {
2424
SseUp
2525
}
2626

27+
impl Class {
28+
pub fn from_layout<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, layout: TyLayout<'tcx>) -> Self {
29+
match layout.abi {
30+
layout::Abi::Scalar(ref scalar) => match scalar.value {
31+
layout::Int(..) |
32+
layout::Pointer => Class::Int,
33+
layout::F32 |
34+
layout::F64 => Class::Sse,
35+
},
36+
layout::Abi::ScalarPair(..) | layout::Abi::Aggregate { .. } => {
37+
let last_idx = layout.fields.count().checked_sub(1).unwrap_or(0);
38+
Class::from_layout(ccx, layout.field(ccx, last_idx))
39+
}
40+
layout::Abi::Vector{ .. } => Class::SseUp,
41+
layout::Abi::Uninhabited => unreachable!(),
42+
}
43+
}
44+
}
45+
2746
#[derive(Clone, Copy, Debug)]
2847
struct Memory;
2948

@@ -64,17 +83,12 @@ fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>)
6483
return Ok(());
6584
}
6685

67-
match layout.abi {
68-
layout::Abi::Uninhabited => {}
86+
let mut offset = match layout.abi {
87+
layout::Abi::Uninhabited => return Ok(()),
6988

7089
layout::Abi::Scalar(ref scalar) => {
71-
let reg = match scalar.value {
72-
layout::Int(..) |
73-
layout::Pointer => Class::Int,
74-
layout::F32 |
75-
layout::F64 => Class::Sse
76-
};
77-
unify(cls, off, reg);
90+
unify(cls, off, Class::from_layout(ccx, layout));
91+
off + scalar.value.size(ccx)
7892
}
7993

8094
layout::Abi::Vector { ref element, count } => {
@@ -83,26 +97,39 @@ fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>)
8397
// everything after the first one is the upper
8498
// half of a register.
8599
let stride = element.value.size(ccx);
100+
let mut field_off = off;
86101
for i in 1..count {
87-
let field_off = off + stride * i;
102+
field_off = off + stride * i;
88103
unify(cls, field_off, Class::SseUp);
89104
}
105+
field_off + stride
90106
}
91107

92108
layout::Abi::ScalarPair(..) |
93109
layout::Abi::Aggregate { .. } => {
94110
match layout.variants {
95111
layout::Variants::Single { .. } => {
112+
let mut field_off = off;
113+
let mut last_size = Size::from_bytes(0);
96114
for i in 0..layout.fields.count() {
97-
let field_off = off + layout.fields.offset(i);
115+
field_off = off + layout.fields.offset(i);
98116
classify(ccx, layout.field(ccx, i), cls, field_off)?;
117+
last_size = layout.field(ccx, i).size;
99118
}
119+
field_off + last_size
100120
}
101121
layout::Variants::Tagged { .. } |
102122
layout::Variants::NicheFilling { .. } => return Err(Memory),
103123
}
104124
}
105125

126+
};
127+
128+
// Add registers for padding.
129+
let reg = Class::from_layout(ccx, layout);
130+
while offset < layout.size {
131+
unify(cls, offset, reg);
132+
offset = offset + Size::from_bytes(8);
106133
}
107134

108135
Ok(())

0 commit comments

Comments
 (0)