Cli*_*ton 5 haskell ffi llvm ghc llvm-ir
我正在尝试使用这篇文章中的想法调用一个用LLVM编写的外来导入文章,但我只是继续得到段错误.这就是我目前所拥有的.
在哈斯克尔
{-# LANGUAGE GHCForeignImportPrim #-}
{-# LANGUAGE MagicHash, UnboxedTuples #-}
{-# LANGUAGE ForeignFunctionInterface, UnliftedFFITypes #-}
import GHC.Prim
foreign import prim "primllvm" primllvm :: Word# -> Word# -> (# Word#, Word# #)
Run Code Online (Sandbox Code Playgroud)
并在.ll文件中
define cc10 void @primllvm(i64* %baseReg, i64* %sp, i64* %hp, i64* %buffer, i64 %length, i64 %r3, i64 %r4, i64 %r5, i64 %r6, i64* %spLim, float %f1, float %f2, float %f3, float %f4, double %d1, double %d2)
{
%fp = bitcast i64* %sp to void(i64*, i64*, i64*, i64*, i64, i64, i64, i64, i64, i64*, float, float, float, float, double, double)*
tail call cc10 void %fp(i64* %baseReg, i64* %sp, i64* %hp, i64* %buffer, i64 %length, i64 %r3, i64 %r4, i64 %r5, i64 %r6, i64* %spLim, float %f1, float %f2, float %f3, float %f4, double %d1, double %d2) noreturn;
ret void
}
Run Code Online (Sandbox Code Playgroud)
从理论上讲,我认为这应该只是将它作为一个元组返回,但就像我说的那样,它只是段错误.任何帮助让这项工作受到赞赏.
我发现您的代码有两个问题:
虽然你的签名表明你在 Haskell 端传递了两个Word#参数,但在 LLC 端你有i64* %buffer和i64 %length(注意类型%buffer是指针类型!)。
: 中还有一层间接寻址sp,sp指向堆栈,堆栈顶部是延续指针。您的代码似乎尝试将堆栈指针解释为函数指针本身。
我不知道 LLVM,我只是通过查看您链接的博客文章、了解 GHC 并尝试将其拼凑在一起;所以我最终不得不求助于查看clang的输出,因此可能有一种更有效的方法来处理#2,但无论如何,这里有一个可以工作并实现两个 64 位数字交换的版本:
define cc10 void @primllvm(i64* %baseReg, i64* %sp, i64* %hp,
i64 %x, i64 %y, i64 %r3, i64 %r4, i64 %r5, i64 %r6,
i64* %spLim,
float %f1, float %f2, float %f3, float %f4,
double %d1, double %d2)
{
%1 = getelementptr inbounds i64* %sp, i64 0
%2 = load i64* %1, align 8
%cont = inttoptr i64 %2 to void (i64*, i64*, i64*,
i64, i64, i64, i64, i64, i64,
i64*,
float, float, float, float,
double, double)*
tail call cc10 void %cont(i64* %baseReg, i64* %sp, i64* %hp,
i64 %y, i64 %x, i64 %r3, i64 %r4, i64 %r5, i64 %r6,
i64* %spLim,
float %f1, float %f2, float %f3, float %f4,
double %d1, double %d2) noreturn
ret void
}
Run Code Online (Sandbox Code Playgroud)
用于测试的 Haskell 代码:
{-# LANGUAGE GHCForeignImportPrim #-}
{-# LANGUAGE MagicHash, UnboxedTuples, BangPatterns #-}
{-# LANGUAGE ForeignFunctionInterface, UnliftedFFITypes #-}
import GHC.Prim
import GHC.Word
foreign import prim "primllvm" primllvm :: Word# -> Word# -> (# Word#, Word# #)
main :: IO ()
main = do
let !(W# w1) = 12
!(W# w2) = 34
!(# w1', w2' #) = primllvm w1 w2
x = W# w1'
y = W# w2'
print (x, y)
Run Code Online (Sandbox Code Playgroud)
建筑:
llc -filetype=obj -o Define.o Define.ll
ghc --make Use.hs Define.o
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
208 次 |
| 最近记录: |