2015-11-25 3 views
5

Я пытаюсь сделать запрос на импортный импорт, написанный в LLVM, используя идеи из этого post, но я просто продолжаю получать segfaults. Вот что у меня есть в настоящее время.запрос на импорт иностранного импорта в LLVM

В Haskell

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

В теории я думаю, что это надо просто вернуть его аргументы в виде кортежа, но, как я уже сказал, это просто ошибки сегментации. Любая помощь, чтобы получить эту работу оценили.

ответ

2

Я нашел две проблемы с кодом:

  1. Хотя ваша подпись говорит, что вы пройти в двух Word# аргументов на стороне Haskell, на стороне ООО Вы имеете i64* %buffer и i64 %length (примечание типа %buffer является типом указателя!).

  2. Существует еще один уровень косвенности в sp: sp указывает на стек, а верхняя часть в стеке - указатель продолжения. Кажется, что ваш код пытается интерпретировать указатель стека как самого указателя функции.

Я не знаю, LLVM, я только кусочки вместе, глядя на блоге вы связаны, зная GHC, и играть вокруг; так что я в конечном итоге пришлось прибегнуть к поиску на выходе clang «s, так что может быть более эффективным способом справиться с # 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 
} 

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) 

Строительство:

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