@@ -37,6 +37,7 @@ fn emit_direct_ptr_va_arg<'ll, 'tcx>(
37
37
align : Align ,
38
38
slot_size : Align ,
39
39
allow_higher_align : bool ,
40
+ force_right_adjust : bool ,
40
41
) -> ( & ' ll Value , Align ) {
41
42
let va_list_ty = bx. type_ptr ( ) ;
42
43
let va_list_addr = list. immediate ( ) ;
@@ -54,7 +55,10 @@ fn emit_direct_ptr_va_arg<'ll, 'tcx>(
54
55
let next = bx. inbounds_ptradd ( addr, full_direct_size) ;
55
56
bx. store ( next, va_list_addr, bx. tcx ( ) . data_layout . pointer_align . abi ) ;
56
57
57
- if size. bytes ( ) < slot_size. bytes ( ) && bx. tcx ( ) . sess . target . endian == Endian :: Big {
58
+ if size. bytes ( ) < slot_size. bytes ( )
59
+ && bx. tcx ( ) . sess . target . endian == Endian :: Big
60
+ && force_right_adjust
61
+ {
58
62
let adjusted_size = bx. cx ( ) . const_i32 ( ( slot_size. bytes ( ) - size. bytes ( ) ) as i32 ) ;
59
63
let adjusted = bx. inbounds_ptradd ( addr, adjusted_size) ;
60
64
( adjusted, addr_align)
@@ -78,16 +82,23 @@ enum AllowHigherAlign {
78
82
Yes ,
79
83
}
80
84
85
+ enum ForceRightAdjust {
86
+ No ,
87
+ Yes ,
88
+ }
89
+
81
90
fn emit_ptr_va_arg < ' ll , ' tcx > (
82
91
bx : & mut Builder < ' _ , ' ll , ' tcx > ,
83
92
list : OperandRef < ' tcx , & ' ll Value > ,
84
93
target_ty : Ty < ' tcx > ,
85
94
pass_mode : PassMode ,
86
95
slot_size : SlotSize ,
87
96
allow_higher_align : AllowHigherAlign ,
97
+ force_right_adjust : ForceRightAdjust ,
88
98
) -> & ' ll Value {
89
99
let indirect = matches ! ( pass_mode, PassMode :: Indirect ) ;
90
100
let allow_higher_align = matches ! ( allow_higher_align, AllowHigherAlign :: Yes ) ;
101
+ let force_right_adjust = matches ! ( force_right_adjust, ForceRightAdjust :: Yes ) ;
91
102
let slot_size = Align :: from_bytes ( slot_size as u64 ) . unwrap ( ) ;
92
103
93
104
let layout = bx. cx . layout_of ( target_ty) ;
@@ -100,8 +111,15 @@ fn emit_ptr_va_arg<'ll, 'tcx>(
100
111
} else {
101
112
( layout. llvm_type ( bx. cx ) , layout. size , layout. align )
102
113
} ;
103
- let ( addr, addr_align) =
104
- emit_direct_ptr_va_arg ( bx, list, size, align. abi , slot_size, allow_higher_align) ;
114
+ let ( addr, addr_align) = emit_direct_ptr_va_arg (
115
+ bx,
116
+ list,
117
+ size,
118
+ align. abi ,
119
+ slot_size,
120
+ allow_higher_align,
121
+ force_right_adjust,
122
+ ) ;
105
123
if indirect {
106
124
let tmp_ret = bx. load ( llty, addr, addr_align) ;
107
125
bx. load ( bx. cx . layout_of ( target_ty) . llvm_type ( bx. cx ) , tmp_ret, align. abi )
@@ -205,6 +223,7 @@ fn emit_aapcs_va_arg<'ll, 'tcx>(
205
223
PassMode :: Direct ,
206
224
SlotSize :: Bytes8 ,
207
225
AllowHigherAlign :: Yes ,
226
+ ForceRightAdjust :: No ,
208
227
) ;
209
228
bx. br ( end) ;
210
229
@@ -413,13 +432,25 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
413
432
let target = & bx. cx . tcx . sess . target ;
414
433
415
434
match & * target. arch {
435
+ // Windows x86
436
+ "x86" if target. is_like_windows => emit_ptr_va_arg (
437
+ bx,
438
+ addr,
439
+ target_ty,
440
+ PassMode :: Direct ,
441
+ SlotSize :: Bytes4 ,
442
+ AllowHigherAlign :: No ,
443
+ ForceRightAdjust :: No ,
444
+ ) ,
445
+ // Generic x86
416
446
"x86" => emit_ptr_va_arg (
417
447
bx,
418
448
addr,
419
449
target_ty,
420
450
PassMode :: Direct ,
421
451
SlotSize :: Bytes4 ,
422
452
if target. is_like_windows { AllowHigherAlign :: No } else { AllowHigherAlign :: Yes } ,
453
+ ForceRightAdjust :: No ,
423
454
) ,
424
455
"aarch64" | "arm64ec" if target. is_like_windows || target. is_like_darwin => {
425
456
emit_ptr_va_arg (
@@ -429,10 +460,23 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
429
460
PassMode :: Direct ,
430
461
SlotSize :: Bytes8 ,
431
462
if target. is_like_windows { AllowHigherAlign :: No } else { AllowHigherAlign :: Yes } ,
463
+ ForceRightAdjust :: No ,
432
464
)
433
465
}
434
466
"aarch64" => emit_aapcs_va_arg ( bx, addr, target_ty) ,
435
467
"s390x" => emit_s390x_va_arg ( bx, addr, target_ty) ,
468
+ "powerpc64" | "powerpc64le" => emit_ptr_va_arg (
469
+ bx,
470
+ addr,
471
+ target_ty,
472
+ PassMode :: Direct ,
473
+ SlotSize :: Bytes8 ,
474
+ AllowHigherAlign :: Yes ,
475
+ match & * target. arch {
476
+ "powerpc64" => ForceRightAdjust :: Yes ,
477
+ _ => ForceRightAdjust :: No ,
478
+ } ,
479
+ ) ,
436
480
// Windows x86_64
437
481
"x86_64" if target. is_like_windows => {
438
482
let target_ty_size = bx. cx . size_of ( target_ty) . bytes ( ) ;
@@ -447,6 +491,7 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
447
491
} ,
448
492
SlotSize :: Bytes8 ,
449
493
AllowHigherAlign :: No ,
494
+ ForceRightAdjust :: No ,
450
495
)
451
496
}
452
497
"xtensa" => emit_xtensa_va_arg ( bx, addr, target_ty) ,
0 commit comments