Skip to content

Commit 22789e6

Browse files
committed
implement va_start and va_arg
1 parent 8d7b443 commit 22789e6

2 files changed

Lines changed: 22 additions & 8 deletions

File tree

src/builder.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use std::convert::TryFrom;
44
use std::ops::Deref;
55

66
use gccjit::{
7-
BinaryOp, Block, ComparisonOp, Context, Function, LValue, Location, RValue, ToRValue, Type,
8-
UnaryOp,
7+
BinaryOp, Block, CType, ComparisonOp, Context, Function, LValue, Location, RValue, ToRValue,
8+
Type, UnaryOp,
99
};
1010
use rustc_abi as abi;
1111
use rustc_abi::{Align, HasDataLayout, Size, TargetDataLayout, WrappingRange};
@@ -1513,8 +1513,10 @@ impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
15131513
variable.to_rvalue()
15141514
}
15151515

1516-
fn va_arg(&mut self, _list: RValue<'gcc>, _ty: Type<'gcc>) -> RValue<'gcc> {
1517-
unimplemented!();
1516+
fn va_arg(&mut self, list: RValue<'gcc>, ty: Type<'gcc>) -> RValue<'gcc> {
1517+
let va_list_type = self.context.new_c_type(CType::VaList);
1518+
let list = self.context.new_cast(self.location, list, va_list_type.make_pointer());
1519+
self.context.new_va_arg(self.location, list, ty)
15181520
}
15191521

15201522
#[cfg(feature = "master")]

src/intrinsic/mod.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ mod simd;
44
#[cfg(feature = "master")]
55
use std::iter;
66

7-
use gccjit::{ComparisonOp, Function, FunctionType, RValue, ToRValue, Type, UnaryOp};
7+
use gccjit::{CType, ComparisonOp, Function, FunctionType, RValue, ToRValue, Type, UnaryOp};
88
use rustc_abi::{Align, BackendRepr, HasDataLayout, WrappingRange};
99
use rustc_codegen_ssa::base::wants_msvc_seh;
1010
use rustc_codegen_ssa::common::IntPredicate;
@@ -362,7 +362,9 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
362362
unimplemented!();
363363
}
364364
sym::va_arg => {
365-
unimplemented!();
365+
let va_list = args[0].immediate();
366+
let gcc_type = self.immediate_backend_type(result.layout);
367+
self.va_arg(va_list, gcc_type)
366368
}
367369

368370
sym::volatile_load | sym::unaligned_volatile_load => {
@@ -691,8 +693,18 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tc
691693
self.context.new_rvalue_from_int(self.int_type, 0)
692694
}
693695

694-
fn va_start(&mut self, _va_list: RValue<'gcc>) {
695-
unimplemented!();
696+
fn va_start(&mut self, va_list: RValue<'gcc>) {
697+
let func = self.context.get_builtin_function("__builtin_va_start");
698+
699+
let va_list_type = self.context.new_c_type(CType::VaList);
700+
let va_list = self.context.new_cast(self.location, va_list, va_list_type.make_pointer());
701+
702+
// Pre-C23 requires that the last "normal" argument was passed to va_start.
703+
// Just pass 0, this appears to be handled correctly.
704+
let last_normal_arg = self.context.new_rvalue_from_int(self.int_type, 0);
705+
706+
let call = self.context.new_call(self.location, func, &[va_list, last_normal_arg]);
707+
self.block.add_eval(self.location, call);
696708
}
697709

698710
fn retag_reg(&mut self, _ptr: Self::Value, _info: &RetagInfo<Self::Value>) -> Self::Value {

0 commit comments

Comments
 (0)