1

I know in swift it is possible to interop with c using the @_silgen_name attr on a function in a swift module. Is there a way to do this with a symbol defined in an assembly file? I would like to make syscalls using Swift. This is why I'm asking.

jack sexton
  • 1,227
  • 1
  • 9
  • 28
  • A compiled object file has no idea whether it was compiled from C, or assembled from assembly language. – Crowman Sep 09 '16 at 22:33
  • @PaulGriffiths how does the compiler know where the symbol thats in the asm file is when its compiling the swift module? – jack sexton Sep 09 '16 at 22:41
  • In exactly the same way that it knows where the symbol is with a C source file - it looks it up in the symbol table of the object file. – Crowman Sep 09 '16 at 22:43
  • @PaulGriffiths but I haven't told the compiler to link it. is there a special flag I need to pass in or something? – jack sexton Sep 09 '16 at 22:54
  • [This question](http://stackoverflow.com/questions/32125338/how-can-i-use-an-a-static-library-in-swift) may be helpful. – Crowman Sep 09 '16 at 22:57

1 Answers1

2

Create the bridge header.h file and put the prototype of the function in that file.

For example your assembly code:

.globl _add // make it global so that others can find this symbol
....
_add: // int add(int a, int b)
  movl %esi, %eax
  addl %edi, %eax
  ret

Then in bridging header.h file

int add(int a, int b);

OR

define this at the top of the swift module

@_silgen_name("add") func add(a: Int32, b: Int32) -> Int32

Then in swift you can use it:

let a = add(1, 2);
jack sexton
  • 1,227
  • 1
  • 9
  • 28
Daniel Tran
  • 6,083
  • 12
  • 25
  • what flags do I pass into the swiftc compiler for it to link the assembly file? – jack sexton Sep 10 '16 at 17:08
  • Just put in the same XCode project. – Daniel Tran Sep 10 '16 at 17:57
  • Then try this `swiftc -import-objc-header add.h app.swift add.o -o app` where add.h contain the header, add.o is compiled assembly code. – Daniel Tran Sep 10 '16 at 18:00
  • 1
    Thanks for this, do you know who to compile assembly because I can't seem to find any flags in clang to do that. I tried `clang -S -mllvm --x86-asm-syntax=intel add.s` – jack sexton Sep 10 '16 at 21:56
  • This is what I tried `g++ -c main.s`. Can you try `llvm-g++ -c main.s`? – Daniel Tran Sep 10 '16 at 22:51
  • Thanks! works now and I also figured out that you can skip the bridge header by declaring `@_silgen_name("add") func add(x: Int32, y:Int32) -> Int32` in the swift module – jack sexton Sep 10 '16 at 23:14
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/123110/discussion-between-jack-sexton-and-daniel-tran). – jack sexton Sep 11 '16 at 15:22
  • `lea (%esi, %edi), %eax` would be more efficient. Or for 64-bit code: `lea (%rsi, %rdi), %eax`, because the address-size prefix has no effect if you're truncating the result to the default 32-bit operand-size. – Peter Cordes Sep 14 '16 at 23:00