Skip to content

Commit 108a36e

Browse files
committed
implement va_arg for powerpc64 and powerpc64le
1 parent aa5832b commit 108a36e

File tree

1 file changed

+48
-3
lines changed

1 file changed

+48
-3
lines changed

compiler/rustc_codegen_llvm/src/va_arg.rs

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ fn emit_direct_ptr_va_arg<'ll, 'tcx>(
4040
align: Align,
4141
slot_size: Align,
4242
allow_higher_align: bool,
43+
force_right_adjust: bool,
4344
) -> (&'ll Value, Align) {
4445
let va_list_ty = bx.type_ptr();
4546
let va_list_addr = list.immediate();
@@ -57,7 +58,10 @@ fn emit_direct_ptr_va_arg<'ll, 'tcx>(
5758
let next = bx.inbounds_ptradd(addr, full_direct_size);
5859
bx.store(next, va_list_addr, bx.tcx().data_layout.pointer_align.abi);
5960

60-
if size.bytes() < slot_size.bytes() && bx.tcx().sess.target.endian == Endian::Big {
61+
if size.bytes() < slot_size.bytes()
62+
&& bx.tcx().sess.target.endian == Endian::Big
63+
&& force_right_adjust
64+
{
6165
let adjusted_size = bx.cx().const_i32((slot_size.bytes() - size.bytes()) as i32);
6266
let adjusted = bx.inbounds_ptradd(addr, adjusted_size);
6367
(adjusted, addr_align)
@@ -81,16 +85,23 @@ enum AllowHigherAlign {
8185
Yes,
8286
}
8387

88+
enum ForceRightAdjust {
89+
No,
90+
Yes,
91+
}
92+
8493
fn emit_ptr_va_arg<'ll, 'tcx>(
8594
bx: &mut Builder<'_, 'll, 'tcx>,
8695
list: OperandRef<'tcx, &'ll Value>,
8796
target_ty: Ty<'tcx>,
8897
pass_mode: PassMode,
8998
slot_size: SlotSize,
9099
allow_higher_align: AllowHigherAlign,
100+
force_right_adjust: ForceRightAdjust,
91101
) -> &'ll Value {
92102
let indirect = matches!(pass_mode, PassMode::Indirect);
93103
let allow_higher_align = matches!(allow_higher_align, AllowHigherAlign::Yes);
104+
let force_right_adjust = matches!(force_right_adjust, ForceRightAdjust::Yes);
94105
let slot_size = Align::from_bytes(slot_size as u64).unwrap();
95106

96107
let layout = bx.cx.layout_of(target_ty);
@@ -103,8 +114,15 @@ fn emit_ptr_va_arg<'ll, 'tcx>(
103114
} else {
104115
(layout.llvm_type(bx.cx), layout.size, layout.align)
105116
};
106-
let (addr, addr_align) =
107-
emit_direct_ptr_va_arg(bx, list, size, align.abi, slot_size, allow_higher_align);
117+
let (addr, addr_align) = emit_direct_ptr_va_arg(
118+
bx,
119+
list,
120+
size,
121+
align.abi,
122+
slot_size,
123+
allow_higher_align,
124+
force_right_adjust,
125+
);
108126
if indirect {
109127
let tmp_ret = bx.load(llty, addr, addr_align);
110128
bx.load(bx.cx.layout_of(target_ty).llvm_type(bx.cx), tmp_ret, align.abi)
@@ -208,6 +226,7 @@ fn emit_aapcs_va_arg<'ll, 'tcx>(
208226
PassMode::Direct,
209227
SlotSize::Bytes8,
210228
AllowHigherAlign::Yes,
229+
ForceRightAdjust::No,
211230
);
212231
bx.br(end);
213232

@@ -721,13 +740,25 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
721740
let target = &bx.cx.tcx.sess.target;
722741

723742
match &*target.arch {
743+
// Windows x86
744+
"x86" if target.is_like_windows => emit_ptr_va_arg(
745+
bx,
746+
addr,
747+
target_ty,
748+
PassMode::Direct,
749+
SlotSize::Bytes4,
750+
AllowHigherAlign::No,
751+
ForceRightAdjust::No,
752+
),
753+
// Generic x86
724754
"x86" => emit_ptr_va_arg(
725755
bx,
726756
addr,
727757
target_ty,
728758
PassMode::Direct,
729759
SlotSize::Bytes4,
730760
if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes },
761+
ForceRightAdjust::No,
731762
),
732763
"aarch64" | "arm64ec" if target.is_like_windows || target.is_like_darwin => {
733764
emit_ptr_va_arg(
@@ -737,10 +768,23 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
737768
PassMode::Direct,
738769
SlotSize::Bytes8,
739770
if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes },
771+
ForceRightAdjust::No,
740772
)
741773
}
742774
"aarch64" => emit_aapcs_va_arg(bx, addr, target_ty),
743775
"s390x" => emit_s390x_va_arg(bx, addr, target_ty),
776+
"powerpc64" | "powerpc64le" => emit_ptr_va_arg(
777+
bx,
778+
addr,
779+
target_ty,
780+
PassMode::Direct,
781+
SlotSize::Bytes8,
782+
AllowHigherAlign::Yes,
783+
match &*target.arch {
784+
"powerpc64" => ForceRightAdjust::Yes,
785+
_ => ForceRightAdjust::No,
786+
},
787+
),
744788
// Windows x86_64
745789
"x86_64" if target.is_like_windows => {
746790
let target_ty_size = bx.cx.size_of(target_ty).bytes();
@@ -755,6 +799,7 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
755799
},
756800
SlotSize::Bytes8,
757801
AllowHigherAlign::No,
802+
ForceRightAdjust::No,
758803
)
759804
}
760805
// This includes `target.is_like_darwin`, which on x86_64 targets is like sysv64.

0 commit comments

Comments
 (0)