@@ -306,19 +306,19 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
306
306
let mut slots_input = vec ! [ None ; self . operands. len( ) ] ;
307
307
let mut slots_output = vec ! [ None ; self . operands. len( ) ] ;
308
308
309
- let mut new_slot = |reg_class : InlineAsmRegClass | {
309
+ let new_slot_fn = |slot_size : & mut Size , reg_class : InlineAsmRegClass | {
310
310
let reg_size = reg_class
311
311
. supported_types ( InlineAsmArch :: X86_64 )
312
312
. iter ( )
313
313
. map ( |( ty, _) | ty. size ( ) )
314
314
. max ( )
315
315
. unwrap ( ) ;
316
316
let align = rustc_target:: abi:: Align :: from_bytes ( reg_size. bytes ( ) ) . unwrap ( ) ;
317
- slot_size = slot_size. align_to ( align) ;
318
- let offset = slot_size;
319
- slot_size += reg_size;
317
+ let offset = slot_size. align_to ( align) ;
318
+ * slot_size = offset + reg_size;
320
319
offset
321
320
} ;
321
+ let mut new_slot = |x| new_slot_fn ( & mut slot_size, x) ;
322
322
323
323
// Allocate stack slots for saving clobbered registers
324
324
let abi_clobber =
@@ -346,30 +346,49 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
346
346
}
347
347
}
348
348
349
- // FIXME overlap input and output slots to save stack space
349
+ // Allocate stack slots for inout
350
350
for ( i, operand) in self . operands . iter ( ) . enumerate ( ) {
351
351
match * operand {
352
- InlineAsmOperand :: In { reg, .. } => {
353
- slots_input[ i] = Some ( new_slot ( reg. reg_class ( ) ) ) ;
354
- }
355
- InlineAsmOperand :: Out { reg, place, .. } => {
356
- if place. is_some ( ) {
357
- slots_output[ i] = Some ( new_slot ( reg. reg_class ( ) ) ) ;
358
- }
359
- }
360
- InlineAsmOperand :: InOut { reg, out_place, .. } => {
352
+ InlineAsmOperand :: InOut { reg, out_place : Some ( _) , .. } => {
361
353
let slot = new_slot ( reg. reg_class ( ) ) ;
362
354
slots_input[ i] = Some ( slot) ;
363
- if out_place. is_some ( ) {
364
- slots_output[ i] = Some ( slot) ;
365
- }
355
+ slots_output[ i] = Some ( slot) ;
356
+ }
357
+ _ => ( ) ,
358
+ }
359
+ }
360
+
361
+ let slot_size_before_input = slot_size;
362
+ let mut new_slot = |x| new_slot_fn ( & mut slot_size, x) ;
363
+
364
+ // Allocate stack slots for input
365
+ for ( i, operand) in self . operands . iter ( ) . enumerate ( ) {
366
+ match * operand {
367
+ InlineAsmOperand :: In { reg, .. }
368
+ | InlineAsmOperand :: InOut { reg, out_place : None , .. } => {
369
+ slots_input[ i] = Some ( new_slot ( reg. reg_class ( ) ) ) ;
370
+ }
371
+ _ => ( ) ,
372
+ }
373
+ }
374
+
375
+ // Reset slot size
376
+ let slot_size_after_input = slot_size;
377
+ slot_size = slot_size_before_input;
378
+ let mut new_slot = |x| new_slot_fn ( & mut slot_size, x) ;
379
+
380
+ // Allocate stack slots for output
381
+ for ( i, operand) in self . operands . iter ( ) . enumerate ( ) {
382
+ match * operand {
383
+ InlineAsmOperand :: Out { reg, place : Some ( _) , .. } => {
384
+ slots_output[ i] = Some ( new_slot ( reg. reg_class ( ) ) ) ;
366
385
}
367
- InlineAsmOperand :: Const { value : _ } => ( ) ,
368
- InlineAsmOperand :: SymFn { value : _ } => ( ) ,
369
- InlineAsmOperand :: SymStatic { def_id : _ } => ( ) ,
386
+ _ => ( ) ,
370
387
}
371
388
}
372
389
390
+ slot_size = slot_size. max ( slot_size_after_input) ;
391
+
373
392
self . stack_slots_clobber = slots_clobber;
374
393
self . stack_slots_input = slots_input;
375
394
self . stack_slots_output = slots_output;
0 commit comments