2011-06-20 13 views
6

私はスクリプト言語に取り組んでおり、その一部としてLLVMを使って自分の言語とCの間にブリッジコードを書いています。私はこの時点までに大いに働いていたobjective-cのLLVM APIのラッパーに取り組んできました。LLVMとC関数の構造体を引数として

typedef struct _test_struct { 
    int x; 
    int y; 
} test_struct; 

id testLLVMStructFuncCall(test_struct x) { 
    NSLog(@"%d %d",x.x,x.y); 
    return N(x.x + x.y); 
} 

-(void) testLLVMStructFuncCall { 
    CGKModule* myMod = [CGKModule moduleWithName:@"llvm_structfunccall_test"]; 
    CGKType* testStructType = [CGKType structTypeWithElementTypes:[NSArray arrayWithObjects:[CGKType intTypeWith32Bits],[CGKType intTypeWith32Bits],nil]]; 
    CGKFunction* lfunc = [CGKFunction functionWithName:@"testLLVMStructFuncCall" types:[NSArray arrayWithObjects:[CGKType idType],testStructType,nil] intoModule:myMod]; 
    CGKFunction* rfunc = [CGKBuilder createStandaloneCallForFunction:lfunc withArguments:[NSArray 
                          arrayWithObjects: 
                         [CGKConstant getStructOfType:testStructType 
                             withValues:[NSArray arrayWithObjects:[CGKConstant getIntConstant:N(10) bits:32], 
                                [CGKConstant getIntConstant:N(25) bits:32],nil]],nil] 
                 inModule:myMod]; 
    [myMod dump]; 
    id var = [[CGKRunner runnerForModule:myMod] runCGKFunction:rfunc]; 
    assertThat(var,is(equalTo(N(35)))); 
} 

私が持っている問題は、試験から次の出力に見られる:モジュールのダンプが予想されるような構造の引数が渡されることを示している

Test Case '-[SVFunctionTests testLLVMStructFuncCall]' started. 
; ModuleID = 'llvm_structfunccall_test' 

%0 = type { i32, i32 } 

declare i64* @testLLVMStructFuncCall(%0) 

define i64* @0() { 
entry: 
    %0 = call i64* @testLLVMStructFuncCall(%0 { i32 10, i32 25 }) 
    ret i64* %0 
} 
2011-06-20 21:25:54.821 otest-x86_64[3369:707] 10 0 
/Users/mtindal/Projects/Silver/Tests/SVFunctionTests.m:576: error: -[SVFunctionTests testLLVMStructFuncCall] : Expected <35>, but was <10> 
Test Case '-[SVFunctionTests testLLVMStructFuncCall]' failed (0.016 seconds). 

しかし、Cの関数はXを受け取りフィールドは10に設定され、yフィールドは空のままになります。私はこれがどうやって起こっているのか、それを解決するために何ができるのか全くわかりません。あなたが私に与えることができる助けのために事前に感謝します。

+0

<35>および<10>は、モジュールに存在する必要がある以前定義したタイプを指します。モジュールの内容をダンプして質問に貼り付けてください。 – lurscher

答えて

9

プラットフォームABIがありません。私はあなたがx86-64上にいると仮定し、あなたの構造体(ABIによる)は全体として単一のレジスタに渡されるべきです。しかし、{10,25}を2つの別々の32ビット値として渡しています。 32ビット演算が暗黙のゼロ拡張を行うことを考えると、2番目の値として0を持つ理由は明らかです。

正確には、Cコードは最初の引数レジスタの上位32ビットを受け取ることを想定していますが、2番目の引数レジスタの下位32ビットに値を渡しています。

+1

@Michael:Cコードをllvm asmにコンパイルしてください。関数の引数の 'test_struct'がi64にどのように変更され、どのように文字が呼び出されているかを見ることができます。あなたは同じことをする必要があります。 –

+0

ありがとう、私が必要とした情報thats。 –

関連する問題