问题描述
在LLVM中,有一个LLVmfp128Type
,尽管我似乎无法找出如何将实际的long double
转换为类型LLVMValueRef
的{{1}}的方法。
我可以执行以下操作(使用LLVmfp128Type
):
double
生成以下LLVM IR:
LLVMValueRef var = LLVMBuildAlloca(
builder,LLVMDoubleTypeInContext(ctx),"x"
);
double num = 3.1415;
LLVMBuildStore(
builder,LLVMConstReal(
LLVMDoubleTypeInContext(ctx),num
),var
);
但是对于%x = alloca double
store double 3.141500e+00,double* %x
,我该怎么做?有一个long double
函数,它使字符串恒定浮点数,尽管我发现必须使用LLVMConstRealOfString
之类的字符串来回转换效率不高:
sprintf
给出以下(期望的)LLVM IR:
LLVMValueRef var = LLVMBuildAlloca(
builder,LLVmfp128TypeInContext(ctx),"x"
);
// long double num = 3.1415L;
LLVMBuildStore(
builder,LLVMConstRealOfString(
LLVmfp128TypeInContext(ctx),"3.1415" // would have to sprintf `num`
),var
);
如何通过第一个示例的简单性获得期望的结果(下例)?
解决方法
我不知道这些LLVMBuildStore
,但是GCC,ICC和Clang已经有了__float128
作为扩展名,因此您可以使用它。 __float128 x = 3.1415;
产生以下LLVM IR
%7 = load fp128*,fp128** %4,align 8,!dbg !22
store fp128 0xLF0000000000000004000921CAC083126,fp128* %7,align 16,!dbg !23
实际上,对于大多数现代体系结构,long double
映射到__float128
。在x86中,硬件支持扩展精度,因此将其映射到__float80
,您可以使用-mlong-double-128
选项将其设置为IEEE-754 binary128类型,即__float128
。在PowerPC上,long double
默认使用double-double arithmetic,您可以使用-mabi=ieeelongdouble
获得与上述相同的效果