From d7b806afb41673dfbea43e8dfe33e5038e56a952 Mon Sep 17 00:00:00 2001 From: David Mak Date: Tue, 30 Jul 2024 17:00:08 +0800 Subject: [PATCH] core/codegen: Implement support for va_info on supported architectures --- nac3core/src/codegen/mod.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/nac3core/src/codegen/mod.rs b/nac3core/src/codegen/mod.rs index 0f2ec564..f46b50d9 100644 --- a/nac3core/src/codegen/mod.rs +++ b/nac3core/src/codegen/mod.rs @@ -609,6 +609,40 @@ fn need_sret(ty: BasicTypeEnum) -> bool { need_sret_impl(ty, true) } +/// Returns the [`BasicTypeEnum`] representing a `va_list` struct for variadic arguments. +fn get_llvm_valist_type<'ctx>(ctx: &'ctx Context, triple: &TargetTriple) -> BasicTypeEnum<'ctx> { + let triple = TargetMachine::normalize_triple(triple); + let triple = triple.as_str().to_str().unwrap(); + let arch = triple.split('-').next().unwrap(); + + let llvm_pi8 = ctx.i8_type().ptr_type(AddressSpace::default()); + + // Referenced from parseArch() in llvm/lib/Support/Triple.cpp + match arch { + "i386" | "i486" | "i586" | "i686" | "riscv32" => { + ctx.i8_type().ptr_type(AddressSpace::default()).into() + } + "amd64" | "x86_64" | "x86_64h" => { + let llvm_i32 = ctx.i32_type(); + + let va_list_tag = ctx.opaque_struct_type("struct.__va_list_tag"); + va_list_tag.set_body( + &[llvm_i32.into(), llvm_i32.into(), llvm_pi8.into(), llvm_pi8.into()], + false, + ); + va_list_tag.into() + } + "armv7" => { + let va_list = ctx.opaque_struct_type("struct.__va_list"); + va_list.set_body(&[llvm_pi8.into()], false); + va_list.into() + } + triple => { + todo!("Unsupported platform for varargs: {triple}") + } + } +} + /// Implementation for generating LLVM IR for a function. pub fn gen_func_impl< 'ctx,