Skip to content

Commit

Permalink
Add intrinsics for va_list
Browse files Browse the repository at this point in the history
Add the llvm intrinsics used to manipulate a va_list and add the va_list
method to Type that builds a va_list according to the targets
va_list_kind.
  • Loading branch information
dlrobertson committed Apr 30, 2018
1 parent be11aac commit 139b207
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/libcore/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1401,4 +1401,22 @@ extern "rust-intrinsic" {
/// Emits a `!nontemporal` store according to LLVM (see their docs).
/// Probably will never become stable.
pub fn nontemporal_store<T>(ptr: *mut T, val: T);

/// Initialize the arglist `ap` for processing via `va_arg`.
#[cfg(not(stage0))]
pub fn va_start(ap: *mut i8);

/// Destroy the arglist `ap` after initialization with `va_start` or
/// `va_copy`.
#[cfg(not(stage0))]
pub fn va_end(ap: *mut i8);

/// Copy the current location of arglist `ap0` to the arglist `ap1`.
#[cfg(not(stage0))]
pub fn va_copy(ap0: *const i8, ap1: *mut i8);

/// Loads an argument of type `T` from the `va_list` `ap` and increment the
/// argument `ap` points to.
#[cfg(not(stage0))]
pub fn va_arg<T: Copy>(ap: *mut i8) -> T;
}
5 changes: 5 additions & 0 deletions src/librustc_trans/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,11 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
ifn!("llvm.assume", fn(i1) -> void);
ifn!("llvm.prefetch", fn(i8p, t_i32, t_i32, t_i32) -> void);

// variadic intrinsics
ifn!("llvm.va_start", fn(i8p) -> void);
ifn!("llvm.va_end", fn(i8p) -> void);
ifn!("llvm.va_copy", fn(i8p, i8p) -> void);

if cx.sess().opts.debuginfo != NoDebugInfo {
ifn!("llvm.dbg.declare", fn(Type::metadata(cx), Type::metadata(cx)) -> void);
ifn!("llvm.dbg.value", fn(Type::metadata(cx), t_i64, Type::metadata(cx)) -> void);
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_trans/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ fn get_simple_intrinsic(cx: &CodegenCx, name: &str) -> Option<ValueRef> {
"roundf64" => "llvm.round.f64",
"assume" => "llvm.assume",
"abort" => "llvm.trap",
"va_start" => "llvm.va_start",
"va_copy" => "llvm.va_copy",
"va_end" => "llvm.va_end",
_ => return None
};
Some(cx.get_intrinsic(&llvm_name))
Expand Down Expand Up @@ -138,6 +141,9 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
let llfn = cx.get_intrinsic(&("llvm.debugtrap"));
bx.call(llfn, &[], None)
}
"va_arg" => {
bx.va_arg(args[0].immediate(), llret_ty)
}
"size_of" => {
let tp_ty = substs.type_at(0);
C_usize(cx, cx.size_of(tp_ty).bytes())
Expand Down
31 changes: 31 additions & 0 deletions src/librustc_trans/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use context::CodegenCx;

use syntax::ast;
use rustc::ty::layout::{self, Align, Size};
use rustc_target::spec::VaListKind;

use std::ffi::CString;
use std::fmt;
Expand Down Expand Up @@ -297,4 +298,34 @@ impl Type {
pub fn x86_mmx(cx: &CodegenCx) -> Type {
ty!(llvm::LLVMX86MMXTypeInContext(cx.llcx))
}

pub fn va_list(cx: &CodegenCx, name: &str) -> Type {
let int_t = Type::c_int(cx);
let voidp_t = Type::i8p(cx);
match cx.tcx.sess.target.target.options.va_list_kind {
VaListKind::CharPtr => {
Type::i8p(cx)
},
VaListKind::VoidPtr => {
voidp_t
},
VaListKind::X86_64Abi => {
let mut va_list_t = Type::named_struct(cx, name);
va_list_t.set_struct_body(&[int_t, int_t, voidp_t, voidp_t], false);
va_list_t
},
VaListKind::AArch64Abi => {
let mut va_list_t = Type::named_struct(cx, name);
va_list_t.set_struct_body(&[voidp_t, voidp_t, voidp_t, int_t, int_t], false);
va_list_t
},
VaListKind::PowerPcAbi => {
let i8_t = Type::i8(cx);
let i16_t = Type::i16(cx);
let mut va_list_t = Type::named_struct(cx, name);
va_list_t.set_struct_body(&[i8_t, i8_t, i16_t, voidp_t, voidp_t], false);
va_list_t
},
}
}
}
8 changes: 8 additions & 0 deletions src/librustc_typeck/check/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,14 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
(0, vec![ptr_ty, tcx.types.usize], tcx.types.usize)
},

"va_start" | "va_end" => (0, vec![tcx.mk_mut_ptr(tcx.types.i8)], tcx.mk_nil()),

"va_copy" => {
(0, vec![tcx.mk_imm_ptr(tcx.types.i8), tcx.mk_mut_ptr(tcx.types.i8)], tcx.mk_nil())
}

"va_arg" => (1, vec![tcx.mk_mut_ptr(tcx.types.i8)], param(0)),

"nontemporal_store" => {
(1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_nil())
}
Expand Down

0 comments on commit 139b207

Please sign in to comment.