2015-11-25 5 views
5

को रस्मी कॉल मैं इस post से विचारों का उपयोग कर एक विदेशी आयात रस्मी LLVM में लिखा करने के लिए कॉल करने के लिए कोशिश कर रहा हूँ, लेकिन मैं तो बस हो रही segfaults रहते हैं। यहाँ मैं वर्तमान में मिल गया है है।विदेशी आयात LLVM

हास्केल

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

import GHC.Prim 

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

में और .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 
} 

सिद्धांत रूप में में मुझे लगता है कि यह सिर्फ लौटना चाहिए यह एक टपल के रूप में तर्क है, लेकिन जैसा कि मैंने कहा, यह सिर्फ segfaults। इस काम की सराहना करने के लिए किसी भी मदद करते हैं।

उत्तर

2

मैं दो अपने कोड के साथ समस्याओं मिल गया है:

  1. हालांकि अपने हस्ताक्षर आप हास्केल तरफ दो Word# बहस में पारित, एलएलसी ओर आप i64* %buffer और i64 %length (%buffer के नोट प्रकार है पर कहते हैं एक सूचक प्रकार है!)।

  2. स्टैक पर sp: sp अंक में एक और स्तर का संकेत है, और ढेर पर शीर्ष चीज निरंतर सूचक है। आपका कोड ढेर सूचक व्याख्या करने के लिए समारोह में ही सूचक के रूप में की कोशिश करने लगता है।

मैं LLVM पता नहीं है, मैं सिर्फ यह pieced किया है एक साथ, ब्लॉग पोस्ट आप लिंक को देख 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 
} 

परीक्षण के लिए हास्केल कोड:

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

भवन:

llc -filetype=obj -o Define.o Define.ll 
ghc --make Use.hs Define.o