我试图使用来自post的想法来调用LLVM中编写的外来导入文章,但我只是继续得到段错误。这就是我目前所拥有的。
在Haskell
var priorities = "High:1,Medium:2,Low:3,Low:4,Medium:5,High:6,Medium:7,"
+ "High:8,Low:9,Low:10,Medium:11,High:12,Low:13,Medium:14,"
+ "High:15,High:16,Low:17,Medium:18,Low:19,High:20";
var keys = ["High", "Medium", "Low"], res = [];
keys.forEach(function(val) {
res = res.concat(priorities.match(new RegExp(val + "\.\\w+(?=.*,)", "g")))
});
document.body.innerHTML = JSON.stringify(res)
并在{-# LANGUAGE GHCForeignImportPrim #-}
{-# LANGUAGE MagicHash, UnboxedTuples #-}
{-# LANGUAGE ForeignFunctionInterface, UnliftedFFITypes #-}
import GHC.Prim
foreign import prim "primllvm" primllvm :: Word# -> Word# -> (# Word#, Word# #)
文件中
.ll
理论上我认为这应该只是将它作为一个元组返回,但就像我说的那样,它只是段错误。任何帮助使这项工作受到赞赏。
答案 0 :(得分:2)
我发现您的代码存在两个问题:
虽然您的签名表示您在Haskell方面传递了两个Word#
参数,但在LLC方面,您有i64* %buffer
和i64 %length
(注意类型{{1}是指针类型!)。
堆栈中的%buffer
:sp
点还有一个间接级别,堆栈顶部的东西是连续指针。您的代码似乎试图将堆栈指针解释为函数指针本身。
我不知道LLVM,我只是通过查看你链接的博客文章,知道GHC,玩游戏,将它拼凑在一起;所以我最终不得不求助于查看sp
的输出,因此可能有一种更有效的方式来处理#2,但无论如何这里是一个可以工作并实现两个64位交换的版本数:
clang
用于测试的Haskell代码:
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
}
大厦:
{-# 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)