@@ -24,6 +24,25 @@ enum Class {
24
24
SseUp
25
25
}
26
26
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
+
27
46
#[ derive( Clone , Copy , Debug ) ]
28
47
struct Memory ;
29
48
@@ -64,17 +83,12 @@ fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>)
64
83
return Ok ( ( ) ) ;
65
84
}
66
85
67
- match layout. abi {
68
- layout:: Abi :: Uninhabited => { }
86
+ let mut offset = match layout. abi {
87
+ layout:: Abi :: Uninhabited => return Ok ( ( ) ) ,
69
88
70
89
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)
78
92
}
79
93
80
94
layout:: Abi :: Vector { ref element, count } => {
@@ -83,26 +97,39 @@ fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>)
83
97
// everything after the first one is the upper
84
98
// half of a register.
85
99
let stride = element. value . size ( ccx) ;
100
+ let mut field_off = off;
86
101
for i in 1 ..count {
87
- let field_off = off + stride * i;
102
+ field_off = off + stride * i;
88
103
unify ( cls, field_off, Class :: SseUp ) ;
89
104
}
105
+ field_off + stride
90
106
}
91
107
92
108
layout:: Abi :: ScalarPair ( ..) |
93
109
layout:: Abi :: Aggregate { .. } => {
94
110
match layout. variants {
95
111
layout:: Variants :: Single { .. } => {
112
+ let mut field_off = off;
113
+ let mut last_size = Size :: from_bytes ( 0 ) ;
96
114
for i in 0 ..layout. fields . count ( ) {
97
- let field_off = off + layout. fields . offset ( i) ;
115
+ field_off = off + layout. fields . offset ( i) ;
98
116
classify ( ccx, layout. field ( ccx, i) , cls, field_off) ?;
117
+ last_size = layout. field ( ccx, i) . size ;
99
118
}
119
+ field_off + last_size
100
120
}
101
121
layout:: Variants :: Tagged { .. } |
102
122
layout:: Variants :: NicheFilling { .. } => return Err ( Memory ) ,
103
123
}
104
124
}
105
125
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 ) ;
106
133
}
107
134
108
135
Ok ( ( ) )
0 commit comments