@@ -37,6 +37,7 @@ fn emit_direct_ptr_va_arg<'ll, 'tcx>(
3737 align : Align ,
3838 slot_size : Align ,
3939 allow_higher_align : bool ,
40+ force_right_adjust : bool ,
4041) -> ( & ' ll Value , Align ) {
4142 let va_list_ty = bx. type_ptr ( ) ;
4243 let va_list_addr = list. immediate ( ) ;
@@ -54,7 +55,10 @@ fn emit_direct_ptr_va_arg<'ll, 'tcx>(
5455 let next = bx. inbounds_ptradd ( addr, full_direct_size) ;
5556 bx. store ( next, va_list_addr, bx. tcx ( ) . data_layout . pointer_align . abi ) ;
5657
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+ {
5862 let adjusted_size = bx. cx ( ) . const_i32 ( ( slot_size. bytes ( ) - size. bytes ( ) ) as i32 ) ;
5963 let adjusted = bx. inbounds_ptradd ( addr, adjusted_size) ;
6064 ( adjusted, addr_align)
@@ -78,16 +82,23 @@ enum AllowHigherAlign {
7882 Yes ,
7983}
8084
85+ enum ForceRightAdjust {
86+ No ,
87+ Yes ,
88+ }
89+
8190fn emit_ptr_va_arg < ' ll , ' tcx > (
8291 bx : & mut Builder < ' _ , ' ll , ' tcx > ,
8392 list : OperandRef < ' tcx , & ' ll Value > ,
8493 target_ty : Ty < ' tcx > ,
8594 pass_mode : PassMode ,
8695 slot_size : SlotSize ,
8796 allow_higher_align : AllowHigherAlign ,
97+ force_right_adjust : ForceRightAdjust ,
8898) -> & ' ll Value {
8999 let indirect = matches ! ( pass_mode, PassMode :: Indirect ) ;
90100 let allow_higher_align = matches ! ( allow_higher_align, AllowHigherAlign :: Yes ) ;
101+ let force_right_adjust = matches ! ( force_right_adjust, ForceRightAdjust :: Yes ) ;
91102 let slot_size = Align :: from_bytes ( slot_size as u64 ) . unwrap ( ) ;
92103
93104 let layout = bx. cx . layout_of ( target_ty) ;
@@ -100,8 +111,15 @@ fn emit_ptr_va_arg<'ll, 'tcx>(
100111 } else {
101112 ( layout. llvm_type ( bx. cx ) , layout. size , layout. align )
102113 } ;
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+ ) ;
105123 if indirect {
106124 let tmp_ret = bx. load ( llty, addr, addr_align) ;
107125 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>(
205223 PassMode :: Direct ,
206224 SlotSize :: Bytes8 ,
207225 AllowHigherAlign :: Yes ,
226+ ForceRightAdjust :: No ,
208227 ) ;
209228 bx. br ( end) ;
210229
@@ -413,13 +432,25 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
413432 let target = & bx. cx . tcx . sess . target ;
414433
415434 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
416446 "x86" => emit_ptr_va_arg (
417447 bx,
418448 addr,
419449 target_ty,
420450 PassMode :: Direct ,
421451 SlotSize :: Bytes4 ,
422452 if target. is_like_windows { AllowHigherAlign :: No } else { AllowHigherAlign :: Yes } ,
453+ ForceRightAdjust :: No ,
423454 ) ,
424455 "aarch64" | "arm64ec" if target. is_like_windows || target. is_like_darwin => {
425456 emit_ptr_va_arg (
@@ -429,10 +460,23 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
429460 PassMode :: Direct ,
430461 SlotSize :: Bytes8 ,
431462 if target. is_like_windows { AllowHigherAlign :: No } else { AllowHigherAlign :: Yes } ,
463+ ForceRightAdjust :: No ,
432464 )
433465 }
434466 "aarch64" => emit_aapcs_va_arg ( bx, addr, target_ty) ,
435467 "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+ ) ,
436480 // Windows x86_64
437481 "x86_64" if target. is_like_windows => {
438482 let target_ty_size = bx. cx . size_of ( target_ty) . bytes ( ) ;
@@ -447,6 +491,7 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
447491 } ,
448492 SlotSize :: Bytes8 ,
449493 AllowHigherAlign :: No ,
494+ ForceRightAdjust :: No ,
450495 )
451496 }
452497 "xtensa" => emit_xtensa_va_arg ( bx, addr, target_ty) ,
0 commit comments