LLVM和C函数以struct作为参数

时间:2011-06-20 18:43:47

标签: llvm

我正在使用脚本语言,作为其中的一部分,我正在使用LLVM在我的语言和C之间编写桥接代码。我一直致力于在objective-c中使用LLVM API的包装器,直到这一点为止它一直很好用。

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函数仅接收设置为10的x字段,并且y字段保留为空。我完全不知道这是怎么发生的,我能做些什么来解决它。提前感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:10)

你错过了平台ABI。我假设您使用的是x86-64,那么您的结构(根据ABI)应该作为一个整体传递到一个寄存器中。但是,您将{10,25}作为两个单独的32位值传递。鉴于32位操作隐式零扩展,很明显为什么你有0作为第二个值。

准确地说:C代码期望在第一个参数寄存器的前32位中接收25,但是您将该值传递给第二个参数寄存器的低32位。