2015-11-25 12 views
5

Tôi đang cố gắng thực hiện cuộc gọi đến mã nhập khẩu nước ngoài được viết bằng LLVM, sử dụng các ý tưởng từ số post này nhưng tôi chỉ tiếp tục nhận được segfaults. Đây là những gì tôi có hiện tại.gọi điện thoại nhập khẩu nước ngoài đến LLVM

Trong Haskell

{-# LANGUAGE GHCForeignImportPrim #-} 
{-# LANGUAGE MagicHash, UnboxedTuples #-} 
{-# LANGUAGE ForeignFunctionInterface, UnliftedFFITypes #-} 

import GHC.Prim 

foreign import prim "primllvm" primllvm :: Word# -> Word# -> (# Word#, Word# #) 

Và trong .ll tập tin

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 
} 

Về lý thuyết Tôi nghĩ rằng đây chỉ phải trả lại nó lập luận như một tuple, nhưng cũng giống như tôi đã nói, nó chỉ segfaults. Bất kỳ trợ giúp để có được điều này làm việc đánh giá cao.

Trả lời

2

Tôi đã tìm thấy hai vấn đề với mã của bạn:

  1. Mặc dù chữ ký của bạn nói rằng bạn vượt qua trong hai Word# đối số ở phía bên Haskell, ở phía bên LLC bạn có i64* %bufferi64 %length (loại ghi %buffer là kiểu con trỏ!).

  2. Có một cấp độ khác biệt về số không trong sp: sp điểm tại ngăn xếp và điều đầu tiên trên ngăn xếp là con trỏ tiếp tục. Mã của bạn dường như cố gắng giải thích con trỏ ngăn xếp như chính con trỏ hàm.

Tôi không biết LLVM, tôi vừa ghép nối với nhau bằng cách xem bài đăng trên blog bạn đã liên kết, biết GHC và chơi xung quanh; vì vậy cuối cùng tôi đã phải xem xét sản lượng của clang, vì vậy có thể có cách hiệu quả hơn để xử lý # 2, nhưng dù sao đây là phiên bản hoạt động và thực hiện hoán đổi hai số 64 bit:

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 
} 

mã Haskell để thử nghiệm:

{-# 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) 

xây dựng:

llc -filetype=obj -o Define.o Define.ll 
ghc --make Use.hs Define.o 
Các vấn đề liên quan