From 8bf607a22103bfae21bd31710694dd8860a52783 Mon Sep 17 00:00:00 2001
From: Andrew Lenharth
- <resultarglist> = vanext <va_list> <arglist>, <argty> -- -
The 'vanext' instruction is used to access arguments passed -through the "variable argument" area of a function call. It is used to -implement the va_arg macro in C.
- -This instruction takes a va_list value and the type of the -argument. It returns another va_list. The actual type of -va_list may be defined differently for different targets. Most targets -use a va_list type of sbyte* or some other pointer type.
- -The 'vanext' instruction advances the specified va_list -past an argument of the specified type. In conjunction with the vaarg instruction, it is used to implement -the va_arg macro available in C. For more information, see -the variable argument handling Intrinsic -Functions.
- -It is legal for this instruction to be called in a function which -does not take a variable number of arguments, for example, the vfprintf -function.
- -vanext is an LLVM instruction instead of an intrinsic function because it takes a type as an -argument. The type refers to the current argument in the va_list; it -tells the compiler how far on the stack it needs to advance to find the next -argument.
- -See the variable argument processing -section.
- -- <resultval> = vaarg <va_list> <arglist>, <argty> + <resultval> = va_arg <va_list*> <arglist>, <argty>
The 'vaarg' instruction is used to access arguments passed through +
The 'va_arg' instruction is used to access arguments passed through the "variable argument" area of a function call. It is used to implement the va_arg macro in C.
This instruction takes a va_list value and the type of the -argument. It returns a value of the specified argument type. Again, the actual -type of va_list is target specific.
+This instruction takes a va_list* value and the type of +the argument. It returns a value of the specified argument type and +increments the va_list to poin to the next argument. Again, the +actual type of va_list is target specific.
The 'vaarg' instruction loads an argument of the specified type from -the specified va_list. In conjunction with the vanext instruction, it is used to implement the -va_arg macro available in C. For more information, see the variable -argument handling Intrinsic Functions.
+The 'va_arg' instruction loads an argument of the specified +type from the specified va_list and causes the +va_list to point to the next argument. For more information, +see the variable argument handling Intrinsic +Functions.
It is legal for this instruction to be called in a function which does not take a variable number of arguments, for example, the vfprintf function.
-vaarg is an LLVM instruction instead of an va_arg is an LLVM instruction instead of an intrinsic function because it takes a type as an argument.
@@ -2361,20 +2309,20 @@ used.int %test(int %X, ...) { ; Initialize variable argument processing - %ap = call sbyte* %llvm.va_start() + %ap = alloca sbyte* + call void %llvm.va_start(sbyte** %ap) ; Read a single integer argument - %tmp = vaarg sbyte* %ap, int - - ; Advance to the next argument - %ap2 = vanext sbyte* %ap, int + %tmp = va_arg sbyte** %ap, int ; Demonstrate usage of llvm.va_copy and llvm.va_end - %aq = call sbyte* %llvm.va_copy(sbyte* %ap2) - call void %llvm.va_end(sbyte* %aq) + %aq = alloca sbyte* + %apv = load sbyte** %ap + call void %llvm.va_copy(sbyte** %aq, sbyte* %apv) + call void %llvm.va_end(sbyte** %aq) ; Stop processing of arguments. - call void %llvm.va_end(sbyte* %ap2) + call void %llvm.va_end(sbyte** %ap) ret int %tmp }@@ -2388,19 +2336,25 @@ int %test(int %X, ...) {
declare <va_list> %llvm.va_start()+
declare void %llvm.va_start(<va_list>* <arglist>)
The 'llvm.va_start' intrinsic returns a new <arglist> -for subsequent use by the variable argument intrinsics.
+The 'llvm.va_start' intrinsic initializes +*<arglist> for subsequent use by va_arg.
+ +The argument is a pointer to a va_list element to initialize.
+The 'llvm.va_start' intrinsic works just like the va_start -macro available in C. In a target-dependent way, it initializes and -returns a va_list element, so that the next vaarg -will produce the first variable argument passed to the function. Unlike -the C va_start macro, this intrinsic does not need to know the -last argument of the function; the compiler can figure that out.
-Note that this intrinsic function is only legal to be called from -within the body of a variable argument function.
+ +The 'llvm.va_start' intrinsic works just like the va_start +macro available in C. In a target-dependent way, it initializes the +va_list element the argument points to, so that the next call to +va_arg will produce the first variable argument passed to the function. +Unlike the C va_start macro, this intrinsic does not need to know the +last argument of the function, the compiler can figure that out.
+declare void %llvm.va_end(<va_list> <arglist>)+
declare void %llvm.va_end(<va_list*> <arglist>)
The 'llvm.va_end' intrinsic destroys <arglist> which has been initialized previously with llvm.va_start @@ -2435,24 +2389,27 @@ with calls to llvm.va_end.
- declare <va_list> %llvm.va_copy(<va_list> <destarglist>) + declare void %llvm.va_copy(<va_list>* <destarglist>, + <va_list> <srcarglist>)
The 'llvm.va_copy' intrinsic copies the current argument position -from the source argument list to the destination argument list.
+The 'llvm.va_copy' intrinsic copies the current argument position from +the source argument list to the destination argument list.
The argument is the va_list to copy.
+The first argument is a pointer to a va_list element to initialize. +The second argument is a va_list element to copy from.
+The 'llvm.va_copy' intrinsic works just like the va_copy -macro available in C. In a target-dependent way, it copies the source -va_list element into the returned list. This intrinsic is necessary -because the llvm.va_start intrinsic may be +
The 'llvm.va_copy' intrinsic works just like the va_copy macro +available in C. In a target-dependent way, it copies the source +va_list element into the destination list. This intrinsic is necessary +because the llvm.va_begin intrinsic may be arbitrarily complex and require memory allocation, for example.