3
3
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
4
4
use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
5
5
use rustc_middle:: mir:: interpret:: {
6
- read_target_uint, AllocId , ConstValue , ErrorHandled , GlobalAlloc , Scalar ,
6
+ read_target_uint, AllocId , ConstValue , ConstValueKind , ErrorHandled , GlobalAlloc , Scalar ,
7
7
} ;
8
8
9
9
use cranelift_module:: * ;
@@ -103,6 +103,91 @@ pub(crate) fn codegen_constant_operand<'tcx>(
103
103
codegen_const_value ( fx, const_val, ty)
104
104
}
105
105
106
+ pub ( crate ) fn codegen_const_scalar < ' tcx > (
107
+ fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
108
+ scalar : Scalar ,
109
+ layout : TyAndLayout < ' tcx > ,
110
+ ) -> CValue < ' tcx > {
111
+ match scalar {
112
+ Scalar :: Int ( int) => {
113
+ if fx. clif_type ( layout. ty ) . is_some ( ) {
114
+ return CValue :: const_val ( fx, layout, int) ;
115
+ } else {
116
+ let raw_val = int. to_bits ( int. size ( ) ) . unwrap ( ) ;
117
+ let val = match int. size ( ) . bytes ( ) {
118
+ 1 => fx. bcx . ins ( ) . iconst ( types:: I8 , raw_val as i64 ) ,
119
+ 2 => fx. bcx . ins ( ) . iconst ( types:: I16 , raw_val as i64 ) ,
120
+ 4 => fx. bcx . ins ( ) . iconst ( types:: I32 , raw_val as i64 ) ,
121
+ 8 => fx. bcx . ins ( ) . iconst ( types:: I64 , raw_val as i64 ) ,
122
+ 16 => {
123
+ let lsb = fx. bcx . ins ( ) . iconst ( types:: I64 , raw_val as u64 as i64 ) ;
124
+ let msb = fx. bcx . ins ( ) . iconst ( types:: I64 , ( raw_val >> 64 ) as u64 as i64 ) ;
125
+ fx. bcx . ins ( ) . iconcat ( lsb, msb)
126
+ }
127
+ _ => unreachable ! ( ) ,
128
+ } ;
129
+
130
+ // FIXME avoid this extra copy to the stack and directly write to the final
131
+ // destination
132
+ let place = CPlace :: new_stack_slot ( fx, layout) ;
133
+ place. to_ptr ( ) . store ( fx, val, MemFlags :: trusted ( ) ) ;
134
+ place. to_cvalue ( fx)
135
+ }
136
+ }
137
+ Scalar :: Ptr ( ptr, _size) => {
138
+ let ( alloc_id, offset) = ptr. into_parts ( ) ; // we know the `offset` is relative
139
+ let base_addr = match fx. tcx . global_alloc ( alloc_id) {
140
+ GlobalAlloc :: Memory ( alloc) => {
141
+ let data_id = data_id_for_alloc_id (
142
+ & mut fx. constants_cx ,
143
+ fx. module ,
144
+ alloc_id,
145
+ alloc. inner ( ) . mutability ,
146
+ ) ;
147
+ let local_data_id = fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
148
+ if fx. clif_comments . enabled ( ) {
149
+ fx. add_comment ( local_data_id, format ! ( "{:?}" , alloc_id) ) ;
150
+ }
151
+ fx. bcx . ins ( ) . global_value ( fx. pointer_type , local_data_id)
152
+ }
153
+ GlobalAlloc :: Function ( instance) => {
154
+ let func_id = crate :: abi:: import_function ( fx. tcx , fx. module , instance) ;
155
+ let local_func_id = fx. module . declare_func_in_func ( func_id, & mut fx. bcx . func ) ;
156
+ fx. bcx . ins ( ) . func_addr ( fx. pointer_type , local_func_id)
157
+ }
158
+ GlobalAlloc :: VTable ( ty, trait_ref) => {
159
+ let alloc_id = fx. tcx . vtable_allocation ( ( ty, trait_ref) ) ;
160
+ let alloc = fx. tcx . global_alloc ( alloc_id) . unwrap_memory ( ) ;
161
+ // FIXME: factor this common code with the `Memory` arm into a function?
162
+ let data_id = data_id_for_alloc_id (
163
+ & mut fx. constants_cx ,
164
+ fx. module ,
165
+ alloc_id,
166
+ alloc. inner ( ) . mutability ,
167
+ ) ;
168
+ let local_data_id = fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
169
+ fx. bcx . ins ( ) . global_value ( fx. pointer_type , local_data_id)
170
+ }
171
+ GlobalAlloc :: Static ( def_id) => {
172
+ assert ! ( fx. tcx. is_static( def_id) ) ;
173
+ let data_id = data_id_for_static ( fx. tcx , fx. module , def_id, false ) ;
174
+ let local_data_id = fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
175
+ if fx. clif_comments . enabled ( ) {
176
+ fx. add_comment ( local_data_id, format ! ( "{:?}" , def_id) ) ;
177
+ }
178
+ fx. bcx . ins ( ) . global_value ( fx. pointer_type , local_data_id)
179
+ }
180
+ } ;
181
+ let val = if offset. bytes ( ) != 0 {
182
+ fx. bcx . ins ( ) . iadd_imm ( base_addr, i64:: try_from ( offset. bytes ( ) ) . unwrap ( ) )
183
+ } else {
184
+ base_addr
185
+ } ;
186
+ CValue :: by_val ( val, layout)
187
+ }
188
+ }
189
+ }
190
+
106
191
pub ( crate ) fn codegen_const_value < ' tcx > (
107
192
fx : & mut FunctionCx < ' _ , ' _ , ' tcx > ,
108
193
const_val : ConstValue < ' tcx > ,
@@ -115,106 +200,19 @@ pub(crate) fn codegen_const_value<'tcx>(
115
200
return CValue :: by_ref ( crate :: Pointer :: dangling ( layout. align . pref ) , layout) ;
116
201
}
117
202
118
- match const_val {
119
- ConstValue :: ZeroSized => unreachable ! ( ) , // we already handled ZST above
120
- ConstValue :: Scalar ( x) => match x {
121
- Scalar :: Int ( int) => {
122
- if fx. clif_type ( layout. ty ) . is_some ( ) {
123
- return CValue :: const_val ( fx, layout, int) ;
124
- } else {
125
- let raw_val = int. to_bits ( int. size ( ) ) . unwrap ( ) ;
126
- let val = match int. size ( ) . bytes ( ) {
127
- 1 => fx. bcx . ins ( ) . iconst ( types:: I8 , raw_val as i64 ) ,
128
- 2 => fx. bcx . ins ( ) . iconst ( types:: I16 , raw_val as i64 ) ,
129
- 4 => fx. bcx . ins ( ) . iconst ( types:: I32 , raw_val as i64 ) ,
130
- 8 => fx. bcx . ins ( ) . iconst ( types:: I64 , raw_val as i64 ) ,
131
- 16 => {
132
- let lsb = fx. bcx . ins ( ) . iconst ( types:: I64 , raw_val as u64 as i64 ) ;
133
- let msb =
134
- fx. bcx . ins ( ) . iconst ( types:: I64 , ( raw_val >> 64 ) as u64 as i64 ) ;
135
- fx. bcx . ins ( ) . iconcat ( lsb, msb)
136
- }
137
- _ => unreachable ! ( ) ,
138
- } ;
139
-
140
- // FIXME avoid this extra copy to the stack and directly write to the final
141
- // destination
142
- let place = CPlace :: new_stack_slot ( fx, layout) ;
143
- place. to_ptr ( ) . store ( fx, val, MemFlags :: trusted ( ) ) ;
144
- place. to_cvalue ( fx)
145
- }
146
- }
147
- Scalar :: Ptr ( ptr, _size) => {
148
- let ( alloc_id, offset) = ptr. into_parts ( ) ; // we know the `offset` is relative
149
- let base_addr = match fx. tcx . global_alloc ( alloc_id) {
150
- GlobalAlloc :: Memory ( alloc) => {
151
- let data_id = data_id_for_alloc_id (
152
- & mut fx. constants_cx ,
153
- fx. module ,
154
- alloc_id,
155
- alloc. inner ( ) . mutability ,
156
- ) ;
157
- let local_data_id =
158
- fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
159
- if fx. clif_comments . enabled ( ) {
160
- fx. add_comment ( local_data_id, format ! ( "{:?}" , alloc_id) ) ;
161
- }
162
- fx. bcx . ins ( ) . global_value ( fx. pointer_type , local_data_id)
163
- }
164
- GlobalAlloc :: Function ( instance) => {
165
- let func_id = crate :: abi:: import_function ( fx. tcx , fx. module , instance) ;
166
- let local_func_id =
167
- fx. module . declare_func_in_func ( func_id, & mut fx. bcx . func ) ;
168
- fx. bcx . ins ( ) . func_addr ( fx. pointer_type , local_func_id)
169
- }
170
- GlobalAlloc :: VTable ( ty, trait_ref) => {
171
- let alloc_id = fx. tcx . vtable_allocation ( ( ty, trait_ref) ) ;
172
- let alloc = fx. tcx . global_alloc ( alloc_id) . unwrap_memory ( ) ;
173
- // FIXME: factor this common code with the `Memory` arm into a function?
174
- let data_id = data_id_for_alloc_id (
175
- & mut fx. constants_cx ,
176
- fx. module ,
177
- alloc_id,
178
- alloc. inner ( ) . mutability ,
179
- ) ;
180
- let local_data_id =
181
- fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
182
- fx. bcx . ins ( ) . global_value ( fx. pointer_type , local_data_id)
183
- }
184
- GlobalAlloc :: Static ( def_id) => {
185
- assert ! ( fx. tcx. is_static( def_id) ) ;
186
- let data_id = data_id_for_static ( fx. tcx , fx. module , def_id, false ) ;
187
- let local_data_id =
188
- fx. module . declare_data_in_func ( data_id, & mut fx. bcx . func ) ;
189
- if fx. clif_comments . enabled ( ) {
190
- fx. add_comment ( local_data_id, format ! ( "{:?}" , def_id) ) ;
191
- }
192
- fx. bcx . ins ( ) . global_value ( fx. pointer_type , local_data_id)
193
- }
194
- } ;
195
- let val = if offset. bytes ( ) != 0 {
196
- fx. bcx . ins ( ) . iadd_imm ( base_addr, i64:: try_from ( offset. bytes ( ) ) . unwrap ( ) )
197
- } else {
198
- base_addr
199
- } ;
200
- CValue :: by_val ( val, layout)
201
- }
202
- } ,
203
- ConstValue :: Indirect { alloc_id, offset } => CValue :: by_ref (
203
+ match * const_val. kind ( ) {
204
+ ConstValueKind :: ZeroSized => unreachable ! ( ) , // we already handled ZST above
205
+ ConstValueKind :: Scalar ( x) => codegen_const_scalar ( fx, x, layout) ,
206
+ ConstValueKind :: Indirect { alloc_id, offset } => CValue :: by_ref (
204
207
pointer_for_allocation ( fx, alloc_id)
205
208
. offset_i64 ( fx, i64:: try_from ( offset. bytes ( ) ) . unwrap ( ) ) ,
206
209
layout,
207
210
) ,
208
- ConstValue :: Slice { data, start, end } => {
209
- let alloc_id = fx. tcx . reserve_and_set_memory_alloc ( data) ;
210
- let ptr = pointer_for_allocation ( fx, alloc_id)
211
- . offset_i64 ( fx, i64:: try_from ( start) . unwrap ( ) )
212
- . get_addr ( fx) ;
213
- let len = fx
214
- . bcx
215
- . ins ( )
216
- . iconst ( fx. pointer_type , i64:: try_from ( end. checked_sub ( start) . unwrap ( ) ) . unwrap ( ) ) ;
217
- CValue :: by_val_pair ( ptr, len, layout)
211
+ ConstValueKind :: ScalarPair ( a, b) => {
212
+ // FIXME wrong layout.
213
+ let a = codegen_const_scalar ( fx, a, layout) ;
214
+ let b = codegen_const_scalar ( fx, b, layout) ;
215
+ CValue :: by_val_pair ( a, b, layout)
218
216
}
219
217
}
220
218
}
0 commit comments