Mil*_*red 6 assembly llvm variadic-functions
我想在LLVM程序集中定义一个函数,该函数作为参数:
此函数应该进行一些预处理,找到标识符的正确函数并使用vararg调用它,并返回其结果.
就像是:
define ??? @1 (i32 %identifier, ...vararg...)
{
switch i32 %identifier, label %def, i32 1, label %a
a:
%1 = tail call @function_for_a, ...vararg...
ret ??? %1
def:
ret void
}
Run Code Online (Sandbox Code Playgroud)
这似乎不可能.还有办法吗?我认为应该可以使用普通的汇编程序.
这旨在成为面向对象语言的调度功能.我希望它快.
我想要的是一种方式:
然后执行第二个函数代替第一个函数(它是一个尾调用),但是带有一个参数列表,该参数列表与第一个函数(第一个函数的vararg)不完全相同.
第一:如果你想传递可变参数,你不能使用尾部调用:
http://llvm.org/docs/LangRef.html
- 可选的“tail”标记指示被调用函数不访问调用方中的任何分配器或可变参数。
第二:你的调用约定是什么?
第三:要处理可变参数(就像在 C 中一样),您需要使用va_*
函数创建一个新的 va_list 并将所有参数复制到其中:
http://llvm.org/docs/LangRef.html#int-varargs
最后:此调度程序调用的每个函数都必须使用va_*
函数来获取其参数。
更新:
在谈论堆栈作为函数参数的存储之前,您应该知道将使用哪种调用约定(默认值是什么)。然后。如果没有 va_* 函数,则无法访问不传递“...”参数,因为这是在 LLVM 程序集中访问它们的唯一方法。
有一种像 C 语言一样的方法,这里 printf 将使用所有“...”参数调用 vfprintf,并且不知道要传递多少个参数
// 3-clause BSD licensed to The Regents of the University of California.
int
printf(const char *fmt, ...)
{
int ret;
va_list ap;
va_start(ap, fmt);
ret = vfprintf(stdout, fmt, ap);
va_end(ap);
return (ret);
}
Run Code Online (Sandbox Code Playgroud)
Vfprintf 以特殊方式声明以获取“...”并从中提取参数:
int
vfprintf(FILE *fp, const char *fmt0, __va_list ap)
{
...
va_arg(ap, type) //to get next arg of type `type`
Run Code Online (Sandbox Code Playgroud)