(The PAPI thing was related to the perf counters, so not directly relevant
to the inline assembly question. but, see here:
http://icl.cs.utk.edu/projectsdev/papi/)

The big change is that `Base.llvmcall` is now merged, so you can write LLVM
IR directly. There are two examples in test/llvmcall.jl, and I believe
Simon Byrne has been testing the use of this for some math intrinsics if
you want to google around (or maybe he will see this and comment if so).

However, the LLVM+JIT combo in the downloadable Julia versions (LLVM 3.3)
does not support inline assembly, so you will need to compile Julia
yourself against LLVM version 3.6 [1].

Once that is done, here are some basic examples I cobbled together -- if
you know assembly and LLVM IR better than I do, hopefully it will be easier
for you.

Add some ints:

 f(x::Int64,y::Int64) = Base.llvmcall("""%3 = add i64 %0, %1
>                                                        ret i64 %3""",
> (Int64), (Int64,Int64), x, y)
>
> julia> f(1,2)
> 3


Read the RTDSC counter:

 f() = Base.llvmcall("""%1 = call i64 asm sideeffect "rdtsc",
> "=A,~{dirflag},~{fpsr},~{flags}"()
>                                 ret i64 %1""", (Int64), ())

julia> f()
> 3643079421



A helpful trick here is to use clang to tell you what the IR should look
like. Write a C file with the inline assembly you want, then compile it
with `clang -emit-llvm -o test.ll test.c`, then try to translate that into
the form expected by Base.llvmcall.

I should note that llvmcall is not documented yet, so here are the basics
(I guess I should put this in the docs now that I've grok'd it myself...):

- first arg is the IR string
- second arg is the return type. Note that contrary to ccall, if you want
to return i64 you should use `(Int64)` rather than `(Int64,)` (comma added)
because otherwise the ret type will be interpreted as `<1 x i64>`.
- third arg is the argument types
- then the actual arguments

Hope that helps to get started.

[1] Create a file at the base of the source tree called `Make.user` with
contents:

LLVM_VER = 3.6.0

and then proceed with the standard build instructions.

On Sun, Mar 22, 2015 at 1:04 PM, andrew cooke <[email protected]> wrote:

>
> I'm aware of
> https://groups.google.com/forum/#!searchin/julia-users/calling$20assembly/julia-users/fJHZCAJkrgo/VV7ZskAjqzMJ
> - I'm wondering if anything has changed in the last few years?  Is calling
> C still the best way to call inline assembly?
>
> I ask because for a general library, I am not sure how portable this is.
> How does one bundle C code so that it is compiled on all platforms Julia
> runs on?
>
> Thanks, Andrew
>
> PS That thread refers to "PAPI C's interface[1]", but I can't see what [1]
> refers to, and my attepts at googling for PAPI have been unproductive.  So
> any info on that, too, would be appreciated.
>

Reply via email to